mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 05:45:38 +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));
|
||||
|
||||
DispatchRenderCommand(rc, num_vertices);
|
||||
FlushRender();
|
||||
UpdateDisplay();
|
||||
//FlushRender();
|
||||
//UpdateDisplay();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -535,7 +535,7 @@ void GPU::TextureConfig::SetFromPageAttribute(u16 value)
|
|||
if (page_attribute == value)
|
||||
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));
|
||||
page_attribute = value;
|
||||
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)
|
||||
{
|
||||
ss << "#version 330 core\n\n";
|
||||
ss << "const vec2 vram_size = vec2(float(" << VRAM_WIDTH << "), float(" << VRAM_HEIGHT << "));\n";
|
||||
ss << "const vec2 rcp_vram_size = vec2(1.0, 1.0) / vram_size;\n";
|
||||
ss << "const ivec2 VRAM_SIZE = ivec2(" << VRAM_WIDTH << ", " << VRAM_HEIGHT << ");\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"(
|
||||
|
||||
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)
|
||||
|
@ -179,7 +185,7 @@ void main()
|
|||
|
||||
v_col0 = a_col0;
|
||||
#if TEXTURED
|
||||
v_tex0 = vec2(a_tex0 * u_tex_scale);
|
||||
v_tex0 = a_tex0;
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
|
@ -255,10 +261,10 @@ std::string GPU_HW::GenerateTexturePageFragmentShader(TextureColorMode mode)
|
|||
|
||||
ss << R"(
|
||||
uniform sampler2D samp0;
|
||||
uniform vec2 base_offset;
|
||||
uniform ivec2 base_offset;
|
||||
|
||||
#if PALETTE
|
||||
uniform vec2 palette_offset;
|
||||
uniform ivec2 palette_offset;
|
||||
#endif
|
||||
|
||||
in vec2 v_tex0;
|
||||
|
@ -266,33 +272,32 @@ out vec4 o_col0;
|
|||
|
||||
void main()
|
||||
{
|
||||
ivec2 local_coords = ivec2(gl_FragCoord.xy);
|
||||
#if PALETTE_4_BIT
|
||||
vec2 local_coords = vec2(v_tex0.x / 4.0, v_tex0.y);
|
||||
local_coords.x /= 4;
|
||||
#elif PALETTE_8_BIT
|
||||
vec2 local_coords = vec2(v_tex0.x / 2.0, v_tex0.y);
|
||||
#else
|
||||
vec2 local_coords = v_tex0;
|
||||
local_coords.x /= 2;
|
||||
#endif
|
||||
|
||||
// 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
|
||||
vec4 color = texture(samp0, coords);
|
||||
vec4 color = texelFetch(samp0, coords & VRAM_COORD_MASK, 0);
|
||||
|
||||
// apply palette
|
||||
#if PALETTE
|
||||
#if PALETTE_4_BIT
|
||||
uint subpixel = uint(gl_FragCoord.x) & 3u;
|
||||
int subpixel = int(gl_FragCoord.x) & 3;
|
||||
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
|
||||
// TODO: Still has precision issues here
|
||||
uint subpixel = uint(gl_FragCoord.x) & 1u;
|
||||
float palette_index = ((subpixel == 0u) ? color.x : color.y) * (255.0 * rcp_vram_size.x);
|
||||
int subpixel = int(gl_FragCoord.x) & 1;
|
||||
uint vram_value = RGBA8ToRGBA5551(color);
|
||||
int palette_index = int((vram_value >> (subpixel * 8)) & 0xFFu);
|
||||
#endif
|
||||
vec2 palette_coords = vec2(palette_offset.x + palette_index, fixYCoord(palette_offset.y));
|
||||
color = texture(samp0, palette_coords);
|
||||
ivec2 palette_coords = ivec2(palette_offset.x + palette_index, fixYCoord(palette_offset.y));
|
||||
color = texelFetch(samp0, palette_coords & VRAM_COORD_MASK, 0);
|
||||
#endif
|
||||
|
||||
o_col0 = color;
|
||||
|
|
|
@ -151,9 +151,8 @@ bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, bool textured, bool blendi
|
|||
if (textured)
|
||||
{
|
||||
prog.Bind();
|
||||
prog.RegisterUniform("u_tex_scale");
|
||||
prog.RegisterUniform("samp0");
|
||||
prog.Uniform1i(1, 0);
|
||||
prog.Uniform1i(0, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -165,27 +164,7 @@ void GPU_HW_OpenGL::SetProgram(bool textured, bool blending)
|
|||
prog.Bind();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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)];
|
||||
prog.Bind();
|
||||
|
||||
const float base_x = static_cast<float>(m_texture_config.base_x) * (1.0f / static_cast<float>(VRAM_WIDTH));
|
||||
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);
|
||||
|
||||
prog.Uniform2i(1, m_texture_config.base_x, m_texture_config.base_y);
|
||||
if (m_texture_config.color_mode >= GPU::TextureColorMode::Palette4Bit)
|
||||
{
|
||||
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);
|
||||
}
|
||||
prog.Uniform2i(2, m_texture_config.palette_x, m_texture_config.palette_y);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
|
|
Loading…
Reference in a new issue