Check that format/texture is supported on local proxy

* Even if we can map a remote format precisely to a local API format, that
  doesn't mean the local API driver supports it - we need to check, otherwise
  force a remap.
This commit is contained in:
baldurk
2019-11-25 17:07:06 +00:00
parent a4372b2b5f
commit 62dc2c5a91
3 changed files with 92 additions and 2 deletions
+34
View File
@@ -3604,6 +3604,16 @@ void D3D11Replay::SetProxyTextureData(ResourceId texid, const Subresource &sub,
bool D3D11Replay::IsTextureSupported(const TextureDescription &tex)
{
// these formats are inconsistently laid out between APIs, always remap
switch(tex.format.type)
{
case ResourceFormatType::R4G4:
case ResourceFormatType::R4G4B4A4:
case ResourceFormatType::R5G6B5:
case ResourceFormatType::R5G5B5A1: return false;
default: break;
}
DXGI_FORMAT f = MakeDXGIFormat(tex.format);
if(f == DXGI_FORMAT_UNKNOWN)
@@ -3614,6 +3624,30 @@ bool D3D11Replay::IsTextureSupported(const TextureDescription &tex)
if(IsTypelessFormat(f) && tex.format.compType != CompType::Typeless)
return false;
if(!IsDepthFormat(f))
f = GetTypelessFormat(f);
else
f = GetDepthTypedFormat(f);
// CheckFormatSupport doesn't like returning MSAA support for typeless formats, if we're thinking
// about MSAA ensure we query a typed format.
if(tex.msSamp > 1)
f = GetTypedFormat(f);
UINT supp = 0;
m_pDevice->CheckFormatSupport(f, &supp);
if(tex.dimension == 1 && (supp & D3D11_FORMAT_SUPPORT_TEXTURE1D) == 0)
return false;
if(tex.dimension == 2 && (supp & D3D11_FORMAT_SUPPORT_TEXTURE2D) == 0)
return false;
if(tex.dimension == 3 && (supp & D3D11_FORMAT_SUPPORT_TEXTURE3D) == 0)
return false;
if(tex.msSamp > 1 &&
(supp &
(D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) == 0)
return false;
return true;
}
+1
View File
@@ -647,6 +647,7 @@ DXGI_FORMAT GetDepthTypedFormat(DXGI_FORMAT f)
case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
case DXGI_FORMAT_R16_FLOAT:
case DXGI_FORMAT_R16_UNORM:
case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_D16_UNORM;
default: break;
+57 -2
View File
@@ -3304,6 +3304,17 @@ void GLReplay::SetProxyTextureData(ResourceId texid, const Subresource &sub, byt
bool GLReplay::IsTextureSupported(const TextureDescription &tex)
{
// these formats are inconsistently laid out between APIs, always remap if the remote API is
// different
switch(tex.format.type)
{
case ResourceFormatType::R4G4:
case ResourceFormatType::R4G4B4A4:
case ResourceFormatType::R5G6B5:
case ResourceFormatType::R5G5B5A1: return false;
default: break;
}
// We couldn't create proxy textures for ASTC textures (see MakeGLFormat). So we give back false
// and let RemapProxyTextureIfNeeded to set remap type for them.
if(tex.format.type == ResourceFormatType::ASTC)
@@ -3318,8 +3329,8 @@ bool GLReplay::IsTextureSupported(const TextureDescription &tex)
if(tex.format.BGRAOrder())
return IsGLES && HasExt[EXT_texture_format_BGRA8888];
// don't support 3D block compressed textures
if(tex.dimension == 3 &&
// don't support 1D/3D block compressed textures
if(tex.dimension != 2 &&
(tex.format.type == ResourceFormatType::BC1 || tex.format.type == ResourceFormatType::BC2 ||
tex.format.type == ResourceFormatType::BC1 || tex.format.type == ResourceFormatType::BC2 ||
tex.format.type == ResourceFormatType::BC3 || tex.format.type == ResourceFormatType::BC4 ||
@@ -3328,6 +3339,50 @@ bool GLReplay::IsTextureSupported(const TextureDescription &tex)
tex.format.type == ResourceFormatType::ETC2 || tex.format.type == ResourceFormatType::EAC))
return false;
GLenum fmt = MakeGLFormat(tex.format);
if(fmt == eGL_NONE)
return false;
GLenum target = eGL_TEXTURE_2D;
switch(tex.type)
{
case TextureType::Unknown: break;
case TextureType::Buffer:
case TextureType::Texture1D: target = eGL_TEXTURE_1D; break;
case TextureType::Texture1DArray: target = eGL_TEXTURE_1D_ARRAY; break;
case TextureType::TextureRect:
case TextureType::Texture2D: target = eGL_TEXTURE_2D; break;
case TextureType::Texture2DArray: target = eGL_TEXTURE_2D_ARRAY; break;
case TextureType::Texture2DMS: target = eGL_TEXTURE_2D_MULTISAMPLE; break;
case TextureType::Texture2DMSArray: target = eGL_TEXTURE_2D_MULTISAMPLE_ARRAY; break;
case TextureType::Texture3D: target = eGL_TEXTURE_3D; break;
case TextureType::TextureCube: target = eGL_TEXTURE_CUBE_MAP; break;
case TextureType::TextureCubeArray: target = eGL_TEXTURE_CUBE_MAP_ARRAY; break;
case TextureType::Count: RDCERR("Invalid texture dimension"); break;
}
GLint supported = 0, fragment = 0;
m_pDriver->glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_SUPPORTED, 4, &supported);
m_pDriver->glGetInternalformativ(target, fmt, eGL_FRAGMENT_TEXTURE, 4, &fragment);
// check the texture is supported
if(supported == 0 || fragment == 0)
return false;
// for multisampled textures it must be in a view compatibility class, to let us copy to/from the
// MSAA texture.
if(tex.msSamp > 1 && !IsDepthStencilFormat(fmt))
{
GLenum viewClass = eGL_NONE;
m_pDriver->glGetInternalformativ(eGL_TEXTURE_2D_ARRAY, fmt, eGL_VIEW_COMPATIBILITY_CLASS,
sizeof(GLenum), (GLint *)&viewClass);
if(viewClass == eGL_NONE)
return false;
}
return true;
}