diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/pica.h | 11 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/vertex_shader.cpp | 5 |
3 files changed, 32 insertions, 27 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index e4a5ef78e..d03b811d3 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -39,13 +39,6 @@ namespace Pica { struct Regs { -// helper macro to properly align structure members. -// Calling INSERT_PADDING_WORDS will add a new member variable with a name like "pad121", -// depending on the current source line to make sure variable names are unique. -#define INSERT_PADDING_WORDS_HELPER1(x, y) x ## y -#define INSERT_PADDING_WORDS_HELPER2(x, y) INSERT_PADDING_WORDS_HELPER1(x, y) -#define INSERT_PADDING_WORDS(num_words) u32 INSERT_PADDING_WORDS_HELPER2(pad, __LINE__)[(num_words)]; - INSERT_PADDING_WORDS(0x10); u32 trigger_irq; @@ -709,10 +702,6 @@ struct Regs { INSERT_PADDING_WORDS(0x22); -#undef INSERT_PADDING_WORDS_HELPER1 -#undef INSERT_PADDING_WORDS_HELPER2 -#undef INSERT_PADDING_WORDS - // Map register indices to names readable by humans // Used for debugging purposes, so performance is not an issue here static std::string GetCommandName(int index) { diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 94873f406..17f8f70ca 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -20,7 +20,7 @@ namespace Rasterizer { static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { const PAddr addr = registers.framebuffer.GetColorBufferPhysicalAddress(); - u32* color_buffer = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(addr))); + u8* color_buffer = Memory::GetPointer(PAddrToVAddr(addr)); // Similarly to textures, the render framebuffer is laid out from bottom to top, too. // NOTE: The framebuffer height register contains the actual FB height minus one. @@ -29,8 +29,11 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { switch (registers.framebuffer.color_format) { case registers.framebuffer.RGBA8: { - u32 value = (color.a() << 24) | (color.r() << 16) | (color.g() << 8) | color.b(); - *(color_buffer + x + y * registers.framebuffer.GetWidth()) = value; + u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 4; + pixel[3] = color.r(); + pixel[2] = color.g(); + pixel[1] = color.b(); + pixel[0] = color.a(); break; } @@ -42,17 +45,27 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { static const Math::Vec4<u8> GetPixel(int x, int y) { const PAddr addr = registers.framebuffer.GetColorBufferPhysicalAddress(); - u32* color_buffer_u32 = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(addr))); + u8* color_buffer = Memory::GetPointer(PAddrToVAddr(addr)); y = (registers.framebuffer.height - y); - u32 value = *(color_buffer_u32 + x + y * registers.framebuffer.GetWidth()); - Math::Vec4<u8> ret; - ret.a() = value >> 24; - ret.r() = (value >> 16) & 0xFF; - ret.g() = (value >> 8) & 0xFF; - ret.b() = value & 0xFF; - return ret; + switch (registers.framebuffer.color_format) { + case registers.framebuffer.RGBA8: + { + Math::Vec4<u8> ret; + u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 4; + ret.r() = pixel[3]; + ret.g() = pixel[2]; + ret.b() = pixel[1]; + ret.a() = pixel[0]; + return ret; + } + default: + LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); + UNIMPLEMENTED(); + } + + return {}; } static u32 GetDepth(int x, int y) { @@ -266,10 +279,10 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, case Regs::TextureConfig::MirroredRepeat: { - int val = (int)((unsigned)val % (2 * size)); - if (val >= size) - val = 2 * size - 1 - val; - return val; + int coord = (int)((unsigned)val % (2 * size)); + if (coord >= size) + coord = 2 * size - 1 - coord; + return coord; } default: diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index def868ac7..bc8c0041c 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp @@ -90,6 +90,7 @@ struct VertexShaderState { u8 repeat_counter; // How often to repeat until this call stack element is removed u8 loop_increment; // Which value to add to the loop counter after an iteration // TODO: Should this be a signed value? Does it even matter? + u32 loop_address; // The address where we'll return to after each loop iteration }; // TODO: Is there a maximal size for this? @@ -115,6 +116,8 @@ static void ProcessShaderCode(VertexShaderState& state) { if (top.repeat_counter-- == 0) { state.program_counter = &shader_memory[top.return_address]; state.call_stack.pop(); + } else { + state.program_counter = &shader_memory[top.loop_address]; } // TODO: Is "trying again" accurate to hardware? @@ -129,7 +132,7 @@ static void ProcessShaderCode(VertexShaderState& state) { static auto call = [](VertexShaderState& state, u32 offset, u32 num_instructions, u32 return_offset, u8 repeat_count, u8 loop_increment) { state.program_counter = &shader_memory[offset] - 1; // -1 to make sure when incrementing the PC we end up at the correct offset - state.call_stack.push({ offset + num_instructions, return_offset, repeat_count, loop_increment }); + state.call_stack.push({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset }); }; u32 binary_offset = state.program_counter - shader_memory.data(); |
