mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
GPU: Fix texcoord off-by-one error in rectangles
This commit is contained in:
parent
9f5bd6e5f9
commit
5626d4f282
|
@ -101,7 +101,6 @@ protected:
|
||||||
{
|
{
|
||||||
return std::make_tuple(static_cast<u8>(texcoord), static_cast<u8>(texcoord >> 8));
|
return std::make_tuple(static_cast<u8>(texcoord), static_cast<u8>(texcoord >> 8));
|
||||||
}
|
}
|
||||||
static constexpr u16 PackTexcoord(u8 x, u8 y) { return ZeroExtend16(x) | (ZeroExtend16(y) << 8); }
|
|
||||||
|
|
||||||
static constexpr std::tuple<u8, u8, u8> UnpackColorRGB24(u32 rgb24)
|
static constexpr std::tuple<u8, u8, u8> UnpackColorRGB24(u32 rgb24)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,11 +46,14 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command
|
||||||
hw_vert.texpage = texpage;
|
hw_vert.texpage = texpage;
|
||||||
|
|
||||||
if (textured)
|
if (textured)
|
||||||
hw_vert.texcoord = Truncate16(command_ptr[buffer_pos++]);
|
{
|
||||||
|
const auto [texcoord_x, texcoord_y] = UnpackTexcoord(Truncate16(command_ptr[buffer_pos++]));
|
||||||
|
hw_vert.texcoord = HWVertex::PackTexcoord(texcoord_x, texcoord_y);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
hw_vert.texcoord = 0;
|
hw_vert.texcoord = 0;
|
||||||
|
}
|
||||||
hw_vert.padding = 0;
|
|
||||||
|
|
||||||
m_batch.vertices.push_back(hw_vert);
|
m_batch.vertices.push_back(hw_vert);
|
||||||
if (restart_strip)
|
if (restart_strip)
|
||||||
|
@ -74,9 +77,12 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command
|
||||||
const VertexPosition vp{command_ptr[buffer_pos++]};
|
const VertexPosition vp{command_ptr[buffer_pos++]};
|
||||||
const s32 pos_left = vp.x;
|
const s32 pos_left = vp.x;
|
||||||
const s32 pos_top = vp.y;
|
const s32 pos_top = vp.y;
|
||||||
const auto [tex_left, tex_top] = UnpackTexcoord(rc.texture_enable ? Truncate16(command_ptr[buffer_pos++]) : 0);
|
const auto [texcoord_x, texcoord_y] =
|
||||||
s32 rectangle_width;
|
UnpackTexcoord(rc.texture_enable ? Truncate16(command_ptr[buffer_pos++]) : 0);
|
||||||
s32 rectangle_height;
|
const u16 tex_left = ZeroExtend16(texcoord_x);
|
||||||
|
const u16 tex_top = ZeroExtend16(texcoord_y);
|
||||||
|
u32 rectangle_width;
|
||||||
|
u32 rectangle_height;
|
||||||
switch (rc.rectangle_size)
|
switch (rc.rectangle_size)
|
||||||
{
|
{
|
||||||
case DrawRectangleSize::R1x1:
|
case DrawRectangleSize::R1x1:
|
||||||
|
@ -92,23 +98,27 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command
|
||||||
rectangle_height = 16;
|
rectangle_height = 16;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rectangle_width = static_cast<s32>(command_ptr[buffer_pos] & UINT32_C(0xFFFF));
|
rectangle_width = command_ptr[buffer_pos] & 0xFFFF;
|
||||||
rectangle_height = static_cast<s32>(command_ptr[buffer_pos] >> 16);
|
rectangle_height = command_ptr[buffer_pos] >> 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should repeat the texcoords instead of stretching
|
// TODO: This should repeat the texcoords instead of stretching
|
||||||
const s32 pos_right = pos_left + rectangle_width;
|
const s32 pos_right = pos_left + static_cast<s32>(rectangle_width);
|
||||||
const s32 pos_bottom = pos_top + rectangle_height;
|
const s32 pos_bottom = pos_top + static_cast<s32>(rectangle_height);
|
||||||
const u8 tex_right = static_cast<u8>(tex_left + (rectangle_width - 1));
|
const u16 tex_right = tex_left + static_cast<u16>(rectangle_width);
|
||||||
const u8 tex_bottom = static_cast<u8>(tex_top + (rectangle_height - 1));
|
const u16 tex_bottom = tex_top + static_cast<u16>(rectangle_height);
|
||||||
|
|
||||||
m_batch.vertices.push_back(HWVertex{pos_left, pos_top, color, texpage, PackTexcoord(tex_left, tex_top)});
|
m_batch.vertices.push_back(
|
||||||
|
HWVertex{pos_left, pos_top, color, texpage, HWVertex::PackTexcoord(tex_left, tex_top)});
|
||||||
if (restart_strip)
|
if (restart_strip)
|
||||||
m_batch.vertices.push_back(m_batch.vertices.back());
|
m_batch.vertices.push_back(m_batch.vertices.back());
|
||||||
m_batch.vertices.push_back(HWVertex{pos_right, pos_top, color, texpage, PackTexcoord(tex_right, tex_top)});
|
m_batch.vertices.push_back(
|
||||||
m_batch.vertices.push_back(HWVertex{pos_left, pos_bottom, color, texpage, PackTexcoord(tex_left, tex_bottom)});
|
HWVertex{pos_right, pos_top, color, texpage, HWVertex::PackTexcoord(tex_right, tex_top)});
|
||||||
m_batch.vertices.push_back(HWVertex{pos_right, pos_bottom, color, texpage, PackTexcoord(tex_right, tex_bottom)});
|
m_batch.vertices.push_back(
|
||||||
|
HWVertex{pos_left, pos_bottom, color, texpage, HWVertex::PackTexcoord(tex_left, tex_bottom)});
|
||||||
|
m_batch.vertices.push_back(
|
||||||
|
HWVertex{pos_right, pos_bottom, color, texpage, HWVertex::PackTexcoord(tex_right, tex_bottom)});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -197,7 +207,7 @@ std::string GPU_HW::GenerateVertexShader(bool textured)
|
||||||
ss << R"(
|
ss << R"(
|
||||||
in ivec2 a_pos;
|
in ivec2 a_pos;
|
||||||
in vec4 a_col0;
|
in vec4 a_col0;
|
||||||
in vec2 a_tex0;
|
in int a_texcoord;
|
||||||
in int a_texpage;
|
in int a_texpage;
|
||||||
|
|
||||||
out vec3 v_col0;
|
out vec3 v_col0;
|
||||||
|
@ -217,7 +227,7 @@ void main()
|
||||||
|
|
||||||
v_col0 = a_col0.rgb;
|
v_col0 = a_col0.rgb;
|
||||||
#if TEXTURED
|
#if TEXTURED
|
||||||
v_tex0 = a_tex0;
|
v_tex0 = vec2(float(a_texcoord & 0xFFFF), float(a_texcoord >> 16)) / vec2(255.0);
|
||||||
|
|
||||||
// base_x,base_y,palette_x,palette_y
|
// base_x,base_y,palette_x,palette_y
|
||||||
v_texpage.x = (a_texpage & 15) * 64 * RESOLUTION_SCALE;
|
v_texpage.x = (a_texpage & 15) * 64 * RESOLUTION_SCALE;
|
||||||
|
|
|
@ -20,8 +20,10 @@ protected:
|
||||||
s32 y;
|
s32 y;
|
||||||
u32 color;
|
u32 color;
|
||||||
u32 texpage;
|
u32 texpage;
|
||||||
u16 texcoord;
|
u32 texcoord;
|
||||||
u16 padding;
|
|
||||||
|
// 16-bit texcoords are needed for 256 extent rectangles
|
||||||
|
static u32 PackTexcoord(u16 x, u16 y) { return ZeroExtend32(x) | (ZeroExtend32(y) << 16); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HWRenderBatch
|
struct HWRenderBatch
|
||||||
|
|
|
@ -221,8 +221,7 @@ void GPU_HW_OpenGL::CreateVertexBuffer()
|
||||||
glVertexAttribIPointer(0, 2, GL_INT, sizeof(HWVertex), reinterpret_cast<void*>(offsetof(HWVertex, x)));
|
glVertexAttribIPointer(0, 2, GL_INT, sizeof(HWVertex), reinterpret_cast<void*>(offsetof(HWVertex, x)));
|
||||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(HWVertex),
|
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(HWVertex),
|
||||||
reinterpret_cast<void*>(offsetof(HWVertex, color)));
|
reinterpret_cast<void*>(offsetof(HWVertex, color)));
|
||||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_BYTE, true, sizeof(HWVertex),
|
glVertexAttribIPointer(2, 2, GL_INT, sizeof(HWVertex), reinterpret_cast<void*>(offsetof(HWVertex, texcoord)));
|
||||||
reinterpret_cast<void*>(offsetof(HWVertex, texcoord)));
|
|
||||||
glVertexAttribIPointer(3, 1, GL_INT, sizeof(HWVertex), reinterpret_cast<void*>(offsetof(HWVertex, texpage)));
|
glVertexAttribIPointer(3, 1, GL_INT, sizeof(HWVertex), reinterpret_cast<void*>(offsetof(HWVertex, texpage)));
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
@ -289,7 +288,7 @@ bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, TransparencyRenderMode tra
|
||||||
prog.BindAttribute(1, "a_col0");
|
prog.BindAttribute(1, "a_col0");
|
||||||
if (textured)
|
if (textured)
|
||||||
{
|
{
|
||||||
prog.BindAttribute(2, "a_tex0");
|
prog.BindAttribute(2, "a_texcoord");
|
||||||
prog.BindAttribute(3, "a_texpage");
|
prog.BindAttribute(3, "a_texpage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -603,7 +603,7 @@ void SDLInterface::HandleSDLKeyEvent(const SDL_Event* event)
|
||||||
{
|
{
|
||||||
m_speed_limiter_enabled = !m_speed_limiter_enabled;
|
m_speed_limiter_enabled = !m_speed_limiter_enabled;
|
||||||
UpdateAudioVisualSync();
|
UpdateAudioVisualSync();
|
||||||
AddOSDMessage(m_speed_limiter_enabled ? "Speed limiter disabled" : "Speed limiter enabled");
|
AddOSDMessage(m_speed_limiter_enabled ? "Speed limiter enabled." : "Speed limiter disabled.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue