aboutsummaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/pica.h11
-rw-r--r--src/video_core/rasterizer.cpp43
-rw-r--r--src/video_core/vertex_shader.cpp5
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();