diff --git a/renderdoc/common/dds_readwrite.cpp b/renderdoc/common/dds_readwrite.cpp index f77f9aa3b..a70e1f0b1 100644 --- a/renderdoc/common/dds_readwrite.cpp +++ b/renderdoc/common/dds_readwrite.cpp @@ -312,6 +312,13 @@ ResourceFormat DXGIFormat2ResourceFormat(DXGI_FORMAT format) return special; case DXGI_FORMAT_D24_UNORM_S8_UINT: special.type = ResourceFormatType::D24S8; return special; case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: special.type = ResourceFormatType::D32S8; return special; + case DXGI_FORMAT_YUY2: + special.type = ResourceFormatType::YUV8; + special.compByteWidth = 1; + special.compCount = 3; + special.compType = CompType::UNorm; + special.SetYUVSubsampling(422); + return special; case DXGI_FORMAT_R32G32B32A32_UINT: fmt32.compType = CompType::UInt; @@ -922,6 +929,8 @@ dds_data load_dds_from_file(FILE *f) if(ret.cubemap) ret.slices *= 6; + bool bgrSwap = false; + if(dx10Header) { ret.format = DXGIFormat2ResourceFormat(headerDXT10.dxgiFormat); @@ -966,6 +975,12 @@ dds_data load_dds_from_file(FILE *f) case MAKE_FOURCC('G', 'R', 'G', 'B'): ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_G8R8_G8B8_UNORM); break; + case MAKE_FOURCC('U', 'Y', 'V', 'Y'): + bgrSwap = true; + // deliberate fall-through + case MAKE_FOURCC('Y', 'U', 'Y', '2'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_YUY2); + break; case 36: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_UNORM); break; case 82: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_D32_FLOAT); break; case 110: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_SNORM); break; @@ -997,6 +1012,7 @@ dds_data load_dds_from_file(FILE *f) } uint32_t bytesPerPixel = 1; + int subsamplePacking = 1; switch(ret.format.type) { case ResourceFormatType::S8: @@ -1009,11 +1025,17 @@ dds_data load_dds_from_file(FILE *f) case ResourceFormatType::R5G5B5A1: case ResourceFormatType::R4G4B4A4: bytesPerPixel = 2; break; case ResourceFormatType::D32S8: bytesPerPixel = 8; break; - case ResourceFormatType::D16S8: case ResourceFormatType::YUV8: + if(ret.format.YUVPlaneCount() == 1 && ret.format.YUVSubsampling() == 422) + { + subsamplePacking = 2; + bytesPerPixel = 2; + break; + } case ResourceFormatType::YUV10: case ResourceFormatType::YUV12: case ResourceFormatType::YUV16: + case ResourceFormatType::D16S8: case ResourceFormatType::R4G4: RDCERR("Unsupported file format %u", ret.format.type); return error; @@ -1036,10 +1058,6 @@ dds_data load_dds_from_file(FILE *f) case ResourceFormatType::ETC2: case ResourceFormatType::EAC: case ResourceFormatType::ASTC: - case ResourceFormatType::YUV8: - case ResourceFormatType::YUV10: - case ResourceFormatType::YUV12: - case ResourceFormatType::YUV16: RDCERR("Unsupported file format, %u", ret.format.type); return error; default: break; @@ -1055,6 +1073,7 @@ dds_data load_dds_from_file(FILE *f) for(int mip = 0; mip < ret.mips; mip++) { int rowlen = RDCMAX(1, ret.width >> mip); + rowlen = AlignUp(rowlen, subsamplePacking); int numRows = RDCMAX(1, ret.height >> mip); int numdepths = RDCMAX(1, ret.depth >> mip); int pitch = RDCMAX(1U, rowlen * bytesPerPixel); @@ -1082,6 +1101,28 @@ dds_data load_dds_from_file(FILE *f) { FileIO::fread(bytedata, 1, pitch, f); + if(bgrSwap) + { + byte *rgba = bytedata; + + if(bytesPerPixel >= 3) + { + for(int p = 0; p < rowlen; p++) + { + std::swap(rgba[0], rgba[2]); + rgba += bytesPerPixel; + } + } + else + { + for(int p = 0; p < rowlen; p++) + { + std::swap(rgba[0], rgba[1]); + rgba += bytesPerPixel; + } + } + } + bytedata += pitch; } } diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 347a699aa..a19ebcd47 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -456,6 +456,12 @@ ReplayStatus IMG_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver) *driver = new ImageViewer(proxy, filename.c_str()); + if((*driver)->GetResources()[0].resourceId == ResourceId()) + { + delete *driver; + return ReplayStatus::ImageUnsupported; + } + return ReplayStatus::Succeeded; } @@ -731,6 +737,9 @@ void ImageViewer::RefreshFile() if(m_TextureID == ResourceId()) m_TextureID = m_Proxy->CreateProxyTexture(texDetails); + if(m_TextureID == ResourceId()) + RDCERR("Couldn't create proxy texture for image file"); + if(!dds) { m_Proxy->SetProxyTextureData(m_TextureID, 0, 0, data, datasize); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 9deb4aa87..0a7651acd 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2948,9 +2948,6 @@ ResourceId GLReplay::CreateProxyTexture(const TextureDescription &templateTex) MakeCurrentReplayContext(m_DebugCtx); - GLuint tex = 0; - drv.glGenTextures(1, &tex); - GLenum intFormat = MakeGLFormat(templateTex.format); bool isCompressed = IsCompressedFormat(intFormat); @@ -2962,6 +2959,12 @@ ResourceId GLReplay::CreateProxyTexture(const TextureDescription &templateTex) dataType = GetDataType(intFormat); } + if(baseFormat == eGL_NONE || dataType == eGL_NONE) + return ResourceId(); + + GLuint tex = 0; + drv.glGenTextures(1, &tex); + GLenum target = eGL_NONE; switch(templateTex.type) @@ -3109,6 +3112,9 @@ void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t auto &texdetails = m_pDriver->m_Textures[texid]; + if(texdetails.curType == eGL_NONE) + return; + GLenum fmt = texdetails.internalFormat; GLenum target = texdetails.curType;