diff options
| author | Pierre Bourdon <delroth@gmail.com> | 2016-06-24 10:43:46 +0200 |
|---|---|---|
| committer | Pierre Bourdon <delroth@gmail.com> | 2016-06-24 10:43:46 +0200 |
| commit | 3570c7f03a2aa90aa634f96c0af1969af610f14d (patch) | |
| tree | 4252e03c0e853ba7cffe022937698c854ad0eaa9 /Source/Core/VideoBackends/D3D/TextureCache.cpp | |
| parent | 2115e8a4a6814e32107b5205ff5c95bbd3c6e99c (diff) | |
Reformat all the things. Have fun with merge conflicts.
Diffstat (limited to 'Source/Core/VideoBackends/D3D/TextureCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/TextureCache.cpp | 559 |
1 files changed, 281 insertions, 278 deletions
diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index f30d0309ef..62fdbd23d7 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -10,8 +10,8 @@ #include "VideoBackends/D3D/D3DUtil.h" #include "VideoBackends/D3D/FramebufferManager.h" #include "VideoBackends/D3D/GeometryShaderCache.h" -#include "VideoBackends/D3D/PixelShaderCache.h" #include "VideoBackends/D3D/PSTextureEncoder.h" +#include "VideoBackends/D3D/PixelShaderCache.h" #include "VideoBackends/D3D/TextureCache.h" #include "VideoBackends/D3D/TextureEncoder.h" #include "VideoBackends/D3D/VertexShaderCache.h" @@ -22,249 +22,246 @@ namespace DX11 { - static std::unique_ptr<TextureEncoder> g_encoder; const size_t MAX_COPY_BUFFERS = 32; -ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 }; +ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = {0}; TextureCache::TCacheEntry::~TCacheEntry() { - texture->Release(); + texture->Release(); } void TextureCache::TCacheEntry::Bind(unsigned int stage) { - D3D::stateman->SetTexture(stage, texture->GetSRV()); + D3D::stateman->SetTexture(stage, texture->GetSRV()); } bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level) { - // TODO: Somehow implement this (D3DX11 doesn't support dumping individual LODs) - static bool warn_once = true; - if (level && warn_once) - { - WARN_LOG(VIDEO, "Dumping individual LOD not supported by D3D11 backend!"); - warn_once = false; - return false; - } - - ID3D11Texture2D* pNewTexture = nullptr; - ID3D11Texture2D* pSurface = texture->GetTex(); - D3D11_TEXTURE2D_DESC desc; - pSurface->GetDesc(&desc); - - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.Usage = D3D11_USAGE_STAGING; - - HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &pNewTexture); - - bool saved_png = false; - - if (SUCCEEDED(hr) && pNewTexture) - { - D3D::context->CopyResource(pNewTexture, pSurface); - - D3D11_MAPPED_SUBRESOURCE map; - hr = D3D::context->Map(pNewTexture, 0, D3D11_MAP_READ_WRITE, 0, &map); - if (SUCCEEDED(hr)) - { - saved_png = TextureToPng((u8*)map.pData, map.RowPitch, filename, desc.Width, desc.Height); - D3D::context->Unmap(pNewTexture, 0); - } - SAFE_RELEASE(pNewTexture); - } - - return saved_png; + // TODO: Somehow implement this (D3DX11 doesn't support dumping individual LODs) + static bool warn_once = true; + if (level && warn_once) + { + WARN_LOG(VIDEO, "Dumping individual LOD not supported by D3D11 backend!"); + warn_once = false; + return false; + } + + ID3D11Texture2D* pNewTexture = nullptr; + ID3D11Texture2D* pSurface = texture->GetTex(); + D3D11_TEXTURE2D_DESC desc; + pSurface->GetDesc(&desc); + + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.Usage = D3D11_USAGE_STAGING; + + HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &pNewTexture); + + bool saved_png = false; + + if (SUCCEEDED(hr) && pNewTexture) + { + D3D::context->CopyResource(pNewTexture, pSurface); + + D3D11_MAPPED_SUBRESOURCE map; + hr = D3D::context->Map(pNewTexture, 0, D3D11_MAP_READ_WRITE, 0, &map); + if (SUCCEEDED(hr)) + { + saved_png = TextureToPng((u8*)map.pData, map.RowPitch, filename, desc.Width, desc.Height); + D3D::context->Unmap(pNewTexture, 0); + } + SAFE_RELEASE(pNewTexture); + } + + return saved_png; } -void TextureCache::TCacheEntry::CopyRectangleFromTexture( - const TCacheEntryBase* source, - const MathUtil::Rectangle<int> &srcrect, - const MathUtil::Rectangle<int> &dstrect) +void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* source, + const MathUtil::Rectangle<int>& srcrect, + const MathUtil::Rectangle<int>& dstrect) { - TCacheEntry* srcentry = (TCacheEntry*)source; - if (srcrect.GetWidth() == dstrect.GetWidth() - && srcrect.GetHeight() == dstrect.GetHeight()) - { - D3D11_BOX srcbox; - srcbox.left = srcrect.left; - srcbox.top = srcrect.top; - srcbox.right = srcrect.right; - srcbox.bottom = srcrect.bottom; - srcbox.front = 0; - srcbox.back = srcentry->config.layers; - - D3D::context->CopySubresourceRegion( - texture->GetTex(), - 0, - dstrect.left, - dstrect.top, - 0, - srcentry->texture->GetTex(), - 0, - &srcbox); - return; - } - else if (!config.rendertarget) - { - return; - } - g_renderer->ResetAPIState(); // reset any game specific settings - - const D3D11_VIEWPORT vp = CD3D11_VIEWPORT( - float(dstrect.left), - float(dstrect.top), - float(dstrect.GetWidth()), - float(dstrect.GetHeight())); - - D3D::stateman->UnsetTexture(texture->GetSRV()); - D3D::stateman->Apply(); - - D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); - D3D::context->RSSetViewports(1, &vp); - D3D::SetLinearCopySampler(); - D3D11_RECT srcRC; - srcRC.left = srcrect.left; - srcRC.right = srcrect.right; - srcRC.top = srcrect.top; - srcRC.bottom = srcrect.bottom; - D3D::drawShadedTexQuad(srcentry->texture->GetSRV(), &srcRC, - srcentry->config.width, srcentry->config.height, - PixelShaderCache::GetColorCopyProgram(false), - VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader(), 1.0, 0); - - D3D::context->OMSetRenderTargets(1, - &FramebufferManager::GetEFBColorTexture()->GetRTV(), - FramebufferManager::GetEFBDepthTexture()->GetDSV()); - - g_renderer->RestoreAPIState(); + TCacheEntry* srcentry = (TCacheEntry*)source; + if (srcrect.GetWidth() == dstrect.GetWidth() && srcrect.GetHeight() == dstrect.GetHeight()) + { + D3D11_BOX srcbox; + srcbox.left = srcrect.left; + srcbox.top = srcrect.top; + srcbox.right = srcrect.right; + srcbox.bottom = srcrect.bottom; + srcbox.front = 0; + srcbox.back = srcentry->config.layers; + + D3D::context->CopySubresourceRegion(texture->GetTex(), 0, dstrect.left, dstrect.top, 0, + srcentry->texture->GetTex(), 0, &srcbox); + return; + } + else if (!config.rendertarget) + { + return; + } + g_renderer->ResetAPIState(); // reset any game specific settings + + const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(float(dstrect.left), float(dstrect.top), + float(dstrect.GetWidth()), float(dstrect.GetHeight())); + + D3D::stateman->UnsetTexture(texture->GetSRV()); + D3D::stateman->Apply(); + + D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); + D3D::context->RSSetViewports(1, &vp); + D3D::SetLinearCopySampler(); + D3D11_RECT srcRC; + srcRC.left = srcrect.left; + srcRC.right = srcrect.right; + srcRC.top = srcrect.top; + srcRC.bottom = srcrect.bottom; + D3D::drawShadedTexQuad(srcentry->texture->GetSRV(), &srcRC, srcentry->config.width, + srcentry->config.height, PixelShaderCache::GetColorCopyProgram(false), + VertexShaderCache::GetSimpleVertexShader(), + VertexShaderCache::GetSimpleInputLayout(), + GeometryShaderCache::GetCopyGeometryShader(), 1.0, 0); + + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + FramebufferManager::GetEFBDepthTexture()->GetDSV()); + + g_renderer->RestoreAPIState(); } void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level) + unsigned int expanded_width, unsigned int level) { - unsigned int src_pitch = 4 * expanded_width; - D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, src_pitch, level, usage); + unsigned int src_pitch = 4 * expanded_width; + D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, src_pitch, level, + usage); } TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config) { - if (config.rendertarget) - { - return new TCacheEntry(config, D3DTexture2D::Create(config.width, config.height, - (D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE), - D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers)); - } - else - { - D3D11_USAGE usage = D3D11_USAGE_DEFAULT; - D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0; - - if (config.levels == 1) - { - usage = D3D11_USAGE_DYNAMIC; - cpu_access = D3D11_CPU_ACCESS_WRITE; - } - - const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, - config.width, config.height, 1, config.levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access); - - ID3D11Texture2D *pTexture; - const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture); - CHECK(SUCCEEDED(hr), "Create texture of the TextureCache"); - - TCacheEntry* const entry = new TCacheEntry(config, new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE)); - entry->usage = usage; - - // TODO: better debug names - D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache"); - D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache"); - - SAFE_RELEASE(pTexture); - - return entry; - } + if (config.rendertarget) + { + return new TCacheEntry( + config, D3DTexture2D::Create( + config.width, config.height, (D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | + (int)D3D11_BIND_SHADER_RESOURCE), + D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers)); + } + else + { + D3D11_USAGE usage = D3D11_USAGE_DEFAULT; + D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0; + + if (config.levels == 1) + { + usage = D3D11_USAGE_DYNAMIC; + cpu_access = D3D11_CPU_ACCESS_WRITE; + } + + const D3D11_TEXTURE2D_DESC texdesc = + CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, config.width, config.height, 1, + config.levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access); + + ID3D11Texture2D* pTexture; + const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture); + CHECK(SUCCEEDED(hr), "Create texture of the TextureCache"); + + TCacheEntry* const entry = + new TCacheEntry(config, new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE)); + entry->usage = usage; + + // TODO: better debug names + D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), + "a texture of the TextureCache"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), + "shader resource view of a texture of the TextureCache"); + + SAFE_RELEASE(pTexture); + + return entry; + } } -void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, - bool scaleByHalf, unsigned int cbufid, const float *colmat) +void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, + const EFBRectangle& srcRect, bool scaleByHalf, + unsigned int cbufid, const float* colmat) { - // When copying at half size, in multisampled mode, resolve the color/depth buffer first. - // This is because multisampled texture reads go through Load, not Sample, and the linear - // filter is ignored. - bool multisampled = (g_ActiveConfig.iMultisamples > 1); - ID3D11ShaderResourceView* efbTexSRV = (srcFormat == PEControl::Z24) ? - FramebufferManager::GetEFBDepthTexture()->GetSRV() : - FramebufferManager::GetEFBColorTexture()->GetSRV(); - if (multisampled && scaleByHalf) - { - multisampled = false; - efbTexSRV = (srcFormat == PEControl::Z24) ? - FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : - FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); - } - - g_renderer->ResetAPIState(); - - // stretch picture with increased internal resolution - const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)config.width, (float)config.height); - D3D::context->RSSetViewports(1, &vp); - - // set transformation - if (nullptr == efbcopycbuf[cbufid]) - { - const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = colmat; - HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); - CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); - D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); - } - D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]); - - const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); - // TODO: try targetSource.asRECT(); - const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); - - // Use linear filtering if (bScaleByHalf), use point filtering otherwise - if (scaleByHalf) - D3D::SetLinearCopySampler(); - else - D3D::SetPointCopySampler(); - - // Make sure we don't draw with the texture set as both a source and target. - // (This can happen because we don't unbind textures when we free them.) - D3D::stateman->UnsetTexture(texture->GetSRV()); - D3D::stateman->Apply(); - - D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); - - // Create texture copy - D3D::drawShadedTexQuad( - efbTexSRV, - &sourcerect, Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - srcFormat == PEControl::Z24 ? PixelShaderCache::GetDepthMatrixProgram(multisampled) : PixelShaderCache::GetColorMatrixProgram(multisampled), - VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout(), - GeometryShaderCache::GetCopyGeometryShader()); - - D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); - - g_renderer->RestoreAPIState(); + // When copying at half size, in multisampled mode, resolve the color/depth buffer first. + // This is because multisampled texture reads go through Load, not Sample, and the linear + // filter is ignored. + bool multisampled = (g_ActiveConfig.iMultisamples > 1); + ID3D11ShaderResourceView* efbTexSRV = (srcFormat == PEControl::Z24) ? + FramebufferManager::GetEFBDepthTexture()->GetSRV() : + FramebufferManager::GetEFBColorTexture()->GetSRV(); + if (multisampled && scaleByHalf) + { + multisampled = false; + efbTexSRV = (srcFormat == PEControl::Z24) ? + FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : + FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); + } + + g_renderer->ResetAPIState(); + + // stretch picture with increased internal resolution + const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)config.width, (float)config.height); + D3D::context->RSSetViewports(1, &vp); + + // set transformation + if (nullptr == efbcopycbuf[cbufid]) + { + const D3D11_BUFFER_DESC cbdesc = + CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = colmat; + HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); + CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); + D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], + "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); + } + D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]); + + const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); + // TODO: try targetSource.asRECT(); + const D3D11_RECT sourcerect = + CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); + + // Use linear filtering if (bScaleByHalf), use point filtering otherwise + if (scaleByHalf) + D3D::SetLinearCopySampler(); + else + D3D::SetPointCopySampler(); + + // Make sure we don't draw with the texture set as both a source and target. + // (This can happen because we don't unbind textures when we free them.) + D3D::stateman->UnsetTexture(texture->GetSRV()); + D3D::stateman->Apply(); + + D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); + + // Create texture copy + D3D::drawShadedTexQuad( + efbTexSRV, &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), + srcFormat == PEControl::Z24 ? PixelShaderCache::GetDepthMatrixProgram(multisampled) : + PixelShaderCache::GetColorMatrixProgram(multisampled), + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), + GeometryShaderCache::GetCopyGeometryShader()); + + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + FramebufferManager::GetEFBDepthTexture()->GetDSV()); + + g_renderer->RestoreAPIState(); } -void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride, - PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, - bool isIntensity, bool scaleByHalf) +void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat, + const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) { - g_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride, srcFormat, srcRect, isIntensity, scaleByHalf); + g_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride, + srcFormat, srcRect, isIntensity, scaleByHalf); } const char palette_shader[] = -R"HLSL( + R"HLSL( sampler samp0 : register(s0); Texture2DArray Tex0 : register(t0); Buffer<uint> Tex1 : register(t1); @@ -343,97 +340,103 @@ void main( } )HLSL"; -void TextureCache::ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette, TlutFormat format) +void TextureCache::ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, + void* palette, TlutFormat format) { - g_renderer->ResetAPIState(); + g_renderer->ResetAPIState(); - // stretch picture with increased internal resolution - const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)unconverted->config.width, (float)unconverted->config.height); - D3D::context->RSSetViewports(1, &vp); + // stretch picture with increased internal resolution + const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)unconverted->config.width, + (float)unconverted->config.height); + D3D::context->RSSetViewports(1, &vp); - D3D11_BOX box{ 0, 0, 0, 512, 1, 1 }; - D3D::context->UpdateSubresource(palette_buf, 0, &box, palette, 0, 0); + D3D11_BOX box{0, 0, 0, 512, 1, 1}; + D3D::context->UpdateSubresource(palette_buf, 0, &box, palette, 0, 0); - D3D::stateman->SetTexture(1, palette_buf_srv); + D3D::stateman->SetTexture(1, palette_buf_srv); - // TODO: Add support for C14X2 format. (Different multiplier, more palette entries.) - float params[4] = { (unconverted->format & 0xf) == GX_TF_I4 ? 15.f : 255.f }; - D3D::context->UpdateSubresource(palette_uniform, 0, nullptr, ¶ms, 0, 0); - D3D::stateman->SetPixelConstants(palette_uniform); + // TODO: Add support for C14X2 format. (Different multiplier, more palette entries.) + float params[4] = {(unconverted->format & 0xf) == GX_TF_I4 ? 15.f : 255.f}; + D3D::context->UpdateSubresource(palette_uniform, 0, nullptr, ¶ms, 0, 0); + D3D::stateman->SetPixelConstants(palette_uniform); - const D3D11_RECT sourcerect = CD3D11_RECT(0, 0, unconverted->config.width, unconverted->config.height); + const D3D11_RECT sourcerect = + CD3D11_RECT(0, 0, unconverted->config.width, unconverted->config.height); - D3D::SetPointCopySampler(); + D3D::SetPointCopySampler(); - // Make sure we don't draw with the texture set as both a source and target. - // (This can happen because we don't unbind textures when we free them.) - D3D::stateman->UnsetTexture(static_cast<TCacheEntry*>(entry)->texture->GetSRV()); - D3D::stateman->Apply(); + // Make sure we don't draw with the texture set as both a source and target. + // (This can happen because we don't unbind textures when we free them.) + D3D::stateman->UnsetTexture(static_cast<TCacheEntry*>(entry)->texture->GetSRV()); + D3D::stateman->Apply(); - D3D::context->OMSetRenderTargets(1, &static_cast<TCacheEntry*>(entry)->texture->GetRTV(), nullptr); + D3D::context->OMSetRenderTargets(1, &static_cast<TCacheEntry*>(entry)->texture->GetRTV(), + nullptr); - // Create texture copy - D3D::drawShadedTexQuad( - static_cast<TCacheEntry*>(unconverted)->texture->GetSRV(), - &sourcerect, unconverted->config.width, unconverted->config.height, - palette_pixel_shader[format], - VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), - GeometryShaderCache::GetCopyGeometryShader()); + // Create texture copy + D3D::drawShadedTexQuad(static_cast<TCacheEntry*>(unconverted)->texture->GetSRV(), &sourcerect, + unconverted->config.width, unconverted->config.height, + palette_pixel_shader[format], VertexShaderCache::GetSimpleVertexShader(), + VertexShaderCache::GetSimpleInputLayout(), + GeometryShaderCache::GetCopyGeometryShader()); - D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + FramebufferManager::GetEFBDepthTexture()->GetDSV()); - g_renderer->RestoreAPIState(); + g_renderer->RestoreAPIState(); } -ID3D11PixelShader *GetConvertShader(const char* Type) +ID3D11PixelShader* GetConvertShader(const char* Type) { - std::string shader = "#define DECODE DecodePixel_"; - shader.append(Type); - shader.append("\n"); - shader.append(palette_shader); - return D3D::CompileAndCreatePixelShader(shader); + std::string shader = "#define DECODE DecodePixel_"; + shader.append(Type); + shader.append("\n"); + shader.append(palette_shader); + return D3D::CompileAndCreatePixelShader(shader); } TextureCache::TextureCache() { - // FIXME: Is it safe here? - g_encoder = std::make_unique<PSTextureEncoder>(); - g_encoder->Init(); - - palette_buf = nullptr; - palette_buf_srv = nullptr; - palette_uniform = nullptr; - palette_pixel_shader[GX_TL_IA8] = GetConvertShader("IA8"); - palette_pixel_shader[GX_TL_RGB565] = GetConvertShader("RGB565"); - palette_pixel_shader[GX_TL_RGB5A3] = GetConvertShader("RGB5A3"); - auto lutBd = CD3D11_BUFFER_DESC(sizeof(u16) * 256, D3D11_BIND_SHADER_RESOURCE); - HRESULT hr = D3D::device->CreateBuffer(&lutBd, nullptr, &palette_buf); - CHECK(SUCCEEDED(hr), "create palette decoder lut buffer"); - D3D::SetDebugObjectName(palette_buf, "texture decoder lut buffer"); - // TODO: C14X2 format. - auto outlutUavDesc = CD3D11_SHADER_RESOURCE_VIEW_DESC(palette_buf, DXGI_FORMAT_R16_UINT, 0, 256, 0); - hr = D3D::device->CreateShaderResourceView(palette_buf, &outlutUavDesc, &palette_buf_srv); - CHECK(SUCCEEDED(hr), "create palette decoder lut srv"); - D3D::SetDebugObjectName(palette_buf_srv, "texture decoder lut srv"); - const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(16, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); - hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &palette_uniform); - CHECK(SUCCEEDED(hr), "Create palette decoder constant buffer"); - D3D::SetDebugObjectName((ID3D11DeviceChild*)palette_uniform, "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); + // FIXME: Is it safe here? + g_encoder = std::make_unique<PSTextureEncoder>(); + g_encoder->Init(); + + palette_buf = nullptr; + palette_buf_srv = nullptr; + palette_uniform = nullptr; + palette_pixel_shader[GX_TL_IA8] = GetConvertShader("IA8"); + palette_pixel_shader[GX_TL_RGB565] = GetConvertShader("RGB565"); + palette_pixel_shader[GX_TL_RGB5A3] = GetConvertShader("RGB5A3"); + auto lutBd = CD3D11_BUFFER_DESC(sizeof(u16) * 256, D3D11_BIND_SHADER_RESOURCE); + HRESULT hr = D3D::device->CreateBuffer(&lutBd, nullptr, &palette_buf); + CHECK(SUCCEEDED(hr), "create palette decoder lut buffer"); + D3D::SetDebugObjectName(palette_buf, "texture decoder lut buffer"); + // TODO: C14X2 format. + auto outlutUavDesc = + CD3D11_SHADER_RESOURCE_VIEW_DESC(palette_buf, DXGI_FORMAT_R16_UINT, 0, 256, 0); + hr = D3D::device->CreateShaderResourceView(palette_buf, &outlutUavDesc, &palette_buf_srv); + CHECK(SUCCEEDED(hr), "create palette decoder lut srv"); + D3D::SetDebugObjectName(palette_buf_srv, "texture decoder lut srv"); + const D3D11_BUFFER_DESC cbdesc = + CD3D11_BUFFER_DESC(16, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); + hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &palette_uniform); + CHECK(SUCCEEDED(hr), "Create palette decoder constant buffer"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)palette_uniform, + "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } TextureCache::~TextureCache() { - for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k) - SAFE_RELEASE(efbcopycbuf[k]); + for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k) + SAFE_RELEASE(efbcopycbuf[k]); - g_encoder->Shutdown(); - g_encoder.reset(); + g_encoder->Shutdown(); + g_encoder.reset(); - SAFE_RELEASE(palette_buf); - SAFE_RELEASE(palette_buf_srv); - SAFE_RELEASE(palette_uniform); - for (ID3D11PixelShader*& shader : palette_pixel_shader) - SAFE_RELEASE(shader); + SAFE_RELEASE(palette_buf); + SAFE_RELEASE(palette_buf_srv); + SAFE_RELEASE(palette_uniform); + for (ID3D11PixelShader*& shader : palette_pixel_shader) + SAFE_RELEASE(shader); } - } |
