Merge pull request #4569 from degasus/texcache2
TextureCache: Extract BP enum check to VideoCommon.
This commit is contained in:
commit
fd54d4f767
|
@ -86,7 +86,7 @@ void PSTextureEncoder::Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
if (!m_ready) // Make sure we initialized OK
|
if (!m_ready) // Make sure we initialized OK
|
||||||
|
@ -95,12 +95,11 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// Resolve MSAA targets before copying.
|
// Resolve MSAA targets before copying.
|
||||||
ID3D11ShaderResourceView* pEFB =
|
|
||||||
(srcFormat == PEControl::Z24) ?
|
|
||||||
FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() :
|
|
||||||
// FIXME: Instead of resolving EFB, it would be better to pick out a
|
// FIXME: 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
|
// single sample from each pixel. The game may break if it isn't
|
||||||
// expecting the blurred edges around multisampled shapes.
|
// expecting the blurred edges around multisampled shapes.
|
||||||
|
ID3D11ShaderResourceView* pEFB = is_depth_copy ?
|
||||||
|
FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() :
|
||||||
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
|
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
|
||||||
|
|
||||||
// Reset API
|
// Reset API
|
||||||
|
@ -137,7 +136,7 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
pEFB, targetRect.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
pEFB, targetRect.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
||||||
SetStaticShader(format, srcFormat, isIntensity, scaleByHalf),
|
SetStaticShader(format, is_depth_copy, isIntensity, scaleByHalf),
|
||||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
// Copy to staging buffer
|
// Copy to staging buffer
|
||||||
|
@ -167,27 +166,22 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PSTextureEncoder::SetStaticShader(unsigned int dstFormat,
|
ID3D11PixelShader* PSTextureEncoder::SetStaticShader(unsigned int dstFormat, bool is_depth_copy,
|
||||||
PEControl::PixelFormat srcFormat,
|
|
||||||
bool isIntensity, bool scaleByHalf)
|
bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
size_t fetchNum = static_cast<size_t>(srcFormat);
|
ComboKey key = MakeComboKey(dstFormat, is_depth_copy, isIntensity, scaleByHalf);
|
||||||
size_t scaledFetchNum = scaleByHalf ? 1 : 0;
|
|
||||||
size_t intensityNum = isIntensity ? 1 : 0;
|
|
||||||
size_t generatorNum = dstFormat;
|
|
||||||
|
|
||||||
ComboKey key = MakeComboKey(dstFormat, srcFormat, isIntensity, scaleByHalf);
|
|
||||||
|
|
||||||
ComboMap::iterator it = m_staticShaders.find(key);
|
ComboMap::iterator it = m_staticShaders.find(key);
|
||||||
if (it == m_staticShaders.end())
|
if (it == m_staticShaders.end())
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Compiling efb encoding shader for dstFormat 0x%X, srcFormat %d, isIntensity "
|
INFO_LOG(VIDEO,
|
||||||
|
"Compiling efb encoding shader for dstFormat 0x%X, is_depth_copy %d, isIntensity "
|
||||||
"%d, scaleByHalf %d",
|
"%d, scaleByHalf %d",
|
||||||
dstFormat, static_cast<int>(srcFormat), isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
dstFormat, is_depth_copy, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
||||||
|
|
||||||
u32 format = dstFormat;
|
u32 format = dstFormat;
|
||||||
|
|
||||||
if (srcFormat == PEControl::Z24)
|
if (is_depth_copy)
|
||||||
{
|
{
|
||||||
format |= _GX_TF_ZTF;
|
format |= _GX_TF_ZTF;
|
||||||
if (dstFormat == 11)
|
if (dstFormat == 11)
|
||||||
|
@ -205,9 +199,9 @@ ID3D11PixelShader* PSTextureEncoder::SetStaticShader(unsigned int dstFormat,
|
||||||
const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::D3D);
|
const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::D3D);
|
||||||
if (!D3D::CompilePixelShader(shader, &bytecode))
|
if (!D3D::CompilePixelShader(shader, &bytecode))
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "EFB encoder shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, "
|
WARN_LOG(VIDEO, "EFB encoder shader for dstFormat 0x%X, is_depth_copy %d, isIntensity %d, "
|
||||||
"scaleByHalf %d failed to compile",
|
"scaleByHalf %d failed to compile",
|
||||||
dstFormat, static_cast<int>(srcFormat), isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
dstFormat, is_depth_copy, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
||||||
m_staticShaders[key] = nullptr;
|
m_staticShaders[key] = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -218,8 +212,9 @@ ID3D11PixelShader* PSTextureEncoder::SetStaticShader(unsigned int dstFormat,
|
||||||
CHECK(SUCCEEDED(hr), "create efb encoder pixel shader");
|
CHECK(SUCCEEDED(hr), "create efb encoder pixel shader");
|
||||||
|
|
||||||
char debugName[255] = {};
|
char debugName[255] = {};
|
||||||
sprintf_s(debugName, "efb encoder pixel shader (dst:%d, src:%d, intensity:%d, scale:%d)",
|
sprintf_s(debugName,
|
||||||
dstFormat, srcFormat, isIntensity, scaleByHalf);
|
"efb encoder pixel shader (dst:%d, is_depth_copy:%d, intensity:%d, scale:%d)",
|
||||||
|
dstFormat, is_depth_copy, isIntensity, scaleByHalf);
|
||||||
D3D::SetDebugObjectName(newShader, debugName);
|
D3D::SetDebugObjectName(newShader, debugName);
|
||||||
|
|
||||||
it = m_staticShaders.emplace(key, newShader).first;
|
it = m_staticShaders.emplace(key, newShader).first;
|
||||||
|
|
|
@ -31,8 +31,8 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||||
u32 memory_stride, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool isIntensity, bool scaleByHalf);
|
bool scaleByHalf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
@ -42,16 +42,16 @@ private:
|
||||||
ID3D11Texture2D* m_outStage;
|
ID3D11Texture2D* m_outStage;
|
||||||
ID3D11Buffer* m_encodeParams;
|
ID3D11Buffer* m_encodeParams;
|
||||||
|
|
||||||
ID3D11PixelShader* SetStaticShader(unsigned int dstFormat, PEControl::PixelFormat srcFormat,
|
ID3D11PixelShader* SetStaticShader(unsigned int dstFormat, bool is_depth_copy, bool isIntensity,
|
||||||
bool isIntensity, bool scaleByHalf);
|
bool scaleByHalf);
|
||||||
|
|
||||||
typedef unsigned int ComboKey; // Key for a shader combination
|
typedef unsigned int ComboKey; // Key for a shader combination
|
||||||
|
|
||||||
ComboKey MakeComboKey(unsigned int dstFormat, PEControl::PixelFormat srcFormat, bool isIntensity,
|
ComboKey MakeComboKey(unsigned int dstFormat, bool is_depth_copy, bool isIntensity,
|
||||||
bool scaleByHalf)
|
bool scaleByHalf)
|
||||||
{
|
{
|
||||||
return (dstFormat << 4) | (static_cast<int>(srcFormat) << 2) | (isIntensity ? (1 << 1) : 0) |
|
return (dstFormat << 4) | (static_cast<int>(is_depth_copy) << 2) |
|
||||||
(scaleByHalf ? (1 << 0) : 0);
|
(isIntensity ? (1 << 1) : 0) | (scaleByHalf ? (1 << 0) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::map<ComboKey, ID3D11PixelShader*> ComboMap;
|
typedef std::map<ComboKey, ID3D11PixelShader*> ComboMap;
|
||||||
|
|
|
@ -179,22 +179,21 @@ TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect,
|
||||||
const EFBRectangle& srcRect, bool scaleByHalf,
|
bool scaleByHalf, unsigned int cbufid,
|
||||||
unsigned int cbufid, const float* colmat)
|
const float* colmat)
|
||||||
{
|
{
|
||||||
// When copying at half size, in multisampled mode, resolve the color/depth buffer first.
|
// 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
|
// This is because multisampled texture reads go through Load, not Sample, and the linear
|
||||||
// filter is ignored.
|
// filter is ignored.
|
||||||
bool multisampled = (g_ActiveConfig.iMultisamples > 1);
|
bool multisampled = (g_ActiveConfig.iMultisamples > 1);
|
||||||
ID3D11ShaderResourceView* efbTexSRV = (srcFormat == PEControl::Z24) ?
|
ID3D11ShaderResourceView* efbTexSRV = is_depth_copy ?
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetSRV() :
|
FramebufferManager::GetEFBDepthTexture()->GetSRV() :
|
||||||
FramebufferManager::GetEFBColorTexture()->GetSRV();
|
FramebufferManager::GetEFBColorTexture()->GetSRV();
|
||||||
if (multisampled && scaleByHalf)
|
if (multisampled && scaleByHalf)
|
||||||
{
|
{
|
||||||
multisampled = false;
|
multisampled = false;
|
||||||
efbTexSRV = (srcFormat == PEControl::Z24) ?
|
efbTexSRV = is_depth_copy ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() :
|
||||||
FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() :
|
|
||||||
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
|
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +238,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat
|
||||||
// Create texture copy
|
// Create texture copy
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
efbTexSRV, &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
efbTexSRV, &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
||||||
srcFormat == PEControl::Z24 ? PixelShaderCache::GetDepthMatrixProgram(multisampled) :
|
is_depth_copy ? PixelShaderCache::GetDepthMatrixProgram(multisampled) :
|
||||||
PixelShaderCache::GetColorMatrixProgram(multisampled),
|
PixelShaderCache::GetColorMatrixProgram(multisampled),
|
||||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(),
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(),
|
||||||
GeometryShaderCache::GetCopyGeometryShader());
|
GeometryShaderCache::GetCopyGeometryShader());
|
||||||
|
@ -251,11 +250,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
g_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride,
|
g_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride,
|
||||||
srcFormat, srcRect, isIntensity, scaleByHalf);
|
is_depth_copy, srcRect, isIntensity, scaleByHalf);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char palette_shader[] =
|
const char palette_shader[] =
|
||||||
|
|
|
@ -34,8 +34,8 @@ private:
|
||||||
|
|
||||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override;
|
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override;
|
||||||
|
|
||||||
void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||||
bool scaleByHalf, unsigned int cbufid, const float* colmat) override;
|
unsigned int cbufid, const float* colmat) override;
|
||||||
|
|
||||||
void Bind(unsigned int stage) override;
|
void Bind(unsigned int stage) override;
|
||||||
bool Save(const std::string& filename, unsigned int level) override;
|
bool Save(const std::string& filename, unsigned int level) override;
|
||||||
|
@ -54,8 +54,8 @@ private:
|
||||||
TlutFormat format) override;
|
TlutFormat format) override;
|
||||||
|
|
||||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void 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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool isIntensity, bool scaleByHalf) override;
|
bool scaleByHalf) override;
|
||||||
|
|
||||||
bool CompileShaders() override { return true; }
|
bool CompileShaders() override { return true; }
|
||||||
void DeleteShaders() override {}
|
void DeleteShaders() override {}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
// Returns size in bytes of encoded block of memory
|
// Returns size in bytes of encoded block of memory
|
||||||
virtual void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
virtual void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||||
u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& srcRect,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) = 0;
|
bool isIntensity, bool scaleByHalf) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,9 +106,8 @@ void PSTextureEncoder::Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
|
const EFBRectangle& src_rect, bool is_intensity, bool scale_by_half)
|
||||||
bool is_intensity, bool scale_by_half)
|
|
||||||
{
|
{
|
||||||
if (!m_ready) // Make sure we initialized OK
|
if (!m_ready) // Make sure we initialized OK
|
||||||
return;
|
return;
|
||||||
|
@ -117,7 +116,7 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
|
||||||
|
|
||||||
// Resolve MSAA targets before copying.
|
// Resolve MSAA targets before copying.
|
||||||
D3DTexture2D* efb_source =
|
D3DTexture2D* efb_source =
|
||||||
(src_format == PEControl::Z24) ?
|
is_depth_copy ?
|
||||||
FramebufferManager::GetResolvedEFBDepthTexture() :
|
FramebufferManager::GetResolvedEFBDepthTexture() :
|
||||||
// EXISTINGD3D11TODO: Instead of resolving EFB, it would be better to pick out a
|
// 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
|
// single sample from each pixel. The game may break if it isn't
|
||||||
|
@ -163,7 +162,7 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
|
||||||
|
|
||||||
D3D::DrawShadedTexQuad(
|
D3D::DrawShadedTexQuad(
|
||||||
efb_source, target_rect.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
efb_source, target_rect.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
||||||
SetStaticShader(format, src_format, is_intensity, scale_by_half),
|
SetStaticShader(format, is_depth_copy, is_intensity, scale_by_half),
|
||||||
StaticShaderCache::GetSimpleVertexShader(),
|
StaticShaderCache::GetSimpleVertexShader(),
|
||||||
StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0f, 0,
|
StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0f, 0,
|
||||||
DXGI_FORMAT_B8G8R8A8_UNORM, false, false /* Render target is not multisampled */
|
DXGI_FORMAT_B8G8R8A8_UNORM, false, false /* Render target is not multisampled */
|
||||||
|
@ -219,27 +218,21 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
|
||||||
m_out_readback_buffer->Unmap(0, &write_range);
|
m_out_readback_buffer->Unmap(0, &write_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format,
|
D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format, bool is_depth_copy,
|
||||||
PEControl::PixelFormat src_format,
|
|
||||||
bool is_intensity, bool scale_by_half)
|
bool is_intensity, bool scale_by_half)
|
||||||
{
|
{
|
||||||
size_t fetch_num = static_cast<size_t>(src_format);
|
ComboKey key = MakeComboKey(dst_format, is_depth_copy, is_intensity, scale_by_half);
|
||||||
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);
|
ComboMap::iterator it = m_static_shaders_map.find(key);
|
||||||
if (it == m_static_shaders_map.end())
|
if (it == m_static_shaders_map.end())
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Compiling efb encoding shader for dst_format 0x%X, src_format %d, "
|
INFO_LOG(VIDEO, "Compiling efb encoding shader for dst_format 0x%X, is_depth_copy %d, "
|
||||||
"is_intensity %d, scale_by_half %d",
|
"is_intensity %d, scale_by_half %d",
|
||||||
dst_format, static_cast<int>(src_format), is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
|
dst_format, is_depth_copy, is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
|
||||||
|
|
||||||
u32 format = dst_format;
|
u32 format = dst_format;
|
||||||
|
|
||||||
if (src_format == PEControl::Z24)
|
if (is_depth_copy)
|
||||||
{
|
{
|
||||||
format |= _GX_TF_ZTF;
|
format |= _GX_TF_ZTF;
|
||||||
if (dst_format == 11)
|
if (dst_format == 11)
|
||||||
|
@ -257,10 +250,9 @@ D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format,
|
||||||
const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::D3D);
|
const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::D3D);
|
||||||
if (!D3D::CompilePixelShader(shader, &bytecode))
|
if (!D3D::CompilePixelShader(shader, &bytecode))
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "EFB encoder shader for dst_format 0x%X, src_format %d, is_intensity %d, "
|
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",
|
"scale_by_half %d failed to compile",
|
||||||
dst_format, static_cast<int>(src_format), is_intensity ? 1 : 0,
|
dst_format, is_depth_copy, is_intensity ? 1 : 0, scale_by_half ? 1 : 0);
|
||||||
scale_by_half ? 1 : 0);
|
|
||||||
m_static_shaders_blobs[key] = {};
|
m_static_shaders_blobs[key] = {};
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void 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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||||
bool is_intensity, bool scale_by_half);
|
bool is_intensity, bool scale_by_half);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -32,14 +32,14 @@ private:
|
||||||
ID3D12Resource* m_encode_params_buffer = nullptr;
|
ID3D12Resource* m_encode_params_buffer = nullptr;
|
||||||
void* m_encode_params_buffer_data = nullptr;
|
void* m_encode_params_buffer_data = nullptr;
|
||||||
|
|
||||||
D3D12_SHADER_BYTECODE SetStaticShader(unsigned int dst_format, PEControl::PixelFormat src_format,
|
D3D12_SHADER_BYTECODE SetStaticShader(unsigned int dst_format, bool is_depth_copy,
|
||||||
bool is_intensity, bool scale_by_half);
|
bool is_intensity, bool scale_by_half);
|
||||||
|
|
||||||
using ComboKey = unsigned int; // Key for a shader combination
|
using ComboKey = unsigned int; // Key for a shader combination
|
||||||
static ComboKey MakeComboKey(unsigned int dst_format, PEControl::PixelFormat src_format,
|
static ComboKey MakeComboKey(unsigned int dst_format, bool is_depth_copy, bool is_intensity,
|
||||||
bool is_intensity, bool scale_by_half)
|
bool scale_by_half)
|
||||||
{
|
{
|
||||||
return (dst_format << 4) | (static_cast<int>(src_format) << 2) | (is_intensity ? (1 << 1) : 0) |
|
return (dst_format << 4) | (is_depth_copy << 2) | (is_intensity ? (1 << 1) : 0) |
|
||||||
(scale_by_half ? (1 << 0) : 0);
|
(scale_by_half ? (1 << 0) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,21 +229,20 @@ TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat src_format,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect,
|
||||||
const EFBRectangle& srcRect, bool scale_by_half,
|
bool scale_by_half, unsigned int cbuf_id,
|
||||||
unsigned int cbuf_id, const float* colmat)
|
const float* colmat)
|
||||||
{
|
{
|
||||||
// When copying at half size, in multisampled mode, resolve the color/depth buffer first.
|
// 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
|
// This is because multisampled texture reads go through Load, not Sample, and the linear
|
||||||
// filter is ignored.
|
// filter is ignored.
|
||||||
bool multisampled = (g_ActiveConfig.iMultisamples > 1);
|
bool multisampled = (g_ActiveConfig.iMultisamples > 1);
|
||||||
D3DTexture2D* efb_tex = (src_format == PEControl::Z24) ?
|
D3DTexture2D* efb_tex = is_depth_copy ? FramebufferManager::GetEFBDepthTexture() :
|
||||||
FramebufferManager::GetEFBDepthTexture() :
|
|
||||||
FramebufferManager::GetEFBColorTexture();
|
FramebufferManager::GetEFBColorTexture();
|
||||||
if (multisampled && scale_by_half)
|
if (multisampled && scale_by_half)
|
||||||
{
|
{
|
||||||
multisampled = false;
|
multisampled = false;
|
||||||
efb_tex = (src_format == PEControl::Z24) ? FramebufferManager::GetResolvedEFBDepthTexture() :
|
efb_tex = is_depth_copy ? FramebufferManager::GetResolvedEFBDepthTexture() :
|
||||||
FramebufferManager::GetResolvedEFBColorTexture();
|
FramebufferManager::GetResolvedEFBColorTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +285,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat
|
||||||
// Create texture copy
|
// Create texture copy
|
||||||
D3D::DrawShadedTexQuad(
|
D3D::DrawShadedTexQuad(
|
||||||
efb_tex, &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
efb_tex, &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
||||||
(src_format == PEControl::Z24) ? StaticShaderCache::GetDepthMatrixPixelShader(multisampled) :
|
is_depth_copy ? StaticShaderCache::GetDepthMatrixPixelShader(multisampled) :
|
||||||
StaticShaderCache::GetColorMatrixPixelShader(multisampled),
|
StaticShaderCache::GetColorMatrixPixelShader(multisampled),
|
||||||
StaticShaderCache::GetSimpleVertexShader(),
|
StaticShaderCache::GetSimpleVertexShader(),
|
||||||
StaticShaderCache::GetSimpleVertexShaderInputLayout(),
|
StaticShaderCache::GetSimpleVertexShaderInputLayout(),
|
||||||
|
@ -305,11 +304,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
s_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride,
|
s_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride,
|
||||||
srcFormat, srcRect, isIntensity, scaleByHalf);
|
is_depth_copy, srcRect, isIntensity, scaleByHalf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const constexpr char s_palette_shader_hlsl[] =
|
static const constexpr char s_palette_shader_hlsl[] =
|
||||||
|
|
|
@ -41,8 +41,8 @@ private:
|
||||||
|
|
||||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override;
|
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override;
|
||||||
|
|
||||||
void FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
|
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half,
|
||||||
bool scale_by_half, unsigned int cbuf_id, const float* colmat) override;
|
unsigned int cbuf_id, const float* colmat) override;
|
||||||
|
|
||||||
void Bind(unsigned int stage) override;
|
void Bind(unsigned int stage) override;
|
||||||
bool Save(const std::string& filename, unsigned int level) override;
|
bool Save(const std::string& filename, unsigned int level) override;
|
||||||
|
@ -61,7 +61,7 @@ private:
|
||||||
TlutFormat format) override;
|
TlutFormat format) override;
|
||||||
|
|
||||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void CopyEFB(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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||||
bool is_intensity, bool scale_by_half) override;
|
bool is_intensity, bool scale_by_half) override;
|
||||||
|
|
||||||
bool CompileShaders() override { return true; }
|
bool CompileShaders() override { return true; }
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
// Returns size in bytes of encoded block of memory
|
// Returns size in bytes of encoded block of memory
|
||||||
virtual void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
virtual void Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||||
u32 memory_stride, PEControl::PixelFormat src_format,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||||
const EFBRectangle& src_rect, bool is_intensity, bool scale_by_half) = 0;
|
bool is_intensity, bool scale_by_half) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void CopyEFB(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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||||
bool is_intensity, bool scale_by_half) override
|
bool is_intensity, bool scale_by_half) override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ private:
|
||||||
TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {}
|
TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {}
|
||||||
~TCacheEntry() {}
|
~TCacheEntry() {}
|
||||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {}
|
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {}
|
||||||
void FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
|
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half,
|
||||||
bool scale_by_half, unsigned int cbufid, const float* colmat) override
|
unsigned int cbufid, const float* colmat) override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,14 +204,14 @@ void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u3
|
||||||
TextureCache::SetStage();
|
TextureCache::SetStage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(u8* dstPointer, PEControl::PixelFormat srcFormat,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect,
|
||||||
const EFBRectangle& srcRect, bool scaleByHalf,
|
bool scaleByHalf, unsigned int cbufid,
|
||||||
unsigned int cbufid, const float* colmat)
|
const float* colmat)
|
||||||
{
|
{
|
||||||
g_renderer->ResetAPIState(); // reset any game specific settings
|
g_renderer->ResetAPIState(); // reset any game specific settings
|
||||||
|
|
||||||
// Make sure to resolve anything we need to read from.
|
// Make sure to resolve anything we need to read from.
|
||||||
const GLuint read_texture = (srcFormat == PEControl::Z24) ?
|
const GLuint read_texture = is_depth_copy ?
|
||||||
FramebufferManager::ResolveAndGetDepthTarget(srcRect) :
|
FramebufferManager::ResolveAndGetDepthTarget(srcRect) :
|
||||||
FramebufferManager::ResolveAndGetRenderTarget(srcRect);
|
FramebufferManager::ResolveAndGetRenderTarget(srcRect);
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dstPointer, PEControl::Pixe
|
||||||
glViewport(0, 0, config.width, config.height);
|
glViewport(0, 0, config.width, config.height);
|
||||||
|
|
||||||
GLuint uniform_location;
|
GLuint uniform_location;
|
||||||
if (srcFormat == PEControl::Z24)
|
if (is_depth_copy)
|
||||||
{
|
{
|
||||||
s_DepthMatrixProgram.Bind();
|
s_DepthMatrixProgram.Bind();
|
||||||
if (s_DepthCbufid != cbufid)
|
if (s_DepthCbufid != cbufid)
|
||||||
|
@ -257,11 +257,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dstPointer, PEControl::Pixe
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
TextureConverter::EncodeToRamFromTexture(dst, format, native_width, bytes_per_row, num_blocks_y,
|
TextureConverter::EncodeToRamFromTexture(dst, format, native_width, bytes_per_row, num_blocks_y,
|
||||||
memory_stride, srcFormat, isIntensity, scaleByHalf,
|
memory_stride, is_depth_copy, isIntensity, scaleByHalf,
|
||||||
srcRect);
|
srcRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@ private:
|
||||||
|
|
||||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override;
|
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override;
|
||||||
|
|
||||||
void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||||
bool scaleByHalf, unsigned int cbufid, const float* colmat) override;
|
unsigned int cbufid, const float* colmat) override;
|
||||||
|
|
||||||
void Bind(unsigned int stage) override;
|
void Bind(unsigned int stage) override;
|
||||||
bool Save(const std::string& filename, unsigned int level) override;
|
bool Save(const std::string& filename, unsigned int level) override;
|
||||||
|
@ -53,8 +53,8 @@ private:
|
||||||
TlutFormat format) override;
|
TlutFormat format) override;
|
||||||
|
|
||||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void 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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool isIntensity, bool scaleByHalf) override;
|
bool scaleByHalf) override;
|
||||||
|
|
||||||
bool CompileShaders() override;
|
bool CompileShaders() override;
|
||||||
void DeleteShaders() override;
|
void DeleteShaders() override;
|
||||||
|
|
|
@ -270,7 +270,7 @@ static void EncodeToRamUsingShader(GLuint srcTexture, u8* destAddr, u32 dst_line
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRamFromTexture(u8* dest_ptr, u32 format, u32 native_width, u32 bytes_per_row,
|
void EncodeToRamFromTexture(u8* dest_ptr, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
bool bIsIntensityFmt, int bScaleByHalf, const EFBRectangle& source)
|
bool bIsIntensityFmt, int bScaleByHalf, const EFBRectangle& source)
|
||||||
{
|
{
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
|
@ -281,12 +281,11 @@ void EncodeToRamFromTexture(u8* dest_ptr, u32 format, u32 native_width, u32 byte
|
||||||
glUniform4i(s_encodingUniforms[format], source.left, source.top, native_width,
|
glUniform4i(s_encodingUniforms[format], source.left, source.top, native_width,
|
||||||
bScaleByHalf ? 2 : 1);
|
bScaleByHalf ? 2 : 1);
|
||||||
|
|
||||||
const GLuint read_texture = (srcFormat == PEControl::Z24) ?
|
const GLuint read_texture = is_depth_copy ? FramebufferManager::ResolveAndGetDepthTarget(source) :
|
||||||
FramebufferManager::ResolveAndGetDepthTarget(source) :
|
|
||||||
FramebufferManager::ResolveAndGetRenderTarget(source);
|
FramebufferManager::ResolveAndGetRenderTarget(source);
|
||||||
|
|
||||||
EncodeToRamUsingShader(read_texture, dest_ptr, bytes_per_row, num_blocks_y, memory_stride,
|
EncodeToRamUsingShader(read_texture, dest_ptr, bytes_per_row, num_blocks_y, memory_stride,
|
||||||
bScaleByHalf > 0 && srcFormat != PEControl::Z24);
|
bScaleByHalf > 0 && !is_depth_copy);
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
|
|
|
@ -25,7 +25,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
|
|
||||||
// returns size of the encoded data (in bytes)
|
// returns size of the encoded data (in bytes)
|
||||||
void EncodeToRamFromTexture(u8* dest_ptr, u32 format, u32 native_width, u32 bytes_per_row,
|
void EncodeToRamFromTexture(u8* dest_ptr, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
bool bIsIntensityFmt, int bScaleByHalf, const EFBRectangle& source);
|
bool bIsIntensityFmt, int bScaleByHalf, const EFBRectangle& source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,8 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void 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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool isIntensity, bool scaleByHalf) override
|
bool scaleByHalf) override
|
||||||
{
|
{
|
||||||
EfbCopy::CopyEfb();
|
EfbCopy::CopyEfb();
|
||||||
}
|
}
|
||||||
|
@ -65,8 +65,8 @@ private:
|
||||||
TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {}
|
TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {}
|
||||||
~TCacheEntry() {}
|
~TCacheEntry() {}
|
||||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {}
|
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {}
|
||||||
void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||||
bool scaleByHalf, unsigned int cbufid, const float* colmat) override
|
unsigned int cbufid, const float* colmat) override
|
||||||
{
|
{
|
||||||
EfbCopy::CopyEfb();
|
EfbCopy::CopyEfb();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,13 +88,8 @@ void TextureCache::ConvertTexture(TCacheEntryBase* base_entry, TCacheEntryBase*
|
||||||
m_texture_converter->ConvertTexture(entry, unconverted, m_render_pass, palette, format);
|
m_texture_converter->ConvertTexture(entry, unconverted, m_render_pass, palette, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsDepthCopyFormat(PEControl::PixelFormat format)
|
|
||||||
{
|
|
||||||
return format == PEControl::Z24;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||||
u32 num_blocks_y, u32 memory_stride, PEControl::PixelFormat src_format,
|
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||||
const EFBRectangle& src_rect, bool is_intensity, bool scale_by_half)
|
const EFBRectangle& src_rect, bool is_intensity, bool scale_by_half)
|
||||||
{
|
{
|
||||||
// Flush EFB pokes first, as they're expected to be included.
|
// Flush EFB pokes first, as they're expected to be included.
|
||||||
|
@ -107,7 +102,7 @@ void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_
|
||||||
{static_cast<u32>(scaled_src_rect.GetWidth()),
|
{static_cast<u32>(scaled_src_rect.GetWidth()),
|
||||||
static_cast<u32>(scaled_src_rect.GetHeight())}};
|
static_cast<u32>(scaled_src_rect.GetHeight())}};
|
||||||
Texture2D* src_texture;
|
Texture2D* src_texture;
|
||||||
if (IsDepthCopyFormat(src_format))
|
if (is_depth_copy)
|
||||||
src_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(region);
|
src_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(region);
|
||||||
else
|
else
|
||||||
src_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(region);
|
src_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(region);
|
||||||
|
@ -124,8 +119,8 @@ void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
m_texture_converter->EncodeTextureToMemory(src_texture->GetView(), dst, format, native_width,
|
m_texture_converter->EncodeTextureToMemory(src_texture->GetView(), dst, format, native_width,
|
||||||
bytes_per_row, num_blocks_y, memory_stride, src_format,
|
bytes_per_row, num_blocks_y, memory_stride,
|
||||||
is_intensity, scale_by_half, src_rect);
|
is_depth_copy, is_intensity, scale_by_half, src_rect);
|
||||||
|
|
||||||
// Transition back to original state
|
// Transition back to original state
|
||||||
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout);
|
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout);
|
||||||
|
@ -436,15 +431,14 @@ void TextureCache::TCacheEntry::Load(const u8* buffer, unsigned int width, unsig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat src_format,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool is_depth_copy, const EFBRectangle& src_rect,
|
||||||
const EFBRectangle& src_rect, bool scale_by_half,
|
bool scale_by_half, unsigned int cbufid,
|
||||||
unsigned int cbufid, const float* colmat)
|
const float* colmat)
|
||||||
{
|
{
|
||||||
// A better way of doing this would be nice.
|
// A better way of doing this would be nice.
|
||||||
FramebufferManager* framebuffer_mgr =
|
FramebufferManager* framebuffer_mgr =
|
||||||
static_cast<FramebufferManager*>(g_framebuffer_manager.get());
|
static_cast<FramebufferManager*>(g_framebuffer_manager.get());
|
||||||
TargetRectangle scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect);
|
TargetRectangle scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect);
|
||||||
bool is_depth_copy = IsDepthCopyFormat(src_format);
|
|
||||||
|
|
||||||
// Flush EFB pokes first, as they're expected to be included.
|
// Flush EFB pokes first, as they're expected to be included.
|
||||||
framebuffer_mgr->FlushEFBPokes();
|
framebuffer_mgr->FlushEFBPokes();
|
||||||
|
|
|
@ -29,8 +29,8 @@ public:
|
||||||
VkFramebuffer GetFramebuffer() const { return m_framebuffer; }
|
VkFramebuffer GetFramebuffer() const { return m_framebuffer; }
|
||||||
void Load(const u8* buffer, unsigned int width, unsigned int height,
|
void Load(const u8* buffer, unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level) override;
|
unsigned int expanded_width, unsigned int level) override;
|
||||||
void FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
|
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half,
|
||||||
bool scale_by_half, unsigned int cbufid, const float* colmat) override;
|
unsigned int cbufid, const float* colmat) override;
|
||||||
void CopyRectangleFromTexture(const TCacheEntryBase* source,
|
void CopyRectangleFromTexture(const TCacheEntryBase* source,
|
||||||
const MathUtil::Rectangle<int>& src_rect,
|
const MathUtil::Rectangle<int>& src_rect,
|
||||||
const MathUtil::Rectangle<int>& dst_rect) override;
|
const MathUtil::Rectangle<int>& dst_rect) override;
|
||||||
|
@ -60,7 +60,7 @@ public:
|
||||||
TlutFormat format) override;
|
TlutFormat format) override;
|
||||||
|
|
||||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
void CopyEFB(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,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||||
bool is_intensity, bool scale_by_half) override;
|
bool is_intensity, bool scale_by_half) override;
|
||||||
|
|
||||||
void CopyRectangleFromTexture(TCacheEntry* dst_texture, const MathUtil::Rectangle<int>& dst_rect,
|
void CopyRectangleFromTexture(TCacheEntry* dst_texture, const MathUtil::Rectangle<int>& dst_rect,
|
||||||
|
|
|
@ -207,7 +207,7 @@ void TextureConverter::ConvertTexture(TextureCache::TCacheEntry* dst_entry,
|
||||||
|
|
||||||
void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format,
|
void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format,
|
||||||
u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||||
u32 memory_stride, PEControl::PixelFormat src_format,
|
u32 memory_stride, bool is_depth_copy,
|
||||||
bool is_intensity, int scale_by_half,
|
bool is_intensity, int scale_by_half,
|
||||||
const EFBRectangle& src_rect)
|
const EFBRectangle& src_rect)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +234,7 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p
|
||||||
draw.SetPushConstants(position_uniform, sizeof(position_uniform));
|
draw.SetPushConstants(position_uniform, sizeof(position_uniform));
|
||||||
|
|
||||||
// Doesn't make sense to linear filter depth values
|
// Doesn't make sense to linear filter depth values
|
||||||
draw.SetPSSampler(0, src_texture, (scale_by_half && src_format != PEControl::Z24) ?
|
draw.SetPSSampler(0, src_texture, (scale_by_half && !is_depth_copy) ?
|
||||||
g_object_cache->GetLinearSampler() :
|
g_object_cache->GetLinearSampler() :
|
||||||
g_object_cache->GetPointSampler());
|
g_object_cache->GetPointSampler());
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ public:
|
||||||
// NOTE: Executes the current command buffer.
|
// NOTE: Executes the current command buffer.
|
||||||
void EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format, u32 native_width,
|
void EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format, u32 native_width,
|
||||||
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
|
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
|
||||||
PEControl::PixelFormat src_format, bool is_intensity,
|
bool is_depth_copy, bool is_intensity, int scale_by_half,
|
||||||
int scale_by_half, const EFBRectangle& source);
|
const EFBRectangle& source);
|
||||||
|
|
||||||
// Encodes texture to guest memory in XFB (YUYV) format.
|
// Encodes texture to guest memory in XFB (YUYV) format.
|
||||||
void EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u32 dst_stride, u32 dst_height,
|
void EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u32 dst_stride, u32 dst_height,
|
||||||
|
|
|
@ -227,9 +227,10 @@ static void BPWritten(const BPCmd& bp)
|
||||||
{
|
{
|
||||||
// bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer
|
// bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer
|
||||||
// (Zbuffer uses 24-bit Format)
|
// (Zbuffer uses 24-bit Format)
|
||||||
|
bool is_depth_copy = bpmem.zcontrol.pixel_format == PEControl::Z24;
|
||||||
g_texture_cache->CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride,
|
g_texture_cache->CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride,
|
||||||
bpmem.zcontrol.pixel_format, srcRect,
|
is_depth_copy, srcRect, !!PE_copy.intensity_fmt,
|
||||||
!!PE_copy.intensity_fmt, !!PE_copy.half_scale);
|
!!PE_copy.half_scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -862,9 +862,8 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
|
void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
|
||||||
PEControl::PixelFormat srcFormat,
|
bool is_depth_copy, const EFBRectangle& srcRect,
|
||||||
const EFBRectangle& srcRect, bool isIntensity,
|
bool isIntensity, bool scaleByHalf)
|
||||||
bool scaleByHalf)
|
|
||||||
{
|
{
|
||||||
// Emulation methods:
|
// Emulation methods:
|
||||||
//
|
//
|
||||||
|
@ -936,7 +935,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
|
||||||
unsigned int cbufid = -1;
|
unsigned int cbufid = -1;
|
||||||
bool efbHasAlpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
bool efbHasAlpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
||||||
|
|
||||||
if (srcFormat == PEControl::Z24)
|
if (is_depth_copy)
|
||||||
{
|
{
|
||||||
switch (dstFormat)
|
switch (dstFormat)
|
||||||
{
|
{
|
||||||
|
@ -1240,7 +1239,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
|
||||||
|
|
||||||
if (copy_to_ram)
|
if (copy_to_ram)
|
||||||
{
|
{
|
||||||
CopyEFB(dst, dstFormat, tex_w, bytes_per_row, num_blocks_y, dstStride, srcFormat, srcRect,
|
CopyEFB(dst, dstFormat, tex_w, bytes_per_row, num_blocks_y, dstStride, is_depth_copy, srcRect,
|
||||||
isIntensity, scaleByHalf);
|
isIntensity, scaleByHalf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1321,7 +1320,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
|
||||||
entry->SetEfbCopy(dstStride);
|
entry->SetEfbCopy(dstStride);
|
||||||
entry->is_custom_tex = false;
|
entry->is_custom_tex = false;
|
||||||
|
|
||||||
entry->FromRenderTarget(dst, srcFormat, srcRect, scaleByHalf, cbufid, colmat);
|
entry->FromRenderTarget(is_depth_copy, srcRect, scaleByHalf, cbufid, colmat);
|
||||||
|
|
||||||
u64 hash = entry->CalculateHash();
|
u64 hash = entry->CalculateHash();
|
||||||
entry->SetHashes(hash, hash);
|
entry->SetHashes(hash, hash);
|
||||||
|
|
|
@ -128,8 +128,7 @@ public:
|
||||||
const MathUtil::Rectangle<int>& dstrect) = 0;
|
const MathUtil::Rectangle<int>& dstrect) = 0;
|
||||||
|
|
||||||
virtual void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) = 0;
|
virtual void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) = 0;
|
||||||
virtual void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat,
|
virtual void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||||
const EFBRectangle& srcRect, bool scaleByHalf,
|
|
||||||
unsigned int cbufid, const float* colmat) = 0;
|
unsigned int cbufid, const float* colmat) = 0;
|
||||||
|
|
||||||
bool OverlapsMemoryRange(u32 range_address, u32 range_size) const;
|
bool OverlapsMemoryRange(u32 range_address, u32 range_size) const;
|
||||||
|
@ -154,8 +153,8 @@ public:
|
||||||
virtual TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) = 0;
|
virtual TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) = 0;
|
||||||
|
|
||||||
virtual void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
virtual void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||||
u32 memory_stride, PEControl::PixelFormat srcFormat,
|
u32 memory_stride, bool is_depth_copy, const EFBRectangle& srcRect,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) = 0;
|
bool isIntensity, bool scaleByHalf) = 0;
|
||||||
|
|
||||||
virtual bool CompileShaders() = 0;
|
virtual bool CompileShaders() = 0;
|
||||||
virtual void DeleteShaders() = 0;
|
virtual void DeleteShaders() = 0;
|
||||||
|
@ -164,8 +163,8 @@ public:
|
||||||
void UnbindTextures();
|
void UnbindTextures();
|
||||||
virtual void BindTextures();
|
virtual void BindTextures();
|
||||||
void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
|
void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
|
||||||
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool isIntensity, bool scaleByHalf);
|
bool scaleByHalf);
|
||||||
|
|
||||||
virtual void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette,
|
virtual void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette,
|
||||||
TlutFormat format) = 0;
|
TlutFormat format) = 0;
|
||||||
|
|
Loading…
Reference in New Issue