VideoBackends: Support updated texture encoding shader generators

This commit is contained in:
Stenzek
2017-04-04 23:55:36 +10:00
parent 3847e226ab
commit e9850aa0f2
20 changed files with 194 additions and 279 deletions

View File

@ -101,18 +101,18 @@ void PSTextureEncoder::Shutdown()
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)
for (auto& it : m_shader_blobs)
{
SAFE_RELEASE(it);
}
m_static_shaders_blobs.clear();
m_static_shaders_map.clear();
m_shader_blobs.clear();
m_encoding_shaders.clear();
}
void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
const EFBRectangle& src_rect, bool is_intensity, bool scale_by_half)
void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_width,
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half)
{
if (!m_ready) // Make sure we initialized OK
return;
@ -167,8 +167,7 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
D3D::DrawShadedTexQuad(
efb_source, target_rect.AsRECT(), g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(),
SetStaticShader(format, is_depth_copy, is_intensity, scale_by_half),
StaticShaderCache::GetSimpleVertexShader(),
GetEncodingPixelShader(format), StaticShaderCache::GetSimpleVertexShader(),
StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0f, 0,
DXGI_FORMAT_B8G8R8A8_UNORM, false, false /* Render target is not multisampled */
);
@ -223,53 +222,27 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
m_out_readback_buffer->Unmap(0, &write_range);
}
D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format, bool is_depth_copy,
bool is_intensity, bool scale_by_half)
D3D12_SHADER_BYTECODE PSTextureEncoder::GetEncodingPixelShader(const EFBCopyFormat& format)
{
ComboKey key = MakeComboKey(dst_format, is_depth_copy, is_intensity, scale_by_half);
auto iter = m_encoding_shaders.find(format);
if (iter != m_encoding_shaders.end())
return iter->second;
ComboMap::iterator it = m_static_shaders_map.find(key);
if (it == m_static_shaders_map.end())
ID3DBlob* bytecode = nullptr;
const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::D3D);
if (!D3D::CompilePixelShader(shader, &bytecode))
{
INFO_LOG(VIDEO, "Compiling efb encoding shader for dst_format 0x%X, is_depth_copy %d, "
"is_intensity %d, scale_by_half %d",
dst_format, is_depth_copy, is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
u32 format = dst_format;
if (is_depth_copy)
{
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, APIType::D3D);
if (!D3D::CompilePixelShader(shader, &bytecode))
{
WARN_LOG(VIDEO, "EFB encoder shader for dst_format 0x%X, is_depth_copy %d, is_intensity %d, "
"scale_by_half %d failed to compile",
dst_format, is_depth_copy, 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);
PanicAlert("Failed to compile texture encoding shader.");
m_encoding_shaders[format] = {};
return {};
}
return it->second;
D3D12_SHADER_BYTECODE new_shader = {bytecode->GetBufferPointer(), bytecode->GetBufferSize()};
m_encoding_shaders.emplace(format, new_shader);
// Keep track of the ID3DBlobs, so we can free them upon shutdown.
m_shader_blobs.push_back(bytecode);
return new_shader;
}
}

View File

@ -9,6 +9,7 @@
#include "Common/CommonTypes.h"
#include "VideoBackends/D3D12/D3DBase.h"
#include "VideoCommon/TextureConversionShader.h"
#include "VideoCommon/VideoCommon.h"
namespace DX12
@ -20,11 +21,13 @@ public:
void Init();
void Shutdown();
void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
bool is_intensity, bool scale_by_half);
void Encode(u8* dst, const EFBCopyFormat& format, u32 native_width, u32 bytes_per_row,
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
bool scale_by_half);
private:
D3D12_SHADER_BYTECODE GetEncodingPixelShader(const EFBCopyFormat& format);
bool m_ready = false;
ID3D12Resource* m_out = nullptr;
@ -35,19 +38,7 @@ private:
ID3D12Resource* m_encode_params_buffer = nullptr;
void* m_encode_params_buffer_data = nullptr;
D3D12_SHADER_BYTECODE SetStaticShader(unsigned int dst_format, bool is_depth_copy,
bool is_intensity, bool scale_by_half);
using ComboKey = unsigned int; // Key for a shader combination
static ComboKey MakeComboKey(unsigned int dst_format, bool is_depth_copy, bool is_intensity,
bool scale_by_half)
{
return (dst_format << 4) | (is_depth_copy << 2) | (is_intensity ? (1 << 1) : 0) |
(scale_by_half ? (1 << 0) : 0);
}
using ComboMap = std::map<ComboKey, D3D12_SHADER_BYTECODE>;
ComboMap m_static_shaders_map;
std::vector<ID3DBlob*> m_static_shaders_blobs;
std::map<EFBCopyFormat, D3D12_SHADER_BYTECODE> m_encoding_shaders;
std::vector<ID3DBlob*> m_shader_blobs;
};
}

View File

@ -306,12 +306,12 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool is_depth_copy, const EFBRe
g_renderer->RestoreAPIState();
}
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width,
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half)
{
s_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride,
is_depth_copy, srcRect, isIntensity, scaleByHalf);
is_depth_copy, src_rect, scale_by_half);
}
static const constexpr char s_palette_shader_hlsl[] =

View File

@ -60,9 +60,9 @@ private:
void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette,
TlutFormat format) override;
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
bool is_intensity, bool scale_by_half) override;
void CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width, u32 bytes_per_row,
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
const EFBRectangle& src_rect, bool scale_by_half) override;
bool CompileShaders() override { return true; }
void DeleteShaders() override {}