mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 23:25:41 +00:00
GPU: Use texel fetch for creating page textures
This commit is contained in:
parent
19d9322e67
commit
b5d51f47cd
|
@ -409,8 +409,8 @@ bool GPU::HandleRenderCommand()
|
||||||
ZeroExtend32(words_per_vertex));
|
ZeroExtend32(words_per_vertex));
|
||||||
|
|
||||||
DispatchRenderCommand(rc, num_vertices);
|
DispatchRenderCommand(rc, num_vertices);
|
||||||
FlushRender();
|
//FlushRender();
|
||||||
UpdateDisplay();
|
//UpdateDisplay();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ void GPU::TextureConfig::SetFromPageAttribute(u16 value)
|
||||||
if (page_attribute == value)
|
if (page_attribute == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
base_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x1FF)) * UINT32_C(64));
|
base_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x0F)) * UINT32_C(64));
|
||||||
base_y = static_cast<s32>(ZeroExtend32((value >> 11) & UINT16_C(1)) * UINT32_C(512));
|
base_y = static_cast<s32>(ZeroExtend32((value >> 11) & UINT16_C(1)) * UINT32_C(512));
|
||||||
page_attribute = value;
|
page_attribute = value;
|
||||||
page_changed = true;
|
page_changed = true;
|
||||||
|
|
|
@ -123,13 +123,19 @@ static void DefineMacro(std::stringstream& ss, const char* name, bool enabled)
|
||||||
void GPU_HW::GenerateShaderHeader(std::stringstream& ss)
|
void GPU_HW::GenerateShaderHeader(std::stringstream& ss)
|
||||||
{
|
{
|
||||||
ss << "#version 330 core\n\n";
|
ss << "#version 330 core\n\n";
|
||||||
ss << "const vec2 vram_size = vec2(float(" << VRAM_WIDTH << "), float(" << VRAM_HEIGHT << "));\n";
|
ss << "const ivec2 VRAM_SIZE = ivec2(" << VRAM_WIDTH << ", " << VRAM_HEIGHT << ");\n";
|
||||||
ss << "const vec2 rcp_vram_size = vec2(1.0, 1.0) / vram_size;\n";
|
ss << "const ivec2 VRAM_COORD_MASK = ivec2(" << (VRAM_WIDTH - 1) << ", " << (VRAM_HEIGHT - 1) << ");\n";
|
||||||
|
ss << "const vec2 RCP_VRAM_SIZE = vec2(1.0, 1.0) / vec2(VRAM_SIZE);\n";
|
||||||
ss << R"(
|
ss << R"(
|
||||||
|
|
||||||
float fixYCoord(float y)
|
float fixYCoord(float y)
|
||||||
{
|
{
|
||||||
return 1.0 - rcp_vram_size.y - y;
|
return 1.0 - RCP_VRAM_SIZE.y - y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fixYCoord(int y)
|
||||||
|
{
|
||||||
|
return VRAM_SIZE.y - y - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint RGBA8ToRGBA5551(vec4 v)
|
uint RGBA8ToRGBA5551(vec4 v)
|
||||||
|
@ -179,7 +185,7 @@ void main()
|
||||||
|
|
||||||
v_col0 = a_col0;
|
v_col0 = a_col0;
|
||||||
#if TEXTURED
|
#if TEXTURED
|
||||||
v_tex0 = vec2(a_tex0 * u_tex_scale);
|
v_tex0 = a_tex0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
@ -255,10 +261,10 @@ std::string GPU_HW::GenerateTexturePageFragmentShader(TextureColorMode mode)
|
||||||
|
|
||||||
ss << R"(
|
ss << R"(
|
||||||
uniform sampler2D samp0;
|
uniform sampler2D samp0;
|
||||||
uniform vec2 base_offset;
|
uniform ivec2 base_offset;
|
||||||
|
|
||||||
#if PALETTE
|
#if PALETTE
|
||||||
uniform vec2 palette_offset;
|
uniform ivec2 palette_offset;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
in vec2 v_tex0;
|
in vec2 v_tex0;
|
||||||
|
@ -266,33 +272,32 @@ out vec4 o_col0;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
ivec2 local_coords = ivec2(gl_FragCoord.xy);
|
||||||
#if PALETTE_4_BIT
|
#if PALETTE_4_BIT
|
||||||
vec2 local_coords = vec2(v_tex0.x / 4.0, v_tex0.y);
|
local_coords.x /= 4;
|
||||||
#elif PALETTE_8_BIT
|
#elif PALETTE_8_BIT
|
||||||
vec2 local_coords = vec2(v_tex0.x / 2.0, v_tex0.y);
|
local_coords.x /= 2;
|
||||||
#else
|
|
||||||
vec2 local_coords = v_tex0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// fixup coords
|
// fixup coords
|
||||||
vec2 coords = vec2(local_coords.x + base_offset.x, fixYCoord(local_coords.y + base_offset.y));
|
ivec2 coords = ivec2(base_offset.x + local_coords.x, fixYCoord(base_offset.y + local_coords.y));
|
||||||
|
|
||||||
// load colour/palette
|
// load colour/palette
|
||||||
vec4 color = texture(samp0, coords);
|
vec4 color = texelFetch(samp0, coords & VRAM_COORD_MASK, 0);
|
||||||
|
|
||||||
// apply palette
|
// apply palette
|
||||||
#if PALETTE
|
#if PALETTE
|
||||||
#if PALETTE_4_BIT
|
#if PALETTE_4_BIT
|
||||||
uint subpixel = uint(gl_FragCoord.x) & 3u;
|
int subpixel = int(gl_FragCoord.x) & 3;
|
||||||
uint vram_value = RGBA8ToRGBA5551(color);
|
uint vram_value = RGBA8ToRGBA5551(color);
|
||||||
float palette_index = float((vram_value >> (subpixel * 4u)) & 0x0Fu) * rcp_vram_size.x;
|
int palette_index = int((vram_value >> (subpixel * 4)) & 0x0Fu);
|
||||||
#elif PALETTE_8_BIT
|
#elif PALETTE_8_BIT
|
||||||
// TODO: Still has precision issues here
|
int subpixel = int(gl_FragCoord.x) & 1;
|
||||||
uint subpixel = uint(gl_FragCoord.x) & 1u;
|
uint vram_value = RGBA8ToRGBA5551(color);
|
||||||
float palette_index = ((subpixel == 0u) ? color.x : color.y) * (255.0 * rcp_vram_size.x);
|
int palette_index = int((vram_value >> (subpixel * 8)) & 0xFFu);
|
||||||
#endif
|
#endif
|
||||||
vec2 palette_coords = vec2(palette_offset.x + palette_index, fixYCoord(palette_offset.y));
|
ivec2 palette_coords = ivec2(palette_offset.x + palette_index, fixYCoord(palette_offset.y));
|
||||||
color = texture(samp0, palette_coords);
|
color = texelFetch(samp0, palette_coords & VRAM_COORD_MASK, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
o_col0 = color;
|
o_col0 = color;
|
||||||
|
|
|
@ -151,9 +151,8 @@ bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, bool textured, bool blendi
|
||||||
if (textured)
|
if (textured)
|
||||||
{
|
{
|
||||||
prog.Bind();
|
prog.Bind();
|
||||||
prog.RegisterUniform("u_tex_scale");
|
|
||||||
prog.RegisterUniform("samp0");
|
prog.RegisterUniform("samp0");
|
||||||
prog.Uniform1i(1, 0);
|
prog.Uniform1i(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -165,28 +164,8 @@ void GPU_HW_OpenGL::SetProgram(bool textured, bool blending)
|
||||||
prog.Bind();
|
prog.Bind();
|
||||||
|
|
||||||
if (textured)
|
if (textured)
|
||||||
{
|
|
||||||
switch (m_texture_config.color_mode)
|
|
||||||
{
|
|
||||||
case GPU::TextureColorMode::Palette4Bit:
|
|
||||||
prog.Uniform2f(0, 1.0f / 4, 1.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GPU::TextureColorMode::Palette8Bit:
|
|
||||||
prog.Uniform2f(0, 1.0f / 2, 1.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GPU::TextureColorMode::Direct16Bit:
|
|
||||||
prog.Uniform2f(0, 1.0f, 1.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_texture_page_texture->Bind();
|
m_texture_page_texture->Bind();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW_OpenGL::SetViewport()
|
void GPU_HW_OpenGL::SetViewport()
|
||||||
{
|
{
|
||||||
|
@ -334,16 +313,9 @@ void GPU_HW_OpenGL::UpdateTexturePageTexture()
|
||||||
const GL::Program& prog = m_texture_page_programs[static_cast<u8>(m_texture_config.color_mode)];
|
const GL::Program& prog = m_texture_page_programs[static_cast<u8>(m_texture_config.color_mode)];
|
||||||
prog.Bind();
|
prog.Bind();
|
||||||
|
|
||||||
const float base_x = static_cast<float>(m_texture_config.base_x) * (1.0f / static_cast<float>(VRAM_WIDTH));
|
prog.Uniform2i(1, m_texture_config.base_x, m_texture_config.base_y);
|
||||||
const float base_y = static_cast<float>(m_texture_config.base_y) * (1.0f / static_cast<float>(VRAM_HEIGHT));
|
|
||||||
prog.Uniform2f(1, base_x, base_y);
|
|
||||||
|
|
||||||
if (m_texture_config.color_mode >= GPU::TextureColorMode::Palette4Bit)
|
if (m_texture_config.color_mode >= GPU::TextureColorMode::Palette4Bit)
|
||||||
{
|
prog.Uniform2i(2, m_texture_config.palette_x, m_texture_config.palette_y);
|
||||||
const float palette_x = static_cast<float>(m_texture_config.palette_x) * (1.0f / static_cast<float>(VRAM_WIDTH));
|
|
||||||
const float palette_y = static_cast<float>(m_texture_config.palette_y) * (1.0f / static_cast<float>(VRAM_HEIGHT));
|
|
||||||
prog.Uniform2f(2, palette_x, palette_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue