11 changed files with 503 additions and 457 deletions
-
24src/citra_qt/debugger/graphics/graphics_surface.cpp
-
1src/video_core/CMakeLists.txt
-
270src/video_core/pica.h
-
229src/video_core/rasterizer.cpp
-
282src/video_core/regs_framebuffer.h
-
101src/video_core/renderer_opengl/gl_rasterizer.cpp
-
8src/video_core/renderer_opengl/gl_rasterizer.h
-
13src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
-
6src/video_core/renderer_opengl/gl_rasterizer_cache.h
-
8src/video_core/renderer_opengl/gl_shader_gen.cpp
-
10src/video_core/renderer_opengl/pica_to_gl.h
@ -0,0 +1,282 @@ |
|||
// Copyright 2017 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include "common/bit_field.h" |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace Pica { |
|||
|
|||
struct FramebufferRegs { |
|||
enum class LogicOp : u32 { |
|||
Clear = 0, |
|||
And = 1, |
|||
AndReverse = 2, |
|||
Copy = 3, |
|||
Set = 4, |
|||
CopyInverted = 5, |
|||
NoOp = 6, |
|||
Invert = 7, |
|||
Nand = 8, |
|||
Or = 9, |
|||
Nor = 10, |
|||
Xor = 11, |
|||
Equiv = 12, |
|||
AndInverted = 13, |
|||
OrReverse = 14, |
|||
OrInverted = 15, |
|||
}; |
|||
|
|||
enum class BlendEquation : u32 { |
|||
Add = 0, |
|||
Subtract = 1, |
|||
ReverseSubtract = 2, |
|||
Min = 3, |
|||
Max = 4, |
|||
}; |
|||
|
|||
enum class BlendFactor : u32 { |
|||
Zero = 0, |
|||
One = 1, |
|||
SourceColor = 2, |
|||
OneMinusSourceColor = 3, |
|||
DestColor = 4, |
|||
OneMinusDestColor = 5, |
|||
SourceAlpha = 6, |
|||
OneMinusSourceAlpha = 7, |
|||
DestAlpha = 8, |
|||
OneMinusDestAlpha = 9, |
|||
ConstantColor = 10, |
|||
OneMinusConstantColor = 11, |
|||
ConstantAlpha = 12, |
|||
OneMinusConstantAlpha = 13, |
|||
SourceAlphaSaturate = 14, |
|||
}; |
|||
|
|||
enum class CompareFunc : u32 { |
|||
Never = 0, |
|||
Always = 1, |
|||
Equal = 2, |
|||
NotEqual = 3, |
|||
LessThan = 4, |
|||
LessThanOrEqual = 5, |
|||
GreaterThan = 6, |
|||
GreaterThanOrEqual = 7, |
|||
}; |
|||
|
|||
enum class StencilAction : u32 { |
|||
Keep = 0, |
|||
Zero = 1, |
|||
Replace = 2, |
|||
Increment = 3, |
|||
Decrement = 4, |
|||
Invert = 5, |
|||
IncrementWrap = 6, |
|||
DecrementWrap = 7, |
|||
}; |
|||
|
|||
struct { |
|||
union { |
|||
// If false, logic blending is used |
|||
BitField<8, 1, u32> alphablend_enable; |
|||
}; |
|||
|
|||
union { |
|||
BitField<0, 8, BlendEquation> blend_equation_rgb; |
|||
BitField<8, 8, BlendEquation> blend_equation_a; |
|||
|
|||
BitField<16, 4, BlendFactor> factor_source_rgb; |
|||
BitField<20, 4, BlendFactor> factor_dest_rgb; |
|||
|
|||
BitField<24, 4, BlendFactor> factor_source_a; |
|||
BitField<28, 4, BlendFactor> factor_dest_a; |
|||
} alpha_blending; |
|||
|
|||
union { |
|||
BitField<0, 4, LogicOp> logic_op; |
|||
}; |
|||
|
|||
union { |
|||
u32 raw; |
|||
BitField<0, 8, u32> r; |
|||
BitField<8, 8, u32> g; |
|||
BitField<16, 8, u32> b; |
|||
BitField<24, 8, u32> a; |
|||
} blend_const; |
|||
|
|||
union { |
|||
BitField<0, 1, u32> enable; |
|||
BitField<4, 3, CompareFunc> func; |
|||
BitField<8, 8, u32> ref; |
|||
} alpha_test; |
|||
|
|||
struct { |
|||
union { |
|||
// Raw value of this register |
|||
u32 raw_func; |
|||
|
|||
// If true, enable stencil testing |
|||
BitField<0, 1, u32> enable; |
|||
|
|||
// Comparison operation for stencil testing |
|||
BitField<4, 3, CompareFunc> func; |
|||
|
|||
// Mask used to control writing to the stencil buffer |
|||
BitField<8, 8, u32> write_mask; |
|||
|
|||
// Value to compare against for stencil testing |
|||
BitField<16, 8, u32> reference_value; |
|||
|
|||
// Mask to apply on stencil test inputs |
|||
BitField<24, 8, u32> input_mask; |
|||
}; |
|||
|
|||
union { |
|||
// Raw value of this register |
|||
u32 raw_op; |
|||
|
|||
// Action to perform when the stencil test fails |
|||
BitField<0, 3, StencilAction> action_stencil_fail; |
|||
|
|||
// Action to perform when stencil testing passed but depth testing fails |
|||
BitField<4, 3, StencilAction> action_depth_fail; |
|||
|
|||
// Action to perform when both stencil and depth testing pass |
|||
BitField<8, 3, StencilAction> action_depth_pass; |
|||
}; |
|||
} stencil_test; |
|||
|
|||
union { |
|||
BitField<0, 1, u32> depth_test_enable; |
|||
BitField<4, 3, CompareFunc> depth_test_func; |
|||
BitField<8, 1, u32> red_enable; |
|||
BitField<9, 1, u32> green_enable; |
|||
BitField<10, 1, u32> blue_enable; |
|||
BitField<11, 1, u32> alpha_enable; |
|||
BitField<12, 1, u32> depth_write_enable; |
|||
}; |
|||
|
|||
INSERT_PADDING_WORDS(0x8); |
|||
} output_merger; |
|||
|
|||
// Components are laid out in reverse byte order, most significant bits first. |
|||
enum class ColorFormat : u32 { |
|||
RGBA8 = 0, |
|||
RGB8 = 1, |
|||
RGB5A1 = 2, |
|||
RGB565 = 3, |
|||
RGBA4 = 4, |
|||
}; |
|||
|
|||
enum class DepthFormat : u32 { |
|||
D16 = 0, |
|||
D24 = 2, |
|||
D24S8 = 3, |
|||
}; |
|||
|
|||
// Returns the number of bytes in the specified color format |
|||
static unsigned BytesPerColorPixel(ColorFormat format) { |
|||
switch (format) { |
|||
case ColorFormat::RGBA8: |
|||
return 4; |
|||
case ColorFormat::RGB8: |
|||
return 3; |
|||
case ColorFormat::RGB5A1: |
|||
case ColorFormat::RGB565: |
|||
case ColorFormat::RGBA4: |
|||
return 2; |
|||
default: |
|||
LOG_CRITICAL(HW_GPU, "Unknown color format %u", format); |
|||
UNIMPLEMENTED(); |
|||
} |
|||
} |
|||
|
|||
struct FramebufferConfig { |
|||
INSERT_PADDING_WORDS(0x3); |
|||
|
|||
union { |
|||
BitField<0, 4, u32> allow_color_write; // 0 = disable, else enable |
|||
}; |
|||
|
|||
INSERT_PADDING_WORDS(0x1); |
|||
|
|||
union { |
|||
BitField<0, 2, u32> allow_depth_stencil_write; // 0 = disable, else enable |
|||
}; |
|||
|
|||
DepthFormat depth_format; // TODO: Should be a BitField! |
|||
BitField<16, 3, ColorFormat> color_format; |
|||
|
|||
INSERT_PADDING_WORDS(0x4); |
|||
|
|||
u32 depth_buffer_address; |
|||
u32 color_buffer_address; |
|||
|
|||
union { |
|||
// Apparently, the framebuffer width is stored as expected, |
|||
// while the height is stored as the actual height minus one. |
|||
// Hence, don't access these fields directly but use the accessors |
|||
// GetWidth() and GetHeight() instead. |
|||
BitField<0, 11, u32> width; |
|||
BitField<12, 10, u32> height; |
|||
}; |
|||
|
|||
INSERT_PADDING_WORDS(0x1); |
|||
|
|||
inline PAddr GetColorBufferPhysicalAddress() const { |
|||
return color_buffer_address * 8; |
|||
} |
|||
inline PAddr GetDepthBufferPhysicalAddress() const { |
|||
return depth_buffer_address * 8; |
|||
} |
|||
|
|||
inline u32 GetWidth() const { |
|||
return width; |
|||
} |
|||
|
|||
inline u32 GetHeight() const { |
|||
return height + 1; |
|||
} |
|||
} framebuffer; |
|||
|
|||
// Returns the number of bytes in the specified depth format |
|||
static u32 BytesPerDepthPixel(DepthFormat format) { |
|||
switch (format) { |
|||
case DepthFormat::D16: |
|||
return 2; |
|||
case DepthFormat::D24: |
|||
return 3; |
|||
case DepthFormat::D24S8: |
|||
return 4; |
|||
default: |
|||
LOG_CRITICAL(HW_GPU, "Unknown depth format %u", format); |
|||
UNIMPLEMENTED(); |
|||
} |
|||
} |
|||
|
|||
// Returns the number of bits per depth component of the specified depth format |
|||
static u32 DepthBitsPerPixel(DepthFormat format) { |
|||
switch (format) { |
|||
case DepthFormat::D16: |
|||
return 16; |
|||
case DepthFormat::D24: |
|||
case DepthFormat::D24S8: |
|||
return 24; |
|||
default: |
|||
LOG_CRITICAL(HW_GPU, "Unknown depth format %u", format); |
|||
UNIMPLEMENTED(); |
|||
} |
|||
} |
|||
|
|||
INSERT_PADDING_WORDS(0x20); |
|||
}; |
|||
|
|||
static_assert(sizeof(FramebufferRegs) == 0x40 * sizeof(u32), |
|||
"FramebufferRegs struct has incorrect size"); |
|||
|
|||
} // namespace Pica |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue