diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 638ba9479..4dec13568 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -1245,7 +1245,7 @@ void GPU::ReadVRAM(u32 x, u32 y, u32 width, u32 height) {} void GPU::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) { - const u16 color16 = RGBA8888ToRGBA5551(color); + const u16 color16 = VRAMRGBA8888ToRGBA5551(color); if ((x + width) <= VRAM_WIDTH && !IsInterlacedRenderingEnabled()) { for (u32 yoffs = 0; yoffs < height; yoffs++) @@ -1507,7 +1507,7 @@ bool GPU::DumpVRAMToFile(const char* filename, u32 width, u32 height, u32 stride u16 src_col; std::memcpy(&src_col, row_ptr_in, sizeof(u16)); row_ptr_in += sizeof(u16); - *(ptr_out++) = RGBA5551ToRGBA8888(remove_alpha ? (src_col | u16(0x8000)) : src_col); + *(ptr_out++) = VRAMRGBA5551ToRGBA8888(remove_alpha ? (src_col | u16(0x8000)) : src_col); } ptr_in += stride; diff --git a/src/core/gpu.h b/src/core/gpu.h index acae48ce1..a81d0e63d 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -175,27 +175,6 @@ protected: } ALWAYS_INLINE static constexpr TickCount SystemTicksToGPUTicks(TickCount sysclk_ticks) { return sysclk_ticks << 1; } - // Helper/format conversion functions - constants from https://stackoverflow.com/a/9069480 - ALWAYS_INLINE static constexpr u32 Convert5To8(u32 color) { return (((color * 527u) + 23u) >> 6); } - ALWAYS_INLINE static constexpr u32 Convert8To5(u32 color) { return (((color * 249u) + 1014u) >> 11); } - static constexpr u32 RGBA5551ToRGBA8888(u32 color) - { - const u32 r = Convert5To8(color & 31u); - const u32 g = Convert5To8((color >> 5) & 31u); - const u32 b = Convert5To8((color >> 10) & 31u); - const u32 a = ((color >> 15) != 0) ? 255 : 0; - return ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (ZeroExtend32(a) << 24); - } - - static constexpr u16 RGBA8888ToRGBA5551(u32 color) - { - const u32 r = Convert8To5(color & 0xFFu); - const u32 g = Convert8To5((color >> 8) & 0xFFu); - const u32 b = Convert8To5((color >> 16) & 0xFFu); - const u32 a = ((color >> 24) & 0x01u); - return Truncate16(r | (g << 5) | (b << 10) | (a << 15)); - } - static constexpr std::tuple UnpackTexcoord(u16 texcoord) { return std::make_tuple(static_cast(texcoord), static_cast(texcoord >> 8)); diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 2f6a46f4f..a41c92d73 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -885,7 +885,7 @@ GPU_HW::VRAMFillUBOData GPU_HW::GetVRAMFillUBOData(u32 x, u32 y, u32 width, u32 { // drop precision unless true colour is enabled if (!m_true_color) - color = RGBA5551ToRGBA8888(RGBA8888ToRGBA5551(color)); + color = VRAMRGBA5551ToRGBA8888(VRAMRGBA8888ToRGBA5551(color)); VRAMFillUBOData uniforms; std::tie(uniforms.u_fill_color[0], uniforms.u_fill_color[1], uniforms.u_fill_color[2], uniforms.u_fill_color[3]) = diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 4994f3fe2..06a58c0b5 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -1031,7 +1031,8 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) // fast path when not using interlaced rendering if (!IsInterlacedRenderingEnabled()) { - const auto [r, g, b, a] = RGBA8ToFloat(m_true_color ? color : RGBA5551ToRGBA8888(RGBA8888ToRGBA5551(color))); + const auto [r, g, b, a] = + RGBA8ToFloat(m_true_color ? color : VRAMRGBA5551ToRGBA8888(VRAMRGBA8888ToRGBA5551(color))); glClearColor(r, g, b, a); IsGLES() ? glClearDepthf(a) : glClearDepth(a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1128,7 +1129,7 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* u16 src_col; std::memcpy(&src_col, source_row_ptr, sizeof(src_col)); source_row_ptr += sizeof(src_col); - *(dest_ptr++) = RGBA5551ToRGBA8888(src_col | mask_or); + *(dest_ptr++) = VRAMRGBA5551ToRGBA8888(src_col | mask_or); } source_ptr -= source_stride; diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index 0242b0cb9..9eed97cd0 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -115,30 +115,16 @@ ALWAYS_INLINE u16 VRAM16ToOutput(u16 value) template<> ALWAYS_INLINE u32 VRAM16ToOutput(u16 value) { - u8 r = Truncate8(value & 31); - u8 g = Truncate8((value >> 5) & 31); - u8 b = Truncate8((value >> 10) & 31); - - // 00012345 -> 1234545 - b = (b << 3) | (b & 0b111); - g = (g << 3) | (g & 0b111); - r = (r << 3) | (r & 0b111); - - return ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (0xFF000000u); + return VRAMRGBA5551ToRGBA8888(value); } template<> ALWAYS_INLINE u32 VRAM16ToOutput(u16 value) { - u8 r = Truncate8(value & 31); - u8 g = Truncate8((value >> 5) & 31); - u8 b = Truncate8((value >> 10) & 31); - - // 00012345 -> 1234545 - b = (b << 3) | (b & 0b111); - g = (g << 3) | (g & 0b111); - r = (r << 3) | (r & 0b111); - + const u32 value32 = ZeroExtend32(value); + const u32 r = VRAMConvert5To8(value32 & 31u); + const u32 g = VRAMConvert5To8((value32 >> 5) & 31u); + const u32 b = VRAMConvert5To8((value32 >> 10) & 31u); return ZeroExtend32(b) | (ZeroExtend32(g) << 8) | (ZeroExtend32(r) << 16) | (0xFF000000u); } diff --git a/src/core/gpu_sw_backend.cpp b/src/core/gpu_sw_backend.cpp index 55e39958c..eafd317ed 100644 --- a/src/core/gpu_sw_backend.cpp +++ b/src/core/gpu_sw_backend.cpp @@ -769,7 +769,7 @@ GPU_SW_Backend::GetDrawRectangleFunction(bool texture_enable, bool raw_texture_e void GPU_SW_Backend::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color, GPUBackendCommandParameters params) { - const u16 color16 = RGBA8888ToRGBA5551(color); + const u16 color16 = VRAMRGBA8888ToRGBA5551(color); if ((x + width) <= VRAM_WIDTH && !params.interlaced_rendering) { for (u32 yoffs = 0; yoffs < height; yoffs++) diff --git a/src/core/gpu_types.h b/src/core/gpu_types.h index b3edbb64e..e3e66c420 100644 --- a/src/core/gpu_types.h +++ b/src/core/gpu_types.h @@ -114,31 +114,31 @@ union GPURenderCommand } }; -// Helper/format conversion functions. -static constexpr u32 RGBA5551ToRGBA8888(u16 color) +// Helper/format conversion functions - constants from https://stackoverflow.com/a/9069480 +ALWAYS_INLINE static constexpr u32 VRAMConvert5To8(u32 color) { - u8 r = Truncate8(color & 31); - u8 g = Truncate8((color >> 5) & 31); - u8 b = Truncate8((color >> 10) & 31); - u8 a = Truncate8((color >> 15) & 1); - - // 00012345 -> 1234545 - b = (b << 3) | (b & 0b111); - g = (g << 3) | (g & 0b111); - r = (r << 3) | (r & 0b111); - a = a ? 255 : 0; - + return (((color * 527u) + 23u) >> 6); +} +ALWAYS_INLINE static constexpr u32 VRAMConvert8To5(u32 color) +{ + return (((color * 249u) + 1014u) >> 11); +} +ALWAYS_INLINE static constexpr u32 VRAMRGBA5551ToRGBA8888(u32 color) +{ + const u32 r = VRAMConvert5To8(color & 31u); + const u32 g = VRAMConvert5To8((color >> 5) & 31u); + const u32 b = VRAMConvert5To8((color >> 10) & 31u); + const u32 a = ((color >> 15) != 0) ? 255 : 0; return ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (ZeroExtend32(a) << 24); } -static constexpr u16 RGBA8888ToRGBA5551(u32 color) +ALWAYS_INLINE static constexpr u16 VRAMRGBA8888ToRGBA5551(u32 color) { - const u16 r = Truncate16((color >> 3) & 0x1Fu); - const u16 g = Truncate16((color >> 11) & 0x1Fu); - const u16 b = Truncate16((color >> 19) & 0x1Fu); - const u16 a = Truncate16((color >> 31) & 0x01u); - - return r | (g << 5) | (b << 10) | (a << 15); + const u32 r = VRAMConvert8To5(color & 0xFFu); + const u32 g = VRAMConvert8To5((color >> 8) & 0xFFu); + const u32 b = VRAMConvert8To5((color >> 16) & 0xFFu); + const u32 a = ((color >> 24) & 0x01u); + return Truncate16(r | (g << 5) | (b << 10) | (a << 15)); } union GPUVertexPosition diff --git a/src/core/texture_replacements.cpp b/src/core/texture_replacements.cpp index 70c1664bd..1f3392d44 100644 --- a/src/core/texture_replacements.cpp +++ b/src/core/texture_replacements.cpp @@ -15,7 +15,7 @@ Log_SetChannel(TextureReplacements); TextureReplacements g_texture_replacements; -static constexpr u32 RGBA5551ToRGBA8888(u16 color) +static constexpr u32 VRAMRGBA5551ToRGBA8888(u16 color) { u8 r = Truncate8(color & 31); u8 g = Truncate8((color >> 5) & 31); @@ -90,7 +90,7 @@ void TextureReplacements::DumpVRAMWrite(u32 width, u32 height, const void* pixel { for (u32 x = 0; x < width; x++) { - image.SetPixel(x, y, RGBA5551ToRGBA8888(*src_pixels)); + image.SetPixel(x, y, VRAMRGBA5551ToRGBA8888(*src_pixels)); src_pixels++; } }