summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2016-06-24 10:43:46 +0200
committerPierre Bourdon <delroth@gmail.com>2016-06-24 10:43:46 +0200
commit3570c7f03a2aa90aa634f96c0af1969af610f14d (patch)
tree4252e03c0e853ba7cffe022937698c854ad0eaa9 /Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp
parent2115e8a4a6814e32107b5205ff5c95bbd3c6e99c (diff)
Reformat all the things. Have fun with merge conflicts.
Diffstat (limited to 'Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp')
-rw-r--r--Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp484
1 files changed, 228 insertions, 256 deletions
diff --git a/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp
index fda14dd7e1..76e19777ab 100644
--- a/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp
+++ b/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
+#include "VideoBackends/D3D12/PSTextureEncoder.h"
#include "Core/HW/Memmap.h"
#include "VideoBackends/D3D12/D3DBase.h"
#include "VideoBackends/D3D12/D3DCommandListManager.h"
@@ -10,7 +11,6 @@
#include "VideoBackends/D3D12/D3DState.h"
#include "VideoBackends/D3D12/D3DUtil.h"
#include "VideoBackends/D3D12/FramebufferManager.h"
-#include "VideoBackends/D3D12/PSTextureEncoder.h"
#include "VideoBackends/D3D12/Render.h"
#include "VideoBackends/D3D12/StaticShaderCache.h"
#include "VideoBackends/D3D12/TextureCache.h"
@@ -19,13 +19,12 @@
namespace DX12
{
-
struct EFBEncodeParams
{
- DWORD SrcLeft;
- DWORD SrcTop;
- DWORD DestWidth;
- DWORD ScaleFactor;
+ DWORD SrcLeft;
+ DWORD SrcTop;
+ DWORD DestWidth;
+ DWORD ScaleFactor;
};
PSTextureEncoder::PSTextureEncoder()
@@ -34,268 +33,241 @@ PSTextureEncoder::PSTextureEncoder()
void PSTextureEncoder::Init()
{
- // Create output texture RGBA format
- D3D12_RESOURCE_DESC out_tex_desc = CD3DX12_RESOURCE_DESC::Tex2D(
- DXGI_FORMAT_B8G8R8A8_UNORM,
- EFB_WIDTH * 4,
- EFB_HEIGHT / 4,
- 1,
- 0,
- 1,
- 0,
- D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET
- );
-
- D3D12_CLEAR_VALUE optimized_clear_value = { DXGI_FORMAT_B8G8R8A8_UNORM, { 0.0f, 0.0f, 0.0f, 1.0f } };
-
- CheckHR(
- D3D::device12->CreateCommittedResource(
- &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
- D3D12_HEAP_FLAG_NONE,
- &out_tex_desc,
- D3D12_RESOURCE_STATE_COPY_SOURCE,
- &optimized_clear_value,
- IID_PPV_ARGS(&m_out)
- )
- );
-
- D3D::SetDebugObjectName12(m_out, "efb encoder output texture");
-
- // Create output render target view
- D3D12_RENDER_TARGET_VIEW_DESC tex_rtv_desc = {
- DXGI_FORMAT_B8G8R8A8_UNORM, // DXGI_FORMAT Format;
- D3D12_RTV_DIMENSION_TEXTURE2D // D3D12_RTV_DIMENSION ViewDimension;
- };
-
- tex_rtv_desc.Texture2D.MipSlice = 0;
-
- D3D::rtv_descriptor_heap_mgr->Allocate(&m_out_rtv_cpu);
- D3D::device12->CreateRenderTargetView(m_out, &tex_rtv_desc, m_out_rtv_cpu);
-
- // Create output staging buffer
- CheckHR(
- D3D::device12->CreateCommittedResource(
- &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK),
- D3D12_HEAP_FLAG_NONE,
- &CD3DX12_RESOURCE_DESC::Buffer(
- D3D::AlignValue(static_cast<unsigned int>(out_tex_desc.Width) * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) *
- out_tex_desc.Height
- ),
- D3D12_RESOURCE_STATE_COPY_DEST,
- nullptr,
- IID_PPV_ARGS(&m_out_readback_buffer)
- )
- );
-
- D3D::SetDebugObjectName12(m_out_readback_buffer, "efb encoder output staging buffer");
-
- // Create constant buffer for uploading data to shaders. Need to align to 256 bytes.
- unsigned int encode_params_buffer_size = (sizeof(EFBEncodeParams) + 0xff) & ~0xff;
-
- CheckHR(
- D3D::device12->CreateCommittedResource(
- &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
- D3D12_HEAP_FLAG_NONE,
- &CD3DX12_RESOURCE_DESC::Buffer(encode_params_buffer_size),
- D3D12_RESOURCE_STATE_GENERIC_READ,
- nullptr,
- IID_PPV_ARGS(&m_encode_params_buffer)
- )
- );
-
- D3D::SetDebugObjectName12(m_encode_params_buffer, "efb encoder params buffer");
-
- // NOTE: This upload buffer is okay to overwrite each time, since we block until completion when it's used anyway.
- D3D12_RANGE read_range = {};
- CheckHR(m_encode_params_buffer->Map(0, &read_range, &m_encode_params_buffer_data));
-
- m_ready = true;
+ // Create output texture RGBA format
+ D3D12_RESOURCE_DESC out_tex_desc =
+ CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_B8G8R8A8_UNORM, EFB_WIDTH * 4, EFB_HEIGHT / 4, 1, 0,
+ 1, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);
+
+ D3D12_CLEAR_VALUE optimized_clear_value = {DXGI_FORMAT_B8G8R8A8_UNORM, {0.0f, 0.0f, 0.0f, 1.0f}};
+
+ CheckHR(D3D::device12->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &out_tex_desc,
+ D3D12_RESOURCE_STATE_COPY_SOURCE, &optimized_clear_value, IID_PPV_ARGS(&m_out)));
+
+ D3D::SetDebugObjectName12(m_out, "efb encoder output texture");
+
+ // Create output render target view
+ D3D12_RENDER_TARGET_VIEW_DESC tex_rtv_desc = {
+ DXGI_FORMAT_B8G8R8A8_UNORM, // DXGI_FORMAT Format;
+ D3D12_RTV_DIMENSION_TEXTURE2D // D3D12_RTV_DIMENSION ViewDimension;
+ };
+
+ tex_rtv_desc.Texture2D.MipSlice = 0;
+
+ D3D::rtv_descriptor_heap_mgr->Allocate(&m_out_rtv_cpu);
+ D3D::device12->CreateRenderTargetView(m_out, &tex_rtv_desc, m_out_rtv_cpu);
+
+ // Create output staging buffer
+ CheckHR(D3D::device12->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(
+ D3D::AlignValue(static_cast<unsigned int>(out_tex_desc.Width) * 4,
+ D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) *
+ out_tex_desc.Height),
+ D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_out_readback_buffer)));
+
+ D3D::SetDebugObjectName12(m_out_readback_buffer, "efb encoder output staging buffer");
+
+ // Create constant buffer for uploading data to shaders. Need to align to 256 bytes.
+ unsigned int encode_params_buffer_size = (sizeof(EFBEncodeParams) + 0xff) & ~0xff;
+
+ CheckHR(D3D::device12->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(encode_params_buffer_size), D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&m_encode_params_buffer)));
+
+ D3D::SetDebugObjectName12(m_encode_params_buffer, "efb encoder params buffer");
+
+ // NOTE: This upload buffer is okay to overwrite each time, since we block until completion when
+ // it's used anyway.
+ D3D12_RANGE read_range = {};
+ CheckHR(m_encode_params_buffer->Map(0, &read_range, &m_encode_params_buffer_data));
+
+ m_ready = true;
}
void PSTextureEncoder::Shutdown()
{
- m_ready = false;
+ m_ready = false;
- D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_out);
- D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_out_readback_buffer);
- D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_encode_params_buffer);
+ D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_out);
+ D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_out_readback_buffer);
+ D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_encode_params_buffer);
- for (auto& it : m_static_shaders_blobs)
- {
- SAFE_RELEASE(it);
- }
+ for (auto& it : m_static_shaders_blobs)
+ {
+ SAFE_RELEASE(it);
+ }
- m_static_shaders_blobs.clear();
- m_static_shaders_map.clear();
+ m_static_shaders_blobs.clear();
+ m_static_shaders_map.clear();
}
-void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
- PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
- bool is_intensity, bool scale_by_half)
+void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
+ u32 num_blocks_y, u32 memory_stride,
+ PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
+ bool is_intensity, bool scale_by_half)
{
- if (!m_ready) // Make sure we initialized OK
- return;
-
- D3D::command_list_mgr->CPUAccessNotify();
-
- // Resolve MSAA targets before copying.
- D3DTexture2D* efb_source = (src_format == PEControl::Z24) ?
- FramebufferManager::GetResolvedEFBDepthTexture() :
- // EXISTINGD3D11TODO: Instead of resolving EFB, it would be better to pick out a
- // single sample from each pixel. The game may break if it isn't
- // expecting the blurred edges around multisampled shapes.
- FramebufferManager::GetResolvedEFBColorTexture();
-
- // GetResolvedEFBDepthTexture will set the render targets, when MSAA is enabled
- // (since it needs to do a manual depth resolve). So make sure to set the RTs
- // afterwards.
-
- const u32 words_per_row = bytes_per_row / sizeof(u32);
-
- D3D::SetViewportAndScissor(0, 0, words_per_row, num_blocks_y);
-
- constexpr EFBRectangle full_src_rect(0, 0, EFB_WIDTH, EFB_HEIGHT);
-
- TargetRectangle target_rect = g_renderer->ConvertEFBRectangle(full_src_rect);
-
- D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET, 0);
- D3D::current_command_list->OMSetRenderTargets(1, &m_out_rtv_cpu, FALSE, nullptr);
-
- EFBEncodeParams params;
- params.SrcLeft = src_rect.left;
- params.SrcTop = src_rect.top;
- params.DestWidth = native_width;
- params.ScaleFactor = scale_by_half ? 2 : 1;
-
- memcpy(m_encode_params_buffer_data, &params, sizeof(params));
- D3D::current_command_list->SetGraphicsRootConstantBufferView(
- DESCRIPTOR_TABLE_PS_CBVONE,
- m_encode_params_buffer->GetGPUVirtualAddress()
- );
-
- D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true);
-
- // Use linear filtering if (bScaleByHalf), use point filtering otherwise
- if (scale_by_half)
- D3D::SetLinearCopySampler();
- else
- D3D::SetPointCopySampler();
-
- D3D::DrawShadedTexQuad(efb_source,
- target_rect.AsRECT(),
- Renderer::GetTargetWidth(),
- Renderer::GetTargetHeight(),
- SetStaticShader(format, src_format, is_intensity, scale_by_half),
- StaticShaderCache::GetSimpleVertexShader(),
- StaticShaderCache::GetSimpleVertexShaderInputLayout(),
- D3D12_SHADER_BYTECODE(),
- 1.0f,
- 0,
- DXGI_FORMAT_B8G8R8A8_UNORM,
- false,
- false /* Render target is not multisampled */
- );
-
- // Copy to staging buffer
- D3D12_BOX src_box = CD3DX12_BOX(0, 0, 0, words_per_row, num_blocks_y, 1);
-
- D3D12_TEXTURE_COPY_LOCATION dst_location = {};
- dst_location.pResource = m_out_readback_buffer;
- dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
- dst_location.PlacedFootprint.Offset = 0;
- dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
- dst_location.PlacedFootprint.Footprint.Width = EFB_WIDTH * 4;
- dst_location.PlacedFootprint.Footprint.Height = EFB_HEIGHT / 4;
- dst_location.PlacedFootprint.Footprint.Depth = 1;
- dst_location.PlacedFootprint.Footprint.RowPitch = D3D::AlignValue(dst_location.PlacedFootprint.Footprint.Width * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
-
- D3D12_TEXTURE_COPY_LOCATION src_location = {};
- src_location.pResource = m_out;
- src_location.SubresourceIndex = 0;
- src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
-
- D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE, 0);
- D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box);
-
- FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
- FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
-
- // State is automatically restored after executing command list.
- D3D::command_list_mgr->ExecuteQueuedWork(true);
-
- // Transfer staging buffer to GameCube/Wii RAM
- void* readback_data_map;
- D3D12_RANGE read_range = { 0, dst_location.PlacedFootprint.Footprint.RowPitch * num_blocks_y };
- CheckHR(m_out_readback_buffer->Map(0, &read_range, &readback_data_map));
-
- u8* src = static_cast<u8*>(readback_data_map);
- u32 read_stride = std::min(bytes_per_row, dst_location.PlacedFootprint.Footprint.RowPitch);
- for (unsigned int y = 0; y < num_blocks_y; ++y)
- {
- memcpy(dst, src, read_stride);
-
- dst += memory_stride;
- src += dst_location.PlacedFootprint.Footprint.RowPitch;
- }
-
- D3D12_RANGE write_range = {};
- m_out_readback_buffer->Unmap(0, &write_range);
+ if (!m_ready) // Make sure we initialized OK
+ return;
+
+ D3D::command_list_mgr->CPUAccessNotify();
+
+ // Resolve MSAA targets before copying.
+ D3DTexture2D* efb_source =
+ (src_format == PEControl::Z24) ?
+ FramebufferManager::GetResolvedEFBDepthTexture() :
+ // EXISTINGD3D11TODO: Instead of resolving EFB, it would be better to pick out a
+ // single sample from each pixel. The game may break if it isn't
+ // expecting the blurred edges around multisampled shapes.
+ FramebufferManager::GetResolvedEFBColorTexture();
+
+ // GetResolvedEFBDepthTexture will set the render targets, when MSAA is enabled
+ // (since it needs to do a manual depth resolve). So make sure to set the RTs
+ // afterwards.
+
+ const u32 words_per_row = bytes_per_row / sizeof(u32);
+
+ D3D::SetViewportAndScissor(0, 0, words_per_row, num_blocks_y);
+
+ constexpr EFBRectangle full_src_rect(0, 0, EFB_WIDTH, EFB_HEIGHT);
+
+ TargetRectangle target_rect = g_renderer->ConvertEFBRectangle(full_src_rect);
+
+ D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_COPY_SOURCE,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, 0);
+ D3D::current_command_list->OMSetRenderTargets(1, &m_out_rtv_cpu, FALSE, nullptr);
+
+ EFBEncodeParams params;
+ params.SrcLeft = src_rect.left;
+ params.SrcTop = src_rect.top;
+ params.DestWidth = native_width;
+ params.ScaleFactor = scale_by_half ? 2 : 1;
+
+ memcpy(m_encode_params_buffer_data, &params, sizeof(params));
+ D3D::current_command_list->SetGraphicsRootConstantBufferView(
+ DESCRIPTOR_TABLE_PS_CBVONE, m_encode_params_buffer->GetGPUVirtualAddress());
+
+ D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true);
+
+ // Use linear filtering if (bScaleByHalf), use point filtering otherwise
+ if (scale_by_half)
+ D3D::SetLinearCopySampler();
+ else
+ D3D::SetPointCopySampler();
+
+ D3D::DrawShadedTexQuad(
+ efb_source, target_rect.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
+ SetStaticShader(format, src_format, is_intensity, scale_by_half),
+ StaticShaderCache::GetSimpleVertexShader(),
+ StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0f, 0,
+ DXGI_FORMAT_B8G8R8A8_UNORM, false, false /* Render target is not multisampled */
+ );
+
+ // Copy to staging buffer
+ D3D12_BOX src_box = CD3DX12_BOX(0, 0, 0, words_per_row, num_blocks_y, 1);
+
+ D3D12_TEXTURE_COPY_LOCATION dst_location = {};
+ dst_location.pResource = m_out_readback_buffer;
+ dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
+ dst_location.PlacedFootprint.Offset = 0;
+ dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ dst_location.PlacedFootprint.Footprint.Width = EFB_WIDTH * 4;
+ dst_location.PlacedFootprint.Footprint.Height = EFB_HEIGHT / 4;
+ dst_location.PlacedFootprint.Footprint.Depth = 1;
+ dst_location.PlacedFootprint.Footprint.RowPitch = D3D::AlignValue(
+ dst_location.PlacedFootprint.Footprint.Width * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
+
+ D3D12_TEXTURE_COPY_LOCATION src_location = {};
+ src_location.pResource = m_out;
+ src_location.SubresourceIndex = 0;
+ src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
+
+ D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_RENDER_TARGET,
+ D3D12_RESOURCE_STATE_COPY_SOURCE, 0);
+ D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box);
+
+ FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(
+ D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
+ FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(
+ D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
+
+ // State is automatically restored after executing command list.
+ D3D::command_list_mgr->ExecuteQueuedWork(true);
+
+ // Transfer staging buffer to GameCube/Wii RAM
+ void* readback_data_map;
+ D3D12_RANGE read_range = {0, dst_location.PlacedFootprint.Footprint.RowPitch * num_blocks_y};
+ CheckHR(m_out_readback_buffer->Map(0, &read_range, &readback_data_map));
+
+ u8* src = static_cast<u8*>(readback_data_map);
+ u32 read_stride = std::min(bytes_per_row, dst_location.PlacedFootprint.Footprint.RowPitch);
+ for (unsigned int y = 0; y < num_blocks_y; ++y)
+ {
+ memcpy(dst, src, read_stride);
+
+ dst += memory_stride;
+ src += dst_location.PlacedFootprint.Footprint.RowPitch;
+ }
+
+ D3D12_RANGE write_range = {};
+ m_out_readback_buffer->Unmap(0, &write_range);
}
-D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format, PEControl::PixelFormat src_format,
- bool is_intensity, bool scale_by_half)
+D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format,
+ PEControl::PixelFormat src_format,
+ bool is_intensity, bool scale_by_half)
{
- size_t fetch_num = static_cast<size_t>(src_format);
- size_t scaled_fetch_num = scale_by_half ? 1 : 0;
- size_t intensity_num = is_intensity ? 1 : 0;
- size_t generator_num = dst_format;
-
- ComboKey key = MakeComboKey(dst_format, src_format, is_intensity, scale_by_half);
-
- ComboMap::iterator it = m_static_shaders_map.find(key);
- if (it == m_static_shaders_map.end())
- {
- INFO_LOG(VIDEO, "Compiling efb encoding shader for dst_format 0x%X, src_format %d, is_intensity %d, scale_by_half %d",
- dst_format, static_cast<int>(src_format), is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
-
- u32 format = dst_format;
-
- if (src_format == PEControl::Z24)
- {
- format |= _GX_TF_ZTF;
- if (dst_format == 11)
- format = GX_TF_Z16;
- else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
- format |= _GX_TF_CTF;
- }
- else
- {
- if (dst_format > GX_TF_RGBA8 || (dst_format < GX_TF_RGB565 && !is_intensity))
- format |= _GX_TF_CTF;
- }
-
- ID3DBlob* bytecode = nullptr;
- const char* shader = TextureConversionShader::GenerateEncodingShader(format, API_D3D);
- if (!D3D::CompilePixelShader(shader, &bytecode))
- {
- WARN_LOG(VIDEO, "EFB encoder shader for dst_format 0x%X, src_format %d, is_intensity %d, scale_by_half %d failed to compile",
- dst_format, static_cast<int>(src_format), is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
- m_static_shaders_blobs[key] = {};
- return {};
- }
-
- D3D12_SHADER_BYTECODE new_shader = {
- bytecode->GetBufferPointer(),
- bytecode->GetBufferSize()
- };
-
- it = m_static_shaders_map.emplace(key, new_shader).first;
-
- // Keep track of the ID3DBlobs, so we can free them upon shutdown.
- m_static_shaders_blobs.push_back(bytecode);
- }
-
- return it->second;
+ size_t fetch_num = static_cast<size_t>(src_format);
+ size_t scaled_fetch_num = scale_by_half ? 1 : 0;
+ size_t intensity_num = is_intensity ? 1 : 0;
+ size_t generator_num = dst_format;
+
+ ComboKey key = MakeComboKey(dst_format, src_format, is_intensity, scale_by_half);
+
+ ComboMap::iterator it = m_static_shaders_map.find(key);
+ if (it == m_static_shaders_map.end())
+ {
+ INFO_LOG(VIDEO, "Compiling efb encoding shader for dst_format 0x%X, src_format %d, "
+ "is_intensity %d, scale_by_half %d",
+ dst_format, static_cast<int>(src_format), is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
+
+ u32 format = dst_format;
+
+ if (src_format == PEControl::Z24)
+ {
+ format |= _GX_TF_ZTF;
+ if (dst_format == 11)
+ format = GX_TF_Z16;
+ else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
+ format |= _GX_TF_CTF;
+ }
+ else
+ {
+ if (dst_format > GX_TF_RGBA8 || (dst_format < GX_TF_RGB565 && !is_intensity))
+ format |= _GX_TF_CTF;
+ }
+
+ ID3DBlob* bytecode = nullptr;
+ const char* shader = TextureConversionShader::GenerateEncodingShader(format, API_D3D);
+ if (!D3D::CompilePixelShader(shader, &bytecode))
+ {
+ WARN_LOG(VIDEO, "EFB encoder shader for dst_format 0x%X, src_format %d, is_intensity %d, "
+ "scale_by_half %d failed to compile",
+ dst_format, static_cast<int>(src_format), is_intensity ? 1 : 0,
+ scale_by_half ? 1 : 0);
+ m_static_shaders_blobs[key] = {};
+ return {};
+ }
+
+ D3D12_SHADER_BYTECODE new_shader = {bytecode->GetBufferPointer(), bytecode->GetBufferSize()};
+
+ it = m_static_shaders_map.emplace(key, new_shader).first;
+
+ // Keep track of the ID3DBlobs, so we can free them upon shutdown.
+ m_static_shaders_blobs.push_back(bytecode);
+ }
+
+ return it->second;
}
-
}