diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index e5be204a8..a8efc00d9 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -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; } diff --git a/renderdoc/driver/dxgi/dxgi_common.cpp b/renderdoc/driver/dxgi/dxgi_common.cpp index 6e00835cf..217eed874 100644 --- a/renderdoc/driver/dxgi/dxgi_common.cpp +++ b/renderdoc/driver/dxgi/dxgi_common.cpp @@ -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; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 11ce2dbf6..54786ebc3 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -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; }