GPU: Implement texture window
This commit is contained in:
parent
f59d35023c
commit
bc8e035e37
|
@ -73,9 +73,11 @@ bool GPU::DoState(StateWrapper& sw)
|
|||
sw.Do(&m_render_state.texture_y_flip);
|
||||
sw.Do(&m_render_state.texpage_attribute);
|
||||
sw.Do(&m_render_state.texlut_attribute);
|
||||
sw.Do(&m_render_state.texture_window_value);
|
||||
sw.Do(&m_render_state.texture_page_changed);
|
||||
sw.Do(&m_render_state.texture_color_mode_changed);
|
||||
sw.Do(&m_render_state.transparency_mode_changed);
|
||||
sw.Do(&m_render_state.texture_window_changed);
|
||||
|
||||
sw.Do(&m_drawing_area.left);
|
||||
sw.Do(&m_drawing_area.top);
|
||||
|
@ -113,6 +115,7 @@ bool GPU::DoState(StateWrapper& sw)
|
|||
m_render_state.texture_page_changed = true;
|
||||
m_render_state.texture_color_mode_changed = true;
|
||||
m_render_state.transparency_mode_changed = true;
|
||||
m_render_state.texture_window_changed = true;
|
||||
UpdateGPUSTAT();
|
||||
}
|
||||
|
||||
|
@ -437,10 +440,7 @@ void GPU::WriteGP0(u32 value)
|
|||
|
||||
case 0xE2: // set texture window
|
||||
{
|
||||
m_render_state.texture_window_mask_x = param & UINT32_C(0x1F);
|
||||
m_render_state.texture_window_mask_y = (param >> 5) & UINT32_C(0x1F);
|
||||
m_render_state.texture_window_offset_x = (param >> 10) & UINT32_C(0x1F);
|
||||
m_render_state.texture_window_offset_y = (param >> 15) & UINT32_C(0x1F);
|
||||
m_render_state.SetTextureWindow(value);
|
||||
Log_DebugPrintf("Set texture window %02X %02X %02X %02X", m_render_state.texture_window_mask_x,
|
||||
m_render_state.texture_window_mask_y, m_render_state.texture_window_offset_x,
|
||||
m_render_state.texture_window_offset_y);
|
||||
|
@ -895,6 +895,20 @@ void GPU::RenderState::SetFromPaletteAttribute(u16 value)
|
|||
texture_page_changed = true;
|
||||
}
|
||||
|
||||
void GPU::RenderState::SetTextureWindow(u32 value)
|
||||
{
|
||||
value &= TEXTURE_WINDOW_MASK;
|
||||
if (texture_window_value == value)
|
||||
return;
|
||||
|
||||
texture_window_mask_x = value & UINT32_C(0x1F);
|
||||
texture_window_mask_y = (value >> 5) & UINT32_C(0x1F);
|
||||
texture_window_offset_x = (value >> 10) & UINT32_C(0x1F);
|
||||
texture_window_offset_y = (value >> 15) & UINT32_C(0x1F);
|
||||
texture_window_value = value;
|
||||
texture_window_changed = true;
|
||||
}
|
||||
|
||||
bool GPU::DumpVRAMToFile(const char* filename, u32 width, u32 height, u32 stride, const void* buffer, bool remove_alpha)
|
||||
{
|
||||
std::vector<u32> rgba8_buf(width * height);
|
||||
|
|
|
@ -240,6 +240,7 @@ protected:
|
|||
static constexpr u16 PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111);
|
||||
static constexpr u16 PAGE_ATTRIBUTE_MASK = UINT16_C(0b0000000111111111);
|
||||
static constexpr u16 PALETTE_ATTRIBUTE_MASK = UINT16_C(0b0111111111111111);
|
||||
static constexpr u32 TEXTURE_WINDOW_MASK = UINT16_C(0b11111111111111111111);
|
||||
|
||||
// decoded values
|
||||
u32 texture_page_x;
|
||||
|
@ -258,10 +259,12 @@ protected:
|
|||
// original values
|
||||
u16 texpage_attribute; // from register in rectangle modes/vertex in polygon modes
|
||||
u16 texlut_attribute; // from vertex
|
||||
u32 texture_window_value;
|
||||
|
||||
bool texture_page_changed = false;
|
||||
bool texture_color_mode_changed = false;
|
||||
bool transparency_mode_changed = false;
|
||||
bool texture_window_changed = false;
|
||||
|
||||
bool IsChanged() const { return texture_page_changed || texture_color_mode_changed || transparency_mode_changed; }
|
||||
|
||||
|
@ -274,11 +277,15 @@ protected:
|
|||
bool IsTransparencyModeChanged() const { return transparency_mode_changed; }
|
||||
void ClearTransparencyModeChangedFlag() { transparency_mode_changed = false; }
|
||||
|
||||
bool IsTextureWindowChanged() const { return texture_window_changed; }
|
||||
void ClearTextureWindowChangedFlag() { texture_window_changed = false; }
|
||||
|
||||
void SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1);
|
||||
void SetFromRectangleTexcoord(u32 texcoord);
|
||||
|
||||
void SetFromPageAttribute(u16 value);
|
||||
void SetFromPaletteAttribute(u16 value);
|
||||
void SetTextureWindow(u32 value);
|
||||
} m_render_state = {};
|
||||
|
||||
struct DrawingArea
|
||||
|
|
|
@ -46,9 +46,17 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices)
|
|||
hw_vert.texpage = texpage;
|
||||
|
||||
if (textured)
|
||||
{
|
||||
hw_vert.texcoord = Truncate16(m_GP0_command[buffer_pos++]);
|
||||
// auto [u, v] = HWVertex::DecodeTexcoord(hw_vert.texcoord);
|
||||
// u = (u & (~(m_render_state.texture_window_mask_x * 8))) | ((m_render_state.texture_window_offset_x &
|
||||
// m_render_state.texture_window_mask_x) * 8); v = (v & (~(m_render_state.texture_window_mask_y * 8))) |
|
||||
// ((m_render_state.texture_window_offset_y & m_render_state.texture_window_mask_y) * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
hw_vert.texcoord = 0;
|
||||
}
|
||||
|
||||
hw_vert.padding = 0;
|
||||
|
||||
|
@ -258,15 +266,24 @@ uniform vec2 u_transparent_alpha;
|
|||
in vec2 v_tex0;
|
||||
flat in ivec4 v_texpage;
|
||||
uniform sampler2D samp0;
|
||||
uniform uvec4 u_texture_window;
|
||||
#endif
|
||||
|
||||
out vec4 o_col0;
|
||||
|
||||
#if TEXTURED
|
||||
ivec2 ApplyTextureWindow(ivec2 coords)
|
||||
{
|
||||
uint x = (uint(coords.x) & ~(u_texture_window.x * 8u)) | ((u_texture_window.z & u_texture_window.x) * 8u);
|
||||
uint y = (uint(coords.y) & ~(u_texture_window.y * 8u)) | ((u_texture_window.w & u_texture_window.y) * 8u);
|
||||
return ivec2(int(x), int(y));
|
||||
}
|
||||
|
||||
vec4 SampleFromVRAM(vec2 coord)
|
||||
{
|
||||
// from 0..1 to 0..255
|
||||
ivec2 icoord = ivec2(coord * vec2(255.0));
|
||||
icoord = ApplyTextureWindow(icoord);
|
||||
|
||||
// adjust for tightly packed palette formats
|
||||
ivec2 index_coord = icoord;
|
||||
|
@ -493,7 +510,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
|
|||
const bool restart_line_strip = (rc_primitive == HWRenderBatch::Primitive::LineStrip);
|
||||
const bool needs_flush =
|
||||
!IsFlushed() && (m_render_state.IsTextureColorModeChanged() || m_render_state.IsTransparencyModeChanged() ||
|
||||
buffer_overflow || rc_changed || restart_line_strip);
|
||||
m_render_state.IsTextureWindowChanged() || buffer_overflow || rc_changed || restart_line_strip);
|
||||
if (needs_flush)
|
||||
FlushRender();
|
||||
|
||||
|
@ -544,5 +561,14 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
|
|||
m_render_state.ClearTransparencyModeChangedFlag();
|
||||
}
|
||||
|
||||
if (m_render_state.IsTextureWindowChanged())
|
||||
{
|
||||
m_batch.texture_window_values[0] = m_render_state.texture_window_mask_x;
|
||||
m_batch.texture_window_values[1] = m_render_state.texture_window_mask_y;
|
||||
m_batch.texture_window_values[2] = m_render_state.texture_window_offset_x;
|
||||
m_batch.texture_window_values[3] = m_render_state.texture_window_offset_y;
|
||||
m_render_state.ClearTextureWindowChangedFlag();
|
||||
}
|
||||
|
||||
LoadVertices(rc, num_vertices);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
|||
u32 texture_palette_x;
|
||||
u32 texture_palette_y;
|
||||
TransparencyMode transparency_mode;
|
||||
std::array<u8, 4> texture_window_values;
|
||||
|
||||
std::vector<HWVertex> vertices;
|
||||
};
|
||||
|
|
|
@ -358,8 +358,9 @@ bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, bool transparent, bool tex
|
|||
|
||||
if (textured)
|
||||
{
|
||||
prog.RegisterUniform("u_texture_window");
|
||||
prog.RegisterUniform("samp0");
|
||||
prog.Uniform1i(2, 0);
|
||||
prog.Uniform1i(3, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -385,7 +386,11 @@ void GPU_HW_OpenGL::SetDrawState()
|
|||
}
|
||||
|
||||
if (m_batch.texture_enable)
|
||||
{
|
||||
prog.Uniform4ui(2, m_batch.texture_window_values[0], m_batch.texture_window_values[1],
|
||||
m_batch.texture_window_values[2], m_batch.texture_window_values[3]);
|
||||
m_vram_read_texture->Bind();
|
||||
}
|
||||
|
||||
if (m_last_transparency_enable != m_batch.transparency_enable ||
|
||||
(m_last_transparency_enable && m_last_transparency_mode != m_batch.transparency_mode))
|
||||
|
|
Loading…
Reference in New Issue