summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D/TextureCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/D3D/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/D3D/TextureCache.cpp71
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;
+}
}