diff options
Diffstat (limited to 'Source/Core/VideoBackends/D3D/TextureCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/TextureCache.cpp | 71 |
1 files changed, 35 insertions, 36 deletions
diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index a7eab7c041..cca8448421 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -29,8 +29,6 @@ namespace DX11 { -static const size_t MAX_COPY_BUFFERS = 32; -static ID3D11Buffer* s_efbcopycbuf[MAX_COPY_BUFFERS] = {0}; static std::unique_ptr<PSTextureEncoder> g_encoder; void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, @@ -207,17 +205,16 @@ TextureCache::TextureCache() TextureCache::~TextureCache() { - for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k) - SAFE_RELEASE(s_efbcopycbuf[k]); - 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) + for (auto*& shader : palette_pixel_shader) SAFE_RELEASE(shader); + for (auto& iter : m_efb_to_tex_pixel_shaders) + SAFE_RELEASE(iter.second); } void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, @@ -227,20 +224,25 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, { auto* destination_texture = static_cast<DXTexture*>(entry->texture.get()); - // 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 = is_depth_copy ? - FramebufferManager::GetEFBDepthTexture()->GetSRV() : - FramebufferManager::GetEFBColorTexture()->GetSRV(); - if (multisampled && scale_by_half) + bool multisampled = g_ActiveConfig.iMultisamples > 1; + ID3D11ShaderResourceView* efb_tex_srv; + if (multisampled) + { + efb_tex_srv = is_depth_copy ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : + FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); + } + else { - multisampled = false; - efbTexSRV = is_depth_copy ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : - FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); + efb_tex_srv = is_depth_copy ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : + FramebufferManager::GetEFBColorTexture()->GetSRV(); } + auto uid = TextureConversionShaderGen::GetShaderUid(dst_format, is_depth_copy, is_intensity, + scale_by_half); + ID3D11PixelShader* pixel_shader = GetEFBToTexPixelShader(uid); + if (!pixel_shader) + return; + g_renderer->ResetAPIState(); // stretch picture with increased internal resolution @@ -249,20 +251,6 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, static_cast<float>(destination_texture->GetConfig().height)); D3D::context->RSSetViewports(1, &vp); - // set transformation - if (nullptr == s_efbcopycbuf[cbuf_id]) - { - 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, &s_efbcopycbuf[cbuf_id]); - CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbuf_id); - D3D::SetDebugObjectName(s_efbcopycbuf[cbuf_id], - "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); - } - D3D::stateman->SetPixelConstants(s_efbcopycbuf[cbuf_id]); - const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(src_rect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = @@ -284,13 +272,24 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, // Create texture copy D3D::drawShadedTexQuad( - efbTexSRV, &sourcerect, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - is_depth_copy ? PixelShaderCache::GetDepthMatrixProgram(multisampled) : - PixelShaderCache::GetColorMatrixProgram(multisampled), - VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), - GeometryShaderCache::GetCopyGeometryShader()); + efb_tex_srv, &sourcerect, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), + pixel_shader, VertexShaderCache::GetSimpleVertexShader(), + VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); FramebufferManager::BindEFBRenderTarget(); g_renderer->RestoreAPIState(); } + +ID3D11PixelShader* +TextureCache::GetEFBToTexPixelShader(const TextureConversionShaderGen::TCShaderUid& uid) +{ + auto iter = m_efb_to_tex_pixel_shaders.find(uid); + if (iter != m_efb_to_tex_pixel_shaders.end()) + return iter->second; + + ShaderCode code = TextureConversionShaderGen::GenerateShader(APIType::D3D, uid.GetUidData()); + ID3D11PixelShader* shader = D3D::CompileAndCreatePixelShader(code.GetBuffer()); + m_efb_to_tex_pixel_shaders.emplace(uid, shader); + return shader; +} } |
