diff options
| author | N.E.C <beholdnec@gmail.com> | 2017-07-30 12:45:55 -0700 |
|---|---|---|
| committer | N.E.C <beholdnec@gmail.com> | 2017-08-03 18:35:29 -0700 |
| commit | c3a57bbad53567af4546a68f0e9dbcd913bd9a75 (patch) | |
| tree | 4ff1176b00c8df323df8610ff2076545e15c60de /Source/Core/VideoBackends | |
| parent | 9649494f67b86b91c9086f4a9e356fb832c4a9b7 (diff) | |
Video: Clearly separate Texture and EFB Copy formats
Improve bookkeeping around formats. Hopefully make code less confusing.
- Rename TlutFormat -> TLUTFormat to follow conventions.
- Use enum classes to prevent using a Texture format where an EFB Copy format
is expected or vice-versa.
- Use common EFBCopyFormat names regardless of depth and YUV configurations.
Diffstat (limited to 'Source/Core/VideoBackends')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp | 30 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/D3D/PSTextureEncoder.h | 8 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/D3D/TextureCache.cpp | 25 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/D3D/TextureCache.h | 10 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Null/TextureCache.h | 10 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/TextureCache.cpp | 111 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/TextureCache.h | 14 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/TextureConverter.cpp | 20 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/TextureConverter.h | 7 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWmain.cpp | 10 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/TextureEncoder.cpp | 871 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/TextureSampler.cpp | 30 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/TextureCache.cpp | 20 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/TextureCache.h | 14 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/TextureConverter.cpp | 49 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/TextureConverter.h | 19 |
16 files changed, 630 insertions, 618 deletions
diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp index 403e768599..51a7dfda08 100644 --- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp +++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp @@ -87,9 +87,9 @@ void PSTextureEncoder::Shutdown() SAFE_RELEASE(m_out); } -void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_width, +void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, 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) + const EFBRectangle& src_rect, bool scale_by_half) { if (!m_ready) // Make sure we initialized OK return; @@ -100,7 +100,7 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_w // 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 // expecting the blurred edges around multisampled shapes. - ID3D11ShaderResourceView* pEFB = is_depth_copy ? + ID3D11ShaderResourceView* pEFB = params.depth ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); @@ -119,12 +119,12 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_w D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr); - EFBEncodeParams params; - params.SrcLeft = src_rect.left; - params.SrcTop = src_rect.top; - params.DestWidth = native_width; - params.ScaleFactor = scale_by_half ? 2 : 1; - D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, ¶ms, 0, 0); + EFBEncodeParams encode_params; + encode_params.SrcLeft = src_rect.left; + encode_params.SrcTop = src_rect.top; + encode_params.DestWidth = native_width; + encode_params.ScaleFactor = scale_by_half ? 2 : 1; + D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, &encode_params, 0, 0); D3D::stateman->SetPixelConstants(m_encodeParams); // We also linear filtering for both box filtering and downsampling higher resolutions to 1x @@ -137,7 +137,7 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_w D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(pEFB, targetRect.AsRECT(), g_renderer->GetTargetWidth(), - g_renderer->GetTargetHeight(), GetEncodingPixelShader(format), + g_renderer->GetTargetHeight(), GetEncodingPixelShader(params), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); @@ -168,18 +168,18 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_w FramebufferManager::GetEFBDepthTexture()->GetDSV()); } -ID3D11PixelShader* PSTextureEncoder::GetEncodingPixelShader(const EFBCopyFormat& format) +ID3D11PixelShader* PSTextureEncoder::GetEncodingPixelShader(const EFBCopyParams& params) { - auto iter = m_encoding_shaders.find(format); + auto iter = m_encoding_shaders.find(params); if (iter != m_encoding_shaders.end()) return iter->second; D3DBlob* bytecode = nullptr; - const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::D3D); + const char* shader = TextureConversionShader::GenerateEncodingShader(params, APIType::D3D); if (!D3D::CompilePixelShader(shader, &bytecode)) { PanicAlert("Failed to compile texture encoding shader."); - m_encoding_shaders[format] = nullptr; + m_encoding_shaders[params] = nullptr; return nullptr; } @@ -188,7 +188,7 @@ ID3D11PixelShader* PSTextureEncoder::GetEncodingPixelShader(const EFBCopyFormat& D3D::device->CreatePixelShader(bytecode->Data(), bytecode->Size(), nullptr, &newShader); CHECK(SUCCEEDED(hr), "create efb encoder pixel shader"); - m_encoding_shaders.emplace(format, newShader); + m_encoding_shaders.emplace(params, newShader); return newShader; } } diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.h b/Source/Core/VideoBackends/D3D/PSTextureEncoder.h index c000777591..738f1b2d3e 100644 --- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.h +++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.h @@ -32,12 +32,12 @@ public: void Init(); void Shutdown(); - 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, + void Encode(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, bool scale_by_half); private: - ID3D11PixelShader* GetEncodingPixelShader(const EFBCopyFormat& format); + ID3D11PixelShader* GetEncodingPixelShader(const EFBCopyParams& params); bool m_ready; @@ -45,6 +45,6 @@ private: ID3D11RenderTargetView* m_outRTV; ID3D11Texture2D* m_outStage; ID3D11Buffer* m_encodeParams; - std::map<EFBCopyFormat, ID3D11PixelShader*> m_encoding_shaders; + std::map<EFBCopyParams, ID3D11PixelShader*> m_encoding_shaders; }; } diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index a696dba452..87b3a50260 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -38,12 +38,12 @@ std::unique_ptr<AbstractTexture> TextureCache::CreateTexture(const TextureConfig return std::make_unique<DXTexture>(config); } -void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width, +void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, 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) + const EFBRectangle& src_rect, bool scale_by_half) { - g_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride, - is_depth_copy, src_rect, scale_by_half); + g_encoder->Encode(dst, params, native_width, bytes_per_row, num_blocks_y, memory_stride, src_rect, + scale_by_half); } const char palette_shader[] = @@ -126,8 +126,8 @@ void main( } )HLSL"; -void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, void* palette, - TlutFormat format) +void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, + const void* palette, TLUTFormat format) { DXTexture* source_texture = static_cast<DXTexture*>(source->texture.get()); DXTexture* destination_texture = static_cast<DXTexture*>(destination->texture.get()); @@ -144,7 +144,7 @@ void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, D3D::stateman->SetTexture(1, palette_buf_srv); // TODO: Add support for C14X2 format. (Different multiplier, more palette entries.) - float params[4] = {(source->format & 0xf) == GX_TF_I4 ? 15.f : 255.f}; + float params[4] = {source->format == TextureFormat::I4 ? 15.f : 255.f}; D3D::context->UpdateSubresource(palette_uniform, 0, nullptr, ¶ms, 0, 0); D3D::stateman->SetPixelConstants(palette_uniform); @@ -163,8 +163,9 @@ void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, // Create texture copy D3D::drawShadedTexQuad( source_texture->GetRawTexIdentifier()->GetSRV(), &sourcerect, source->GetWidth(), - source->GetHeight(), palette_pixel_shader[format], VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); + source->GetHeight(), palette_pixel_shader[static_cast<int>(format)], + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), + GeometryShaderCache::GetCopyGeometryShader()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); @@ -190,9 +191,9 @@ TextureCache::TextureCache() palette_buf = nullptr; palette_buf_srv = nullptr; palette_uniform = nullptr; - palette_pixel_shader[GX_TL_IA8] = GetConvertShader("IA8"); - palette_pixel_shader[GX_TL_RGB565] = GetConvertShader("RGB565"); - palette_pixel_shader[GX_TL_RGB5A3] = GetConvertShader("RGB5A3"); + palette_pixel_shader[static_cast<int>(TLUTFormat::IA8)] = GetConvertShader("IA8"); + palette_pixel_shader[static_cast<int>(TLUTFormat::RGB565)] = GetConvertShader("RGB565"); + palette_pixel_shader[static_cast<int>(TLUTFormat::RGB5A3)] = GetConvertShader("RGB5A3"); auto lutBd = CD3D11_BUFFER_DESC(sizeof(u16) * 256, D3D11_BIND_SHADER_RESOURCE); HRESULT hr = D3D::device->CreateBuffer(&lutBd, nullptr, &palette_buf); CHECK(SUCCEEDED(hr), "create palette decoder lut buffer"); diff --git a/Source/Core/VideoBackends/D3D/TextureCache.h b/Source/Core/VideoBackends/D3D/TextureCache.h index 87586ca7f3..afb3a1421d 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.h +++ b/Source/Core/VideoBackends/D3D/TextureCache.h @@ -28,12 +28,12 @@ private: return 0; }; - void ConvertTexture(TCacheEntry* destination, TCacheEntry* source, void* palette, - TlutFormat format) override; + void ConvertTexture(TCacheEntry* destination, TCacheEntry* source, const void* palette, + TLUTFormat format) 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; + void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) override; void CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half, unsigned int cbuf_id, const float* colmat) override; diff --git a/Source/Core/VideoBackends/Null/TextureCache.h b/Source/Core/VideoBackends/Null/TextureCache.h index e4d115d49d..2b3283c056 100644 --- a/Source/Core/VideoBackends/Null/TextureCache.h +++ b/Source/Core/VideoBackends/Null/TextureCache.h @@ -20,14 +20,14 @@ public: ~TextureCache() {} bool CompileShaders() override { return true; } void DeleteShaders() override {} - void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, void* palette, - TlutFormat format) override + void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, const void* palette, + TLUTFormat format) 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 + void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) override { } diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp index b4f16266ee..924f3d428c 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.cpp +++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp @@ -9,6 +9,7 @@ #include <memory> #include <vector> +#include "Common/Assert.h" #include "Common/GL/GLInterfaceBase.h" #include "Common/MsgHandler.h" #include "Common/StringUtil.h" @@ -32,12 +33,18 @@ namespace OGL { static u32 s_ColorCbufid; static u32 s_DepthCbufid; -static SHADER s_palette_pixel_shader[3]; + +struct PaletteShader +{ + SHADER shader; + GLuint buffer_offset_uniform; + GLuint multiplier_uniform; + GLuint copy_position_uniform; +}; + +static PaletteShader s_palette_shader[3]; static std::unique_ptr<StreamBuffer> s_palette_stream_buffer; -static GLuint s_palette_resolv_texture; -static GLuint s_palette_buffer_offset_uniform[3]; -static GLuint s_palette_multiplier_uniform[3]; -static GLuint s_palette_copy_position_uniform[3]; +static GLuint s_palette_resolv_texture = 0; struct TextureDecodingProgramInfo { @@ -64,12 +71,12 @@ std::unique_ptr<AbstractTexture> TextureCache::CreateTexture(const TextureConfig return std::make_unique<OGLTexture>(config); } -void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width, +void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, 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) + const EFBRectangle& src_rect, bool scale_by_half) { - TextureConverter::EncodeToRamFromTexture(dst, format, native_width, bytes_per_row, num_blocks_y, - memory_stride, is_depth_copy, src_rect, scale_by_half); + TextureConverter::EncodeToRamFromTexture(dst, params, native_width, bytes_per_row, num_blocks_y, + memory_stride, src_rect, scale_by_half); } TextureCache::TextureCache() @@ -126,6 +133,23 @@ GLuint TextureCache::GetColorCopyPositionUniform() const return m_colorCopyPositionUniform; } +static bool CompilePaletteShader(TLUTFormat tlutfmt, const std::string& vcode, + const std::string& pcode, const std::string& gcode) +{ + _assert_(IsValidTLUTFormat(tlutfmt)); + PaletteShader& shader = s_palette_shader[static_cast<int>(tlutfmt)]; + + if (!ProgramShaderCache::CompileShader(shader.shader, vcode, pcode, gcode)) + return false; + + shader.buffer_offset_uniform = + glGetUniformLocation(shader.shader.glprogid, "texture_buffer_offset"); + shader.multiplier_uniform = glGetUniformLocation(shader.shader.glprogid, "multiplier"); + shader.copy_position_uniform = glGetUniformLocation(shader.shader.glprogid, "copy_position"); + + return true; +} + bool TextureCache::CompileShaders() { constexpr const char* color_copy_program = "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n" @@ -315,44 +339,17 @@ bool TextureCache::CompileShaders() if (g_ActiveConfig.backend_info.bSupportsPaletteConversion) { - if (!ProgramShaderCache::CompileShader( - s_palette_pixel_shader[GX_TL_IA8], StringFromFormat(vertex_program, prefix, prefix), - "#define DECODE DecodePixel_IA8" + palette_shader, geo_program)) - { + if (!CompilePaletteShader(TLUTFormat::IA8, StringFromFormat(vertex_program, prefix, prefix), + "#define DECODE DecodePixel_IA8" + palette_shader, geo_program)) return false; - } - s_palette_buffer_offset_uniform[GX_TL_IA8] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_IA8].glprogid, "texture_buffer_offset"); - s_palette_multiplier_uniform[GX_TL_IA8] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_IA8].glprogid, "multiplier"); - s_palette_copy_position_uniform[GX_TL_IA8] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_IA8].glprogid, "copy_position"); - - if (!ProgramShaderCache::CompileShader( - s_palette_pixel_shader[GX_TL_RGB565], StringFromFormat(vertex_program, prefix, prefix), - "#define DECODE DecodePixel_RGB565" + palette_shader, geo_program)) - { + + if (!CompilePaletteShader(TLUTFormat::RGB565, StringFromFormat(vertex_program, prefix, prefix), + "#define DECODE DecodePixel_RGB565" + palette_shader, geo_program)) return false; - } - s_palette_buffer_offset_uniform[GX_TL_RGB565] = glGetUniformLocation( - s_palette_pixel_shader[GX_TL_RGB565].glprogid, "texture_buffer_offset"); - s_palette_multiplier_uniform[GX_TL_RGB565] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_RGB565].glprogid, "multiplier"); - s_palette_copy_position_uniform[GX_TL_RGB565] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_RGB565].glprogid, "copy_position"); - - if (!ProgramShaderCache::CompileShader( - s_palette_pixel_shader[GX_TL_RGB5A3], StringFromFormat(vertex_program, prefix, prefix), - "#define DECODE DecodePixel_RGB5A3" + palette_shader, geo_program)) - { + + if (!CompilePaletteShader(TLUTFormat::RGB5A3, StringFromFormat(vertex_program, prefix, prefix), + "#define DECODE DecodePixel_RGB5A3" + palette_shader, geo_program)) return false; - } - s_palette_buffer_offset_uniform[GX_TL_RGB5A3] = glGetUniformLocation( - s_palette_pixel_shader[GX_TL_RGB5A3].glprogid, "texture_buffer_offset"); - s_palette_multiplier_uniform[GX_TL_RGB5A3] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_RGB5A3].glprogid, "multiplier"); - s_palette_copy_position_uniform[GX_TL_RGB5A3] = - glGetUniformLocation(s_palette_pixel_shader[GX_TL_RGB5A3].glprogid, "copy_position"); } return true; @@ -364,16 +361,19 @@ void TextureCache::DeleteShaders() m_depthMatrixProgram.Destroy(); if (g_ActiveConfig.backend_info.bSupportsPaletteConversion) - for (auto& shader : s_palette_pixel_shader) - shader.Destroy(); + for (auto& shader : s_palette_shader) + shader.shader.Destroy(); } -void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, void* palette, - TlutFormat format) +void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, + const void* palette, TLUTFormat tlutfmt) { if (!g_ActiveConfig.backend_info.bSupportsPaletteConversion) return; + _assert_(IsValidTLUTFormat(tlutfmt)); + const PaletteShader& palette_shader = s_palette_shader[static_cast<int>(tlutfmt)]; + g_renderer->ResetAPIState(); OGLTexture* source_texture = static_cast<OGLTexture*>(source->texture.get()); @@ -385,16 +385,17 @@ void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, FramebufferManager::SetFramebuffer(destination_texture->GetFramebuffer()); glViewport(0, 0, destination->GetWidth(), destination->GetHeight()); - s_palette_pixel_shader[format].Bind(); + palette_shader.shader.Bind(); // C14 textures are currently unsupported - int size = (source->format & 0xf) == GX_TF_I4 ? 32 : 512; + int size = source->format == TextureFormat::I4 ? 32 : 512; auto buffer = s_palette_stream_buffer->Map(size); memcpy(buffer.first, palette, size); s_palette_stream_buffer->Unmap(size); - glUniform1i(s_palette_buffer_offset_uniform[format], buffer.second / 2); - glUniform1f(s_palette_multiplier_uniform[format], (source->format & 0xf) == 0 ? 15.0f : 255.0f); - glUniform4f(s_palette_copy_position_uniform[format], 0.0f, 0.0f, + glUniform1i(palette_shader.buffer_offset_uniform, buffer.second / 2); + glUniform1f(palette_shader.multiplier_uniform, + source->format == TextureFormat::I4 ? 15.0f : 255.0f); + glUniform4f(palette_shader.copy_position_uniform, 0.0f, 0.0f, static_cast<float>(source->GetWidth()), static_cast<float>(source->GetHeight())); glActiveTexture(GL_TEXTURE10); @@ -441,7 +442,7 @@ void DestroyTextureDecodingResources() s_texture_decoding_program_info.clear(); } -bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TlutFormat palette_format) +bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format) { auto key = std::make_pair(static_cast<u32>(format), static_cast<u32>(palette_format)); auto iter = s_texture_decoding_program_info.find(key); @@ -483,7 +484,7 @@ bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TlutFormat pal void TextureCache::DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, u32 row_stride, - const u8* palette, TlutFormat palette_format) + const u8* palette, TLUTFormat palette_format) { auto key = std::make_pair(static_cast<u32>(format), static_cast<u32>(palette_format)); auto iter = s_texture_decoding_program_info.find(key); diff --git a/Source/Core/VideoBackends/OGL/TextureCache.h b/Source/Core/VideoBackends/OGL/TextureCache.h index 93805de0d1..1cf4084007 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.h +++ b/Source/Core/VideoBackends/OGL/TextureCache.h @@ -26,23 +26,23 @@ public: static TextureCache* GetInstance(); - bool SupportsGPUTextureDecode(TextureFormat format, TlutFormat palette_format) override; + bool SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format) override; void DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, u32 row_stride, const u8* palette, - TlutFormat palette_format) override; + TLUTFormat palette_format) override; const SHADER& GetColorCopyProgram() const; GLuint GetColorCopyPositionUniform() const; private: std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override; - void ConvertTexture(TCacheEntry* destination, TCacheEntry* source, void* palette, - TlutFormat format) override; + void ConvertTexture(TCacheEntry* destination, TCacheEntry* source, const void* palette, + TLUTFormat format) 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; + void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) override; void CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half, unsigned int cbuf_id, const float* colmat) override; diff --git a/Source/Core/VideoBackends/OGL/TextureConverter.cpp b/Source/Core/VideoBackends/OGL/TextureConverter.cpp index d352ea6701..e9a3eaa94f 100644 --- a/Source/Core/VideoBackends/OGL/TextureConverter.cpp +++ b/Source/Core/VideoBackends/OGL/TextureConverter.cpp @@ -51,7 +51,7 @@ struct EncodingProgram SHADER program; GLint copy_position_uniform; }; -static std::map<EFBCopyFormat, EncodingProgram> s_encoding_programs; +static std::map<EFBCopyParams, EncodingProgram> s_encoding_programs; static GLuint s_PBO = 0; // for readback with different strides @@ -136,13 +136,13 @@ static void CreatePrograms() ProgramShaderCache::CompileShader(s_yuyvToRgbProgram, VProgramYuyvToRgb, FProgramYuyvToRgb); } -static EncodingProgram& GetOrCreateEncodingShader(const EFBCopyFormat& format) +static EncodingProgram& GetOrCreateEncodingShader(const EFBCopyParams& params) { - auto iter = s_encoding_programs.find(format); + auto iter = s_encoding_programs.find(params); if (iter != s_encoding_programs.end()) return iter->second; - const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::OpenGL); + const char* shader = TextureConversionShader::GenerateEncodingShader(params, APIType::OpenGL); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) @@ -166,7 +166,7 @@ static EncodingProgram& GetOrCreateEncodingShader(const EFBCopyFormat& format) PanicAlert("Failed to compile texture encoding shader."); program.copy_position_uniform = glGetUniformLocation(program.program.glprogid, "position"); - return s_encoding_programs.emplace(format, program).first->second; + return s_encoding_programs.emplace(params, program).first->second; } void Init() @@ -271,24 +271,24 @@ static void EncodeToRamUsingShader(GLuint srcTexture, u8* destAddr, u32 dst_line glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } -void EncodeToRamFromTexture(u8* dest_ptr, const EFBCopyFormat& format, u32 native_width, +void EncodeToRamFromTexture(u8* dest_ptr, const EFBCopyParams& params, 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) + const EFBRectangle& src_rect, bool scale_by_half) { g_renderer->ResetAPIState(); - EncodingProgram& texconv_shader = GetOrCreateEncodingShader(format); + EncodingProgram& texconv_shader = GetOrCreateEncodingShader(params); texconv_shader.program.Bind(); glUniform4i(texconv_shader.copy_position_uniform, src_rect.left, src_rect.top, native_width, scale_by_half ? 2 : 1); - const GLuint read_texture = is_depth_copy ? + const GLuint read_texture = params.depth ? FramebufferManager::ResolveAndGetDepthTarget(src_rect) : FramebufferManager::ResolveAndGetRenderTarget(src_rect); EncodeToRamUsingShader(read_texture, dest_ptr, bytes_per_row, num_blocks_y, memory_stride, - scale_by_half && !is_depth_copy); + scale_by_half && !params.depth); FramebufferManager::SetFramebuffer(0); g_renderer->RestoreAPIState(); diff --git a/Source/Core/VideoBackends/OGL/TextureConverter.h b/Source/Core/VideoBackends/OGL/TextureConverter.h index 11576f9aa1..3b535752a3 100644 --- a/Source/Core/VideoBackends/OGL/TextureConverter.h +++ b/Source/Core/VideoBackends/OGL/TextureConverter.h @@ -7,9 +7,10 @@ #include "Common/CommonTypes.h" #include "Common/GL/GLUtil.h" -#include "VideoCommon/TextureDecoder.h" #include "VideoCommon/VideoCommon.h" +struct EFBCopyParams; + namespace OGL { // Converts textures between formats using shaders @@ -25,9 +26,9 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* des void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture); // returns size of the encoded data (in bytes) -void EncodeToRamFromTexture(u8* dest_ptr, const EFBCopyFormat& format, u32 native_width, +void EncodeToRamFromTexture(u8* dest_ptr, const EFBCopyParams& params, 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); + const EFBRectangle& src_rect, bool scale_by_half); } } // namespace OGL diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 910de9697d..d1f9ac3bb0 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -50,13 +50,13 @@ class TextureCache : public TextureCacheBase public: bool CompileShaders() override { return true; } void DeleteShaders() override {} - void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, void* palette, - TlutFormat format) override + void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, const void* palette, + TLUTFormat format) 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 + void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) override { EfbCopy::CopyEfb(); } diff --git a/Source/Core/VideoBackends/Software/TextureEncoder.cpp b/Source/Core/VideoBackends/Software/TextureEncoder.cpp index 92dffe1b4b..6181d56dd4 100644 --- a/Source/Core/VideoBackends/Software/TextureEncoder.cpp +++ b/Source/Core/VideoBackends/Software/TextureEncoder.cpp @@ -263,7 +263,7 @@ static void SetSpans(int sBlkSize, int tBlkSize, s32* tSpan, s32* sBlkSpan, s32* dstBlockStart += writeStride; \ } -static void EncodeRGBA6(u8* dst, const u8* src, u32 format) +static void EncodeRGBA6(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) { u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; s32 tSpan, sBlkSpan, tBlkSpan, writeStride; @@ -273,62 +273,121 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) switch (format) { - case GX_TF_I4: + case EFBCopyFormat::R4: SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); sBlkSize /= 2; - ENCODE_LOOP_BLOCKS + if (yuv) { - RGBA_to_RGB8(src, &r, &g, &b); - src += readStride; - *dst = RGB8_to_I(r, g, b) & 0xf0; + ENCODE_LOOP_BLOCKS + { + RGBA_to_RGB8(src, &r, &g, &b); + src += readStride; + *dst = RGB8_to_I(r, g, b) & 0xf0; - RGBA_to_RGB8(src, &r, &g, &b); - src += readStride; - *dst |= RGB8_to_I(r, g, b) >> 4; - dst++; + RGBA_to_RGB8(src, &r, &g, &b); + src += readStride; + *dst |= RGB8_to_I(r, g, b) >> 4; + dst++; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + u32 srcColor = *(u32*)src; + src += readStride; + *dst = (srcColor >> 16) & 0xf0; + + srcColor = *(u32*)src; + src += readStride; + *dst |= (srcColor >> 20) & 0x0f; + dst++; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_I8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - RGBA_to_RGB8(src, &r, &g, &b); - src += readStride; - *dst++ = RGB8_to_I(r, g, b); + ENCODE_LOOP_BLOCKS + { + RGBA_to_RGB8(src, &r, &g, &b); + src += readStride; + *dst++ = RGB8_to_I(r, g, b); + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + u32 srcColor = *(u32*)src; + *dst++ = Convert6To8((srcColor >> 18) & 0x3f); + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA4: + case EFBCopyFormat::RA4: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - RGBA_to_RGBA8(src, &r, &g, &b, &a); - src += readStride; - *dst++ = (a & 0xf0) | (RGB8_to_I(r, g, b) >> 4); + ENCODE_LOOP_BLOCKS + { + RGBA_to_RGBA8(src, &r, &g, &b, &a); + src += readStride; + *dst++ = (a & 0xf0) | (RGB8_to_I(r, g, b) >> 4); + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + u32 srcColor = *(u32*)src; + src += readStride; + *dst++ = ((srcColor << 2) & 0xf0) | ((srcColor >> 20) & 0x0f); + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA8: + case EFBCopyFormat::RA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - RGBA_to_RGBA8(src, &r, &g, &b, &a); - src += readStride; - *dst++ = a; - *dst++ = RGB8_to_I(r, g, b); + ENCODE_LOOP_BLOCKS + { + RGBA_to_RGBA8(src, &r, &g, &b, &a); + src += readStride; + *dst++ = a; + *dst++ = RGB8_to_I(r, g, b); + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + u32 srcColor = *(u32*)src; + src += readStride; + *dst++ = Convert6To8(srcColor & 0x3f); + *dst++ = Convert6To8((srcColor >> 18) & 0x3f); + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_RGB565: + case EFBCopyFormat::RGB565: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -344,7 +403,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGB5A3: + case EFBCopyFormat::RGB5A3: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -367,7 +426,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGBA8: + case EFBCopyFormat::RGBA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -379,50 +438,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS2 break; - case GX_CTF_R4: - SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - sBlkSize /= 2; - ENCODE_LOOP_BLOCKS - { - u32 srcColor = *(u32*)src; - src += readStride; - *dst = (srcColor >> 16) & 0xf0; - - srcColor = *(u32*)src; - src += readStride; - *dst |= (srcColor >> 20) & 0x0f; - dst++; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA4: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - u32 srcColor = *(u32*)src; - src += readStride; - *dst++ = ((srcColor << 2) & 0xf0) | ((srcColor >> 20) & 0x0f); - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA8: - SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - u32 srcColor = *(u32*)src; - src += readStride; - *dst++ = Convert6To8(srcColor & 0x3f); - *dst++ = Convert6To8((srcColor >> 18) & 0x3f); - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_A8: + case EFBCopyFormat::A8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -434,19 +450,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_R8: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - u32 srcColor = *(u32*)src; - *dst++ = Convert6To8((srcColor >> 18) & 0x3f); - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_G8: + case EFBCopyFormat::G8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -458,7 +462,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_B8: + case EFBCopyFormat::B8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -470,7 +474,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_RG8: + case EFBCopyFormat::RG8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -483,7 +487,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_GB8: + case EFBCopyFormat::GB8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -497,12 +501,12 @@ static void EncodeRGBA6(u8* dst, const u8* src, u32 format) break; default: - PanicAlert("Unknown texture copy format: 0x%x\n", format); + PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); break; } } -static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) +static void EncodeRGBA6halfscale(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) { u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; s32 tSpan, sBlkSpan, tBlkSpan, writeStride; @@ -512,62 +516,121 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) switch (format) { - case GX_TF_I4: + case EFBCopyFormat::R4: SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); sBlkSize /= 2; - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGBA_to_RGB8(src, &r, &g, &b); - src += readStride; - *dst = RGB8_to_I(r, g, b) & 0xf0; + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_RGB8(src, &r, &g, &b); + src += readStride; + *dst = RGB8_to_I(r, g, b) & 0xf0; - BoxfilterRGBA_to_RGB8(src, &r, &g, &b); - src += readStride; - *dst |= RGB8_to_I(r, g, b) >> 4; - dst++; + BoxfilterRGBA_to_RGB8(src, &r, &g, &b); + src += readStride; + *dst |= RGB8_to_I(r, g, b) >> 4; + dst++; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_x8(src, &r, 18); + src += readStride; + *dst = r & 0xf0; + + BoxfilterRGBA_to_x8(src, &r, 18); + src += readStride; + *dst |= r >> 4; + dst++; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_I8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGBA_to_RGB8(src, &r, &g, &b); - src += readStride; - *dst++ = RGB8_to_I(r, g, b); + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_RGB8(src, &r, &g, &b); + src += readStride; + *dst++ = RGB8_to_I(r, g, b); + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_x8(src, &r, 18); + *dst++ = r; + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA4: + case EFBCopyFormat::RA4: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); - src += readStride; - *dst++ = (a & 0xf0) | (RGB8_to_I(r, g, b) >> 4); + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); + src += readStride; + *dst++ = (a & 0xf0) | (RGB8_to_I(r, g, b) >> 4); + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_xx8(src, &r, &a, 18, 0); + src += readStride; + *dst++ = (a & 0xf0) | (r >> 4); + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA8: + case EFBCopyFormat::RA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); - src += readStride; - *dst++ = a; - *dst++ = RGB8_to_I(r, g, b); + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_RGBA8(src, &r, &g, &b, &a); + src += readStride; + *dst++ = a; + *dst++ = RGB8_to_I(r, g, b); + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGBA_to_xx8(src, &r, &a, 18, 0); + src += readStride; + *dst++ = a; + *dst++ = r; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_RGB565: + case EFBCopyFormat::RGB565: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -582,7 +645,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGB5A3: + case EFBCopyFormat::RGB5A3: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -602,7 +665,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGBA8: + case EFBCopyFormat::RGBA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -614,50 +677,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS2 break; - case GX_CTF_R4: - SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - sBlkSize /= 2; - ENCODE_LOOP_BLOCKS - { - BoxfilterRGBA_to_x8(src, &r, 18); - src += readStride; - *dst = r & 0xf0; - - BoxfilterRGBA_to_x8(src, &r, 18); - src += readStride; - *dst |= r >> 4; - dst++; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA4: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGBA_to_xx8(src, &r, &a, 18, 0); - src += readStride; - *dst++ = (a & 0xf0) | (r >> 4); - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA8: - SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGBA_to_xx8(src, &r, &a, 18, 0); - src += readStride; - *dst++ = a; - *dst++ = r; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_A8: + case EFBCopyFormat::A8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -669,19 +689,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_R8: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGBA_to_x8(src, &r, 18); - *dst++ = r; - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_G8: + case EFBCopyFormat::G8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -693,7 +701,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_B8: + case EFBCopyFormat::B8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -705,7 +713,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_RG8: + case EFBCopyFormat::RG8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -718,7 +726,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_GB8: + case EFBCopyFormat::GB8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -732,12 +740,12 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, u32 format) break; default: - PanicAlert("Unknown texture copy format: 0x%x\n", format); + PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); break; } } -static void EncodeRGB8(u8* dst, const u8* src, u32 format) +static void EncodeRGB8(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) { u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; s32 tSpan, sBlkSpan, tBlkSpan, writeStride; @@ -746,58 +754,113 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) switch (format) { - case GX_TF_I4: + case EFBCopyFormat::R4: SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); sBlkSize /= 2; - ENCODE_LOOP_BLOCKS + if (yuv) { - *dst = RGB8_to_I(src[2], src[1], src[0]) & 0xf0; - src += readStride; + ENCODE_LOOP_BLOCKS + { + *dst = RGB8_to_I(src[2], src[1], src[0]) & 0xf0; + src += readStride; - *dst |= RGB8_to_I(src[2], src[1], src[0]) >> 4; - src += readStride; - dst++; + *dst |= RGB8_to_I(src[2], src[1], src[0]) >> 4; + src += readStride; + dst++; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + *dst = src[2] & 0xf0; + src += readStride; + + *dst |= src[2] >> 4; + src += readStride; + + dst++; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_I8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - *dst++ = RGB8_to_I(src[2], src[1], src[0]); - src += readStride; + ENCODE_LOOP_BLOCKS + { + *dst++ = RGB8_to_I(src[2], src[1], src[0]); + src += readStride; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + *dst++ = src[2]; + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA4: + case EFBCopyFormat::RA4: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - *dst++ = 0xf0 | (RGB8_to_I(src[2], src[1], src[0]) >> 4); - src += readStride; + ENCODE_LOOP_BLOCKS + { + *dst++ = 0xf0 | (RGB8_to_I(src[2], src[1], src[0]) >> 4); + src += readStride; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + *dst++ = 0xf0 | (src[2] >> 4); + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA8: + case EFBCopyFormat::RA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - *dst++ = 0xff; - *dst++ = RGB8_to_I(src[2], src[1], src[0]); + ENCODE_LOOP_BLOCKS + { + *dst++ = 0xff; + *dst++ = RGB8_to_I(src[2], src[1], src[0]); - src += readStride; + src += readStride; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + *dst++ = 0xff; + *dst++ = src[2]; + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_RGB565: + case EFBCopyFormat::RGB565: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -810,7 +873,7 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGB5A3: + case EFBCopyFormat::RGB5A3: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -824,7 +887,7 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGBA8: + case EFBCopyFormat::RGBA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -839,65 +902,14 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS2 break; - case GX_CTF_R4: - SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - sBlkSize /= 2; - ENCODE_LOOP_BLOCKS - { - *dst = src[2] & 0xf0; - src += readStride; - - *dst |= src[2] >> 4; - src += readStride; - - dst++; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA4: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - *dst++ = 0xf0 | (src[2] >> 4); - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA8: - SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - *dst++ = 0xff; - *dst++ = src[2]; - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_A8: + case EFBCopyFormat::A8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS { *dst++ = 0xff; } ENCODE_LOOP_SPANS break; - case GX_CTF_R8: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - *dst++ = src[2]; - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_G8: + case EFBCopyFormat::G8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -908,7 +920,7 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_B8: + case EFBCopyFormat::B8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -919,11 +931,12 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_RG8: + case EFBCopyFormat::RG8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS { + // FIXME: is this backwards? *dst++ = src[1]; *dst++ = src[2]; src += readStride; @@ -931,7 +944,7 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_GB8: + case EFBCopyFormat::GB8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -944,12 +957,12 @@ static void EncodeRGB8(u8* dst, const u8* src, u32 format) break; default: - PanicAlert("Unknown texture copy format: 0x%x\n", format); + PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); break; } } -static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) +static void EncodeRGB8halfscale(u8* dst, const u8* src, EFBCopyFormat format, bool yuv) { u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; s32 tSpan, sBlkSpan, tBlkSpan, writeStride; @@ -959,62 +972,122 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) switch (format) { - case GX_TF_I4: + case EFBCopyFormat::R4: SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); sBlkSize /= 2; - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGB_to_RGB8(src, &r, &g, &b); - *dst = RGB8_to_I(r, g, b) & 0xf0; - src += readStride; + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_RGB8(src, &r, &g, &b); + *dst = RGB8_to_I(r, g, b) & 0xf0; + src += readStride; - BoxfilterRGB_to_RGB8(src, &r, &g, &b); - *dst |= RGB8_to_I(r, g, b) >> 4; - src += readStride; - dst++; + BoxfilterRGB_to_RGB8(src, &r, &g, &b); + *dst |= RGB8_to_I(r, g, b) >> 4; + src += readStride; + dst++; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_x8(src, &r, 2); + *dst = r & 0xf0; + src += readStride; + + BoxfilterRGB_to_x8(src, &r, 2); + *dst |= r >> 4; + src += readStride; + + dst++; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_I8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGB_to_RGB8(src, &r, &g, &b); - *dst++ = RGB8_to_I(r, g, b); - src += readStride; + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_RGB8(src, &r, &g, &b); + *dst++ = RGB8_to_I(r, g, b); + src += readStride; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_x8(src, &r, 2); + *dst++ = r; + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA4: + case EFBCopyFormat::RA4: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGB_to_RGB8(src, &r, &g, &b); - *dst++ = 0xf0 | (RGB8_to_I(r, g, b) >> 4); - src += readStride; + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_RGB8(src, &r, &g, &b); + *dst++ = 0xf0 | (RGB8_to_I(r, g, b) >> 4); + src += readStride; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_x8(src, &r, 2); + *dst++ = 0xf0 | (r >> 4); + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_IA8: + case EFBCopyFormat::RA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS + if (yuv) { - BoxfilterRGB_to_RGB8(src, &r, &g, &b); - *dst++ = 0xff; - *dst++ = RGB8_to_I(r, g, b); - src += readStride; + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_RGB8(src, &r, &g, &b); + *dst++ = 0xff; + *dst++ = RGB8_to_I(r, g, b); + src += readStride; + } + ENCODE_LOOP_SPANS + } + else + { + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_x8(src, &r, 2); + *dst++ = 0xff; + *dst++ = r; + src += readStride; + } + ENCODE_LOOP_SPANS } - ENCODE_LOOP_SPANS break; - case GX_TF_RGB565: + case EFBCopyFormat::RGB565: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1028,7 +1101,7 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGB5A3: + case EFBCopyFormat::RGB5A3: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1042,7 +1115,7 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_RGBA8: + case EFBCopyFormat::RGBA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1058,70 +1131,14 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS2 break; - case GX_CTF_R4: - SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - sBlkSize /= 2; - ENCODE_LOOP_BLOCKS - { - BoxfilterRGB_to_x8(src, &r, 2); - *dst = r & 0xf0; - src += readStride; - - BoxfilterRGB_to_x8(src, &r, 2); - *dst |= r >> 4; - src += readStride; - - dst++; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA4: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGB_to_x8(src, &r, 2); - *dst++ = 0xf0 | (r >> 4); - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_RA8: - SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGB_to_x8(src, &r, 2); - *dst++ = 0xff; - *dst++ = r; - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_A8: + case EFBCopyFormat::A8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS { *dst++ = 0xff; } ENCODE_LOOP_SPANS break; - case GX_CTF_R8: - SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGB_to_x8(src, &r, 2); - *dst++ = r; - src += readStride; - } - ENCODE_LOOP_SPANS - break; - - case GX_CTF_G8: + case EFBCopyFormat::G8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1133,7 +1150,7 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_B8: + case EFBCopyFormat::B8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1145,7 +1162,7 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_RG8: + case EFBCopyFormat::RG8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1158,7 +1175,7 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_GB8: + case EFBCopyFormat::GB8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1172,12 +1189,12 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, u32 format) break; default: - PanicAlert("Unknown texture copy format: 0x%x\n", format); + PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); break; } } -static void EncodeZ24(u8* dst, const u8* src, u32 format) +static void EncodeZ24(u8* dst, const u8* src, EFBCopyFormat format) { u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; s32 tSpan, sBlkSpan, tBlkSpan, writeStride; @@ -1186,7 +1203,8 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) switch (format) { - case GX_TF_Z8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1197,19 +1215,9 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_Z16: - SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - *dst++ = src[1]; - *dst++ = src[2]; - src += readStride; - } - ENCODE_LOOP_SPANS - break; + // FIXME: handle RA8? - case GX_TF_Z24X8: + case EFBCopyFormat::RGBA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1224,7 +1232,7 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS2 break; - case GX_CTF_Z4: + case EFBCopyFormat::R4: SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); sBlkSize /= 2; @@ -1241,7 +1249,7 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_Z8M: + case EFBCopyFormat::G8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1252,7 +1260,7 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_Z8L: + case EFBCopyFormat::B8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1263,7 +1271,20 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_Z16L: + case EFBCopyFormat::RG8: + SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); + SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); + ENCODE_LOOP_BLOCKS + { + // FIXME: should these be reversed? + *dst++ = src[1]; + *dst++ = src[2]; + src += readStride; + } + ENCODE_LOOP_SPANS + break; + + case EFBCopyFormat::GB8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1276,12 +1297,12 @@ static void EncodeZ24(u8* dst, const u8* src, u32 format) break; default: - PanicAlert("Unknown texture copy format: 0x%x\n", format); + PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); break; } } -static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) +static void EncodeZ24halfscale(u8* dst, const u8* src, EFBCopyFormat format) { u16 sBlkCount, tBlkCount, sBlkSize, tBlkSize; s32 tSpan, sBlkSpan, tBlkSpan, writeStride; @@ -1291,7 +1312,8 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) switch (format) { - case GX_TF_Z8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1303,20 +1325,9 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_TF_Z16: - SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); - SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); - ENCODE_LOOP_BLOCKS - { - BoxfilterRGB_to_xx8(src, &g, &b, 1, 2); - *dst++ = b; - *dst++ = g; - src += readStride; - } - ENCODE_LOOP_SPANS - break; + // FIXME: handle RA8? - case GX_TF_Z24X8: + case EFBCopyFormat::RGBA8: SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1329,7 +1340,7 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS2 break; - case GX_CTF_Z4: + case EFBCopyFormat::R4: // Z4 SetBlockDimensions(3, 3, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); sBlkSize /= 2; @@ -1348,7 +1359,7 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_Z8M: + case EFBCopyFormat::G8: // Z8M SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1360,7 +1371,7 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_Z8L: + case EFBCopyFormat::B8: // Z8L SetBlockDimensions(3, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1372,7 +1383,7 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; - case GX_CTF_Z16L: + case EFBCopyFormat::RG8: // RG8 SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); ENCODE_LOOP_BLOCKS @@ -1385,8 +1396,22 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, u32 format) ENCODE_LOOP_SPANS break; + case EFBCopyFormat::GB8: + SetBlockDimensions(2, 2, &sBlkCount, &tBlkCount, &sBlkSize, &tBlkSize); + SetSpans(sBlkSize, tBlkSize, &tSpan, &sBlkSpan, &tBlkSpan, &writeStride); + ENCODE_LOOP_BLOCKS + { + BoxfilterRGB_to_xx8(src, &g, &b, 1, 2); + // FIXME: is this backwards? + *dst++ = b; + *dst++ = g; + src += readStride; + } + ENCODE_LOOP_SPANS + break; + default: - PanicAlert("Unknown texture copy format: 0x%x\n", format); + PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<int>(format)); break; } } @@ -1396,21 +1421,7 @@ void Encode(u8* dest_ptr) auto pixelformat = bpmem.zcontrol.pixel_format; bool bFromZBuffer = pixelformat == PEControl::Z24; bool bIsIntensityFmt = bpmem.triggerEFBCopy.intensity_fmt > 0; - u32 copyfmt = ((bpmem.triggerEFBCopy.target_pixel_format / 2) + - ((bpmem.triggerEFBCopy.target_pixel_format & 1) * 8)); - - // pack copy format information into a single variable - u32 format = copyfmt; - if (bFromZBuffer) - { - format |= _GX_TF_ZTF; - if (copyfmt == 11) - format = GX_TF_Z16; - else if (format < GX_TF_Z8 || format > GX_TF_Z24X8) - format |= _GX_TF_CTF; - } - else if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt)) - format |= _GX_TF_CTF; + EFBCopyFormat copyfmt = bpmem.triggerEFBCopy.tp_realFormat(); const u8* src = EfbInterface::GetPixelPointer(bpmem.copyTexSrcXY.x, bpmem.copyTexSrcXY.y, bFromZBuffer); @@ -1418,24 +1429,24 @@ void Encode(u8* dest_ptr) if (bpmem.triggerEFBCopy.half_scale) { if (pixelformat == PEControl::RGBA6_Z24) - EncodeRGBA6halfscale(dest_ptr, src, format); + EncodeRGBA6halfscale(dest_ptr, src, copyfmt, bIsIntensityFmt); else if (pixelformat == PEControl::RGB8_Z24) - EncodeRGB8halfscale(dest_ptr, src, format); + EncodeRGB8halfscale(dest_ptr, src, copyfmt, bIsIntensityFmt); else if (pixelformat == PEControl::RGB565_Z16) // not supported - EncodeRGB8halfscale(dest_ptr, src, format); + EncodeRGB8halfscale(dest_ptr, src, copyfmt, bIsIntensityFmt); else if (pixelformat == PEControl::Z24) - EncodeZ24halfscale(dest_ptr, src, format); + EncodeZ24halfscale(dest_ptr, src, copyfmt); } else { if (pixelformat == PEControl::RGBA6_Z24) - EncodeRGBA6(dest_ptr, src, format); + EncodeRGBA6(dest_ptr, src, copyfmt, bIsIntensityFmt); else if (pixelformat == PEControl::RGB8_Z24) - EncodeRGB8(dest_ptr, src, format); + EncodeRGB8(dest_ptr, src, copyfmt, bIsIntensityFmt); else if (pixelformat == PEControl::RGB565_Z16) // not supported - EncodeRGB8(dest_ptr, src, format); + EncodeRGB8(dest_ptr, src, copyfmt, bIsIntensityFmt); else if (pixelformat == PEControl::Z24) - EncodeZ24(dest_ptr, src, format); + EncodeZ24(dest_ptr, src, copyfmt); } } } diff --git a/Source/Core/VideoBackends/Software/TextureSampler.cpp b/Source/Core/VideoBackends/Software/TextureSampler.cpp index 248e4a6f19..0decf134c9 100644 --- a/Source/Core/VideoBackends/Software/TextureSampler.cpp +++ b/Source/Core/VideoBackends/Software/TextureSampler.cpp @@ -111,13 +111,14 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample) TexMode0& tm0 = texUnit.texMode0[subTexmap]; TexImage0& ti0 = texUnit.texImage0[subTexmap]; TexTLUT& texTlut = texUnit.texTlut[subTexmap]; - TlutFormat tlutfmt = (TlutFormat)texTlut.tlut_format; + TextureFormat texfmt = static_cast<TextureFormat>(ti0.format); + TLUTFormat tlutfmt = static_cast<TLUTFormat>(texTlut.tlut_format); u8 *imageSrc, *imageSrcOdd = nullptr; if (texUnit.texImage1[subTexmap].image_type) { imageSrc = &texMem[texUnit.texImage1[subTexmap].tmem_even * TMEM_LINE_SIZE]; - if (ti0.format == GX_TF_RGBA8) + if (texfmt == TextureFormat::RGBA8) imageSrcOdd = &texMem[texUnit.texImage2[subTexmap].tmem_odd * TMEM_LINE_SIZE]; } else @@ -139,9 +140,9 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample) int mipWidth = imageWidth + 1; int mipHeight = imageHeight + 1; - int fmtWidth = TexDecoder_GetBlockWidthInTexels(ti0.format); - int fmtHeight = TexDecoder_GetBlockHeightInTexels(ti0.format); - int fmtDepth = TexDecoder_GetTexelSizeInNibbles(ti0.format); + int fmtWidth = TexDecoder_GetBlockWidthInTexels(texfmt); + int fmtHeight = TexDecoder_GetBlockHeightInTexels(texfmt); + int fmtDepth = TexDecoder_GetTexelSizeInNibbles(texfmt); imageWidth >>= mip; imageHeight >>= mip; @@ -186,21 +187,21 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample) WrapCoord(&imageSPlus1, tm0.wrap_s, imageWidth); WrapCoord(&imageTPlus1, tm0.wrap_t, imageHeight); - if (!(ti0.format == GX_TF_RGBA8 && texUnit.texImage1[subTexmap].image_type)) + if (!(texfmt == TextureFormat::RGBA8 && texUnit.texImage1[subTexmap].image_type)) { - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, ti0.format, tlut, + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, texfmt, tlut, tlutfmt); SetTexel(sampledTex, texel, (128 - fractS) * (128 - fractT)); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageT, imageWidth, ti0.format, - tlut, tlutfmt); + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageT, imageWidth, texfmt, tlut, + tlutfmt); AddTexel(sampledTex, texel, (fractS) * (128 - fractT)); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageTPlus1, imageWidth, ti0.format, - tlut, tlutfmt); + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageTPlus1, imageWidth, texfmt, tlut, + tlutfmt); AddTexel(sampledTex, texel, (128 - fractS) * (fractT)); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageTPlus1, imageWidth, ti0.format, + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageTPlus1, imageWidth, texfmt, tlut, tlutfmt); AddTexel(sampledTex, texel, (fractS) * (fractT)); } @@ -238,9 +239,8 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample) WrapCoord(&imageS, tm0.wrap_s, imageWidth); WrapCoord(&imageT, tm0.wrap_t, imageHeight); - if (!(ti0.format == GX_TF_RGBA8 && texUnit.texImage1[subTexmap].image_type)) - TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, ti0.format, tlut, - tlutfmt); + if (!(texfmt == TextureFormat::RGBA8 && texUnit.texImage1[subTexmap].image_type)) + TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, texfmt, tlut, tlutfmt); else TexDecoder_DecodeTexelRGBA8FromTmem(sample, imageSrc, imageSrcOdd, imageS, imageT, imageWidth); diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp index 30817706b7..1d8221f646 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp @@ -95,8 +95,8 @@ bool TextureCache::Initialize() return true; } -void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, void* palette, - TlutFormat format) +void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, + const void* palette, TLUTFormat format) { m_texture_converter->ConvertTexture(destination, source, m_render_pass, palette, format); @@ -111,9 +111,9 @@ void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } -void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width, +void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, 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) + const EFBRectangle& src_rect, bool scale_by_half) { // Flush EFB pokes first, as they're expected to be included. FramebufferManager::GetInstance()->FlushEFBPokes(); @@ -128,7 +128,7 @@ void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_widt region = Util::ClampRect2D(region, FramebufferManager::GetInstance()->GetEFBWidth(), FramebufferManager::GetInstance()->GetEFBHeight()); Texture2D* src_texture; - if (is_depth_copy) + if (params.depth) src_texture = FramebufferManager::GetInstance()->ResolveEFBDepthTexture(region); else src_texture = FramebufferManager::GetInstance()->ResolveEFBColorTexture(region); @@ -144,15 +144,15 @@ void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_widt src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - m_texture_converter->EncodeTextureToMemory(src_texture->GetView(), dst, format, native_width, - bytes_per_row, num_blocks_y, memory_stride, - is_depth_copy, src_rect, scale_by_half); + m_texture_converter->EncodeTextureToMemory(src_texture->GetView(), dst, params, native_width, + bytes_per_row, num_blocks_y, memory_stride, src_rect, + scale_by_half); // Transition back to original state src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout); } -bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TlutFormat palette_format) +bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format) { return m_texture_converter->SupportsTextureDecoding(format, palette_format); } @@ -160,7 +160,7 @@ bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TlutFormat pal void TextureCache::DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, u32 row_stride, - const u8* palette, TlutFormat palette_format) + const u8* palette, TLUTFormat palette_format) { // Group compute shader dispatches together in the init command buffer. That way we don't have to // pay a penalty for switching from graphics->compute, or end/restart our render pass. diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.h b/Source/Core/VideoBackends/Vulkan/TextureCache.h index d17dd3d1e7..9bfa2da04e 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.h +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.h @@ -33,19 +33,19 @@ public: std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override; - void ConvertTexture(TCacheEntry* destination, TCacheEntry* source, void* palette, - TlutFormat format) override; + void ConvertTexture(TCacheEntry* destination, TCacheEntry* source, const void* palette, + TLUTFormat format) 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; + void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) override; - bool SupportsGPUTextureDecode(TextureFormat format, TlutFormat palette_format) override; + bool SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format) override; void DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, u32 row_stride, const u8* palette, - TlutFormat palette_format) override; + TLUTFormat palette_format) override; VkShaderModule GetCopyShader() const; VkRenderPass GetTextureCopyRenderPass() const; diff --git a/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp b/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp index ca045ec0ce..20be913b6a 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp @@ -166,7 +166,7 @@ TextureConverter::GetCommandBufferForTextureConversion(const TextureCache::TCach void TextureConverter::ConvertTexture(TextureCacheBase::TCacheEntry* dst_entry, TextureCacheBase::TCacheEntry* src_entry, VkRenderPass render_pass, const void* palette, - TlutFormat palette_format) + TLUTFormat palette_format) { struct PSUniformBlock { @@ -182,7 +182,7 @@ void TextureConverter::ConvertTexture(TextureCacheBase::TCacheEntry* dst_entry, _assert_(destination_texture->GetConfig().rendertarget); // We want to align to 2 bytes (R16) or the device's texel buffer alignment, whichever is greater. - size_t palette_size = (src_entry->format & 0xF) == GX_TF_I4 ? 32 : 512; + size_t palette_size = src_entry->format == TextureFormat::I4 ? 32 : 512; if (!ReserveTexelBufferStorage(palette_size, sizeof(u16))) return; @@ -201,13 +201,13 @@ void TextureConverter::ConvertTexture(TextureCacheBase::TCacheEntry* dst_entry, UtilityShaderDraw draw(command_buffer, g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_TEXTURE_CONVERSION), render_pass, g_shader_cache->GetScreenQuadVertexShader(), VK_NULL_HANDLE, - m_palette_conversion_shaders[palette_format]); + m_palette_conversion_shaders[static_cast<int>(palette_format)]); VkRect2D region = {{0, 0}, {dst_entry->GetWidth(), dst_entry->GetHeight()}}; draw.BeginRenderPass(destination_texture->GetFramebuffer(), region); PSUniformBlock uniforms = {}; - uniforms.multiplier = (src_entry->format & 0xF) == GX_TF_I4 ? 15.0f : 255.0f; + uniforms.multiplier = src_entry->format == TextureFormat::I4 ? 15.0f : 255.0f; uniforms.texel_buffer_offset = static_cast<int>(palette_offset / sizeof(u16)); draw.SetPushConstants(&uniforms, sizeof(uniforms)); draw.SetPSSampler(0, source_texture->GetRawTexIdentifier()->GetView(), @@ -219,16 +219,15 @@ void TextureConverter::ConvertTexture(TextureCacheBase::TCacheEntry* dst_entry, } void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, - const EFBCopyFormat& format, u32 native_width, + const EFBCopyParams& params, 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) + const EFBRectangle& src_rect, bool scale_by_half) { - VkShaderModule shader = GetEncodingShader(format); + VkShaderModule shader = GetEncodingShader(params); if (shader == VK_NULL_HANDLE) { - ERROR_LOG(VIDEO, "Missing encoding fragment shader for format %u->%u", format.efb_format, - static_cast<u32>(format.copy_format)); + ERROR_LOG(VIDEO, "Missing encoding fragment shader for format %u->%u", + static_cast<unsigned>(params.efb_format), static_cast<unsigned>(params.copy_format)); return; } @@ -251,7 +250,7 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p // We also linear filtering for both box filtering and downsampling higher resolutions to 1x // TODO: This only produces perfect downsampling for 1.5x and 2x IR, other resolution will // need more complex down filtering to average all pixels and produce the correct result. - bool linear_filter = (scale_by_half && !is_depth_copy) || g_ActiveConfig.iEFBScale != SCALE_1X; + bool linear_filter = (scale_by_half && !params.depth) || g_ActiveConfig.iEFBScale != SCALE_1X; draw.SetPSSampler(0, src_texture, linear_filter ? g_object_cache->GetLinearSampler() : g_object_cache->GetPointSampler()); @@ -387,7 +386,7 @@ void TextureConverter::DecodeYUYVTextureFromMemory(VKTexture* dst_texture, const draw.EndRenderPass(); } -bool TextureConverter::SupportsTextureDecoding(TextureFormat format, TlutFormat palette_format) +bool TextureConverter::SupportsTextureDecoding(TextureFormat format, TLUTFormat palette_format) { auto key = std::make_pair(format, palette_format); auto iter = m_decoding_pipelines.find(key); @@ -424,7 +423,7 @@ void TextureConverter::DecodeTexture(VkCommandBuffer command_buffer, TextureCache::TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, - u32 row_stride, const u8* palette, TlutFormat palette_format) + u32 row_stride, const u8* palette, TLUTFormat palette_format) { VKTexture* destination_texture = static_cast<VKTexture*>(entry->texture.get()); auto key = std::make_pair(format, palette_format); @@ -667,21 +666,21 @@ bool TextureConverter::CompilePaletteConversionShaders() std::string palette_rgb5a3_program = StringFromFormat( "%s\n%s", "#define DECODE DecodePixel_RGB5A3", PALETTE_CONVERSION_FRAGMENT_SHADER_SOURCE); - m_palette_conversion_shaders[GX_TL_IA8] = + m_palette_conversion_shaders[static_cast<int>(TLUTFormat::IA8)] = Util::CompileAndCreateFragmentShader(palette_ia8_program); - m_palette_conversion_shaders[GX_TL_RGB565] = + m_palette_conversion_shaders[static_cast<int>(TLUTFormat::RGB565)] = Util::CompileAndCreateFragmentShader(palette_rgb565_program); - m_palette_conversion_shaders[GX_TL_RGB5A3] = + m_palette_conversion_shaders[static_cast<int>(TLUTFormat::RGB5A3)] = Util::CompileAndCreateFragmentShader(palette_rgb5a3_program); - return m_palette_conversion_shaders[GX_TL_IA8] != VK_NULL_HANDLE && - m_palette_conversion_shaders[GX_TL_RGB565] != VK_NULL_HANDLE && - m_palette_conversion_shaders[GX_TL_RGB5A3] != VK_NULL_HANDLE; + return m_palette_conversion_shaders[static_cast<int>(TLUTFormat::IA8)] != VK_NULL_HANDLE && + m_palette_conversion_shaders[static_cast<int>(TLUTFormat::RGB565)] != VK_NULL_HANDLE && + m_palette_conversion_shaders[static_cast<int>(TLUTFormat::RGB5A3)] != VK_NULL_HANDLE; } -VkShaderModule TextureConverter::CompileEncodingShader(const EFBCopyFormat& format) +VkShaderModule TextureConverter::CompileEncodingShader(const EFBCopyParams& params) { - const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::Vulkan); + const char* shader = TextureConversionShader::GenerateEncodingShader(params, APIType::Vulkan); VkShaderModule module = Util::CompileAndCreateFragmentShader(shader); if (module == VK_NULL_HANDLE) PanicAlert("Failed to compile texture encoding shader."); @@ -689,14 +688,14 @@ VkShaderModule TextureConverter::CompileEncodingShader(const EFBCopyFormat& form return module; } -VkShaderModule TextureConverter::GetEncodingShader(const EFBCopyFormat& format) +VkShaderModule TextureConverter::GetEncodingShader(const EFBCopyParams& params) { - auto iter = m_encoding_shaders.find(format); + auto iter = m_encoding_shaders.find(params); if (iter != m_encoding_shaders.end()) return iter->second; - VkShaderModule shader = CompileEncodingShader(format); - m_encoding_shaders.emplace(format, shader); + VkShaderModule shader = CompileEncodingShader(params); + m_encoding_shaders.emplace(params, shader); return shader; } diff --git a/Source/Core/VideoBackends/Vulkan/TextureConverter.h b/Source/Core/VideoBackends/Vulkan/TextureConverter.h index 3b9afee9ea..2465691901 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureConverter.h +++ b/Source/Core/VideoBackends/Vulkan/TextureConverter.h @@ -33,14 +33,13 @@ public: // Applies palette to dst_entry, using indices from src_entry. void ConvertTexture(TextureCacheBase::TCacheEntry* dst_entry, TextureCache::TCacheEntry* src_entry, VkRenderPass render_pass, - const void* palette, TlutFormat palette_format); + const void* palette, TLUTFormat palette_format); // Uses an encoding shader to copy src_texture to dest_ptr. // NOTE: Executes the current command buffer. - void EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, const EFBCopyFormat& format, + void EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, const EFBCopyParams& params, 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); + u32 memory_stride, const EFBRectangle& src_rect, bool scale_by_half); // Encodes texture to guest memory in XFB (YUYV) format. void EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u32 dst_stride, u32 dst_height, @@ -50,11 +49,11 @@ public: void DecodeYUYVTextureFromMemory(VKTexture* dst_texture, const void* src_ptr, u32 src_width, u32 src_stride, u32 src_height); - bool SupportsTextureDecoding(TextureFormat format, TlutFormat palette_format); + bool SupportsTextureDecoding(TextureFormat format, TLUTFormat palette_format); void DecodeTexture(VkCommandBuffer command_buffer, TextureCache::TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, u32 row_stride, - const u8* palette, TlutFormat palette_format); + const u8* palette, TLUTFormat palette_format); private: static const u32 ENCODING_TEXTURE_WIDTH = EFB_WIDTH * 4; @@ -71,8 +70,8 @@ private: bool CompilePaletteConversionShaders(); - VkShaderModule CompileEncodingShader(const EFBCopyFormat& format); - VkShaderModule GetEncodingShader(const EFBCopyFormat& format); + VkShaderModule CompileEncodingShader(const EFBCopyParams& params); + VkShaderModule GetEncodingShader(const EFBCopyParams& params); bool CreateEncodingRenderPass(); bool CreateEncodingTexture(); @@ -105,7 +104,7 @@ private: std::array<VkShaderModule, NUM_PALETTE_CONVERSION_SHADERS> m_palette_conversion_shaders = {}; // Texture encoding - RGBA8->GX format in memory - std::map<EFBCopyFormat, VkShaderModule> m_encoding_shaders; + std::map<EFBCopyParams, VkShaderModule> m_encoding_shaders; VkRenderPass m_encoding_render_pass = VK_NULL_HANDLE; std::unique_ptr<Texture2D> m_encoding_render_texture; VkFramebuffer m_encoding_render_framebuffer = VK_NULL_HANDLE; @@ -118,7 +117,7 @@ private: VkShaderModule compute_shader; bool valid; }; - std::map<std::pair<TextureFormat, TlutFormat>, TextureDecodingPipeline> m_decoding_pipelines; + std::map<std::pair<TextureFormat, TLUTFormat>, TextureDecodingPipeline> m_decoding_pipelines; std::unique_ptr<Texture2D> m_decoding_texture; // XFB encoding/decoding shaders |
