diff options
| author | 2017-01-27 20:16:36 -0800 | |
|---|---|---|
| committer | 2017-02-04 13:08:47 -0800 | |
| commit | 000e78144ce87d0be1749f26b9d0494d3c4ddf2f (patch) | |
| tree | ab7180a99b8289dff4b2ee96f7675816e5cc0d2b /src/video_core | |
| parent | Merge pull request #2476 from yuriks/shader-refactor3 (diff) | |
| download | yuzu-000e78144ce87d0be1749f26b9d0494d3c4ddf2f.tar.gz yuzu-000e78144ce87d0be1749f26b9d0494d3c4ddf2f.tar.xz yuzu-000e78144ce87d0be1749f26b9d0494d3c4ddf2f.zip | |
VideoCore: Split rasterizer regs from Regs struct
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/clipper.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.h | 2 | ||||
| -rw-r--r-- | src/video_core/pica.h | 137 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/regs_rasterizer.h | 129 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 54 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/shader/shader.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/shader.h | 18 |
13 files changed, 218 insertions, 187 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index ad984cd94..522d7cc13 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -32,6 +32,7 @@ set(HEADERS | |||
| 32 | primitive_assembly.h | 32 | primitive_assembly.h |
| 33 | rasterizer.h | 33 | rasterizer.h |
| 34 | rasterizer_interface.h | 34 | rasterizer_interface.h |
| 35 | regs_rasterizer.h | ||
| 35 | renderer_base.h | 36 | renderer_base.h |
| 36 | renderer_opengl/gl_rasterizer.h | 37 | renderer_opengl/gl_rasterizer.h |
| 37 | renderer_opengl/gl_rasterizer_cache.h | 38 | renderer_opengl/gl_rasterizer_cache.h |
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp index 0774ffc53..59fc5c86b 100644 --- a/src/video_core/clipper.cpp +++ b/src/video_core/clipper.cpp | |||
| @@ -64,10 +64,10 @@ static void InitScreenCoordinates(Vertex& vtx) { | |||
| 64 | } viewport; | 64 | } viewport; |
| 65 | 65 | ||
| 66 | const auto& regs = g_state.regs; | 66 | const auto& regs = g_state.regs; |
| 67 | viewport.halfsize_x = float24::FromRaw(regs.viewport_size_x); | 67 | viewport.halfsize_x = float24::FromRaw(regs.rasterizer.viewport_size_x); |
| 68 | viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y); | 68 | viewport.halfsize_y = float24::FromRaw(regs.rasterizer.viewport_size_y); |
| 69 | viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x)); | 69 | viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.rasterizer.viewport_corner.x)); |
| 70 | viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y)); | 70 | viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.rasterizer.viewport_corner.y)); |
| 71 | 71 | ||
| 72 | float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; | 72 | float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; |
| 73 | vtx.color *= inv_w; | 73 | vtx.color *= inv_w; |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 4955ff9f9..b4a9f23cf 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -165,7 +165,8 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| 167 | g_state.primitive_assembler.SubmitVertex( | 167 | g_state.primitive_assembler.SubmitVertex( |
| 168 | Shader::OutputVertex::FromAttributeBuffer(regs, output), AddTriangle); | 168 | Shader::OutputVertex::FromAttributeBuffer(regs.rasterizer, output), |
| 169 | AddTriangle); | ||
| 169 | } | 170 | } |
| 170 | } | 171 | } |
| 171 | } | 172 | } |
| @@ -295,7 +296,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 295 | shader_unit.WriteOutput(regs.vs, output); | 296 | shader_unit.WriteOutput(regs.vs, output); |
| 296 | 297 | ||
| 297 | // Retrieve vertex from register data | 298 | // Retrieve vertex from register data |
| 298 | output_vertex = Shader::OutputVertex::FromAttributeBuffer(regs, output); | 299 | output_vertex = Shader::OutputVertex::FromAttributeBuffer(regs.rasterizer, output); |
| 299 | 300 | ||
| 300 | if (is_indexed) { | 301 | if (is_indexed) { |
| 301 | vertex_cache[vertex_cache_pos] = output_vertex; | 302 | vertex_cache[vertex_cache_pos] = output_vertex; |
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 2d40f7d4f..618268654 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -90,7 +90,7 @@ namespace DebugUtils { | |||
| 90 | 90 | ||
| 91 | void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, | 91 | void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, |
| 92 | const Shader::ShaderSetup& setup, | 92 | const Shader::ShaderSetup& setup, |
| 93 | const Regs::VSOutputAttributes* output_attributes) { | 93 | const RasterizerRegs::VSOutputAttributes* output_attributes) { |
| 94 | struct StuffToWrite { | 94 | struct StuffToWrite { |
| 95 | const u8* pointer; | 95 | const u8* pointer; |
| 96 | u32 size; | 96 | u32 size; |
| @@ -129,7 +129,7 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, | |||
| 129 | // This is put into a try-catch block to make sure we notice unknown configurations. | 129 | // This is put into a try-catch block to make sure we notice unknown configurations. |
| 130 | std::vector<OutputRegisterInfo> output_info_table; | 130 | std::vector<OutputRegisterInfo> output_info_table; |
| 131 | for (unsigned i = 0; i < 7; ++i) { | 131 | for (unsigned i = 0; i < 7; ++i) { |
| 132 | using OutputAttributes = Pica::Regs::VSOutputAttributes; | 132 | using OutputAttributes = Pica::RasterizerRegs::VSOutputAttributes; |
| 133 | 133 | ||
| 134 | // TODO: It's still unclear how the attribute components map to the register! | 134 | // TODO: It's still unclear how the attribute components map to the register! |
| 135 | // Once we know that, this code probably will not make much sense anymore. | 135 | // Once we know that, this code probably will not make much sense anymore. |
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 938a2e1b5..51270bc9c 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h | |||
| @@ -184,7 +184,7 @@ namespace DebugUtils { | |||
| 184 | 184 | ||
| 185 | void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, | 185 | void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, |
| 186 | const Shader::ShaderSetup& setup, | 186 | const Shader::ShaderSetup& setup, |
| 187 | const Regs::VSOutputAttributes* output_attributes); | 187 | const RasterizerRegs::VSOutputAttributes* output_attributes); |
| 188 | 188 | ||
| 189 | // Utility class to log Pica commands. | 189 | // Utility class to log Pica commands. |
| 190 | struct PicaTrace { | 190 | struct PicaTrace { |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 731540b99..9d7262b43 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "common/common_types.h" | 18 | #include "common/common_types.h" |
| 19 | #include "common/logging/log.h" | 19 | #include "common/logging/log.h" |
| 20 | #include "common/vector_math.h" | 20 | #include "common/vector_math.h" |
| 21 | #include "video_core/regs_rasterizer.h" | ||
| 21 | 22 | ||
| 22 | namespace Pica { | 23 | namespace Pica { |
| 23 | 24 | ||
| @@ -44,121 +45,10 @@ namespace Pica { | |||
| 44 | #endif // _MSC_VER | 45 | #endif // _MSC_VER |
| 45 | 46 | ||
| 46 | struct Regs { | 47 | struct Regs { |
| 47 | |||
| 48 | INSERT_PADDING_WORDS(0x10); | 48 | INSERT_PADDING_WORDS(0x10); |
| 49 | |||
| 50 | u32 trigger_irq; | 49 | u32 trigger_irq; |
| 51 | |||
| 52 | INSERT_PADDING_WORDS(0x2f); | 50 | INSERT_PADDING_WORDS(0x2f); |
| 53 | 51 | RasterizerRegs rasterizer; | |
| 54 | enum class CullMode : u32 { | ||
| 55 | // Select which polygons are considered to be "frontfacing". | ||
| 56 | KeepAll = 0, | ||
| 57 | KeepClockWise = 1, | ||
| 58 | KeepCounterClockWise = 2, | ||
| 59 | // TODO: What does the third value imply? | ||
| 60 | }; | ||
| 61 | |||
| 62 | union { | ||
| 63 | BitField<0, 2, CullMode> cull_mode; | ||
| 64 | }; | ||
| 65 | |||
| 66 | BitField<0, 24, u32> viewport_size_x; | ||
| 67 | |||
| 68 | INSERT_PADDING_WORDS(0x1); | ||
| 69 | |||
| 70 | BitField<0, 24, u32> viewport_size_y; | ||
| 71 | |||
| 72 | INSERT_PADDING_WORDS(0x9); | ||
| 73 | |||
| 74 | BitField<0, 24, u32> viewport_depth_range; // float24 | ||
| 75 | BitField<0, 24, u32> viewport_depth_near_plane; // float24 | ||
| 76 | |||
| 77 | BitField<0, 3, u32> vs_output_total; | ||
| 78 | |||
| 79 | union VSOutputAttributes { | ||
| 80 | // Maps components of output vertex attributes to semantics | ||
| 81 | enum Semantic : u32 { | ||
| 82 | POSITION_X = 0, | ||
| 83 | POSITION_Y = 1, | ||
| 84 | POSITION_Z = 2, | ||
| 85 | POSITION_W = 3, | ||
| 86 | |||
| 87 | QUATERNION_X = 4, | ||
| 88 | QUATERNION_Y = 5, | ||
| 89 | QUATERNION_Z = 6, | ||
| 90 | QUATERNION_W = 7, | ||
| 91 | |||
| 92 | COLOR_R = 8, | ||
| 93 | COLOR_G = 9, | ||
| 94 | COLOR_B = 10, | ||
| 95 | COLOR_A = 11, | ||
| 96 | |||
| 97 | TEXCOORD0_U = 12, | ||
| 98 | TEXCOORD0_V = 13, | ||
| 99 | TEXCOORD1_U = 14, | ||
| 100 | TEXCOORD1_V = 15, | ||
| 101 | |||
| 102 | TEXCOORD0_W = 16, | ||
| 103 | |||
| 104 | VIEW_X = 18, | ||
| 105 | VIEW_Y = 19, | ||
| 106 | VIEW_Z = 20, | ||
| 107 | |||
| 108 | TEXCOORD2_U = 22, | ||
| 109 | TEXCOORD2_V = 23, | ||
| 110 | |||
| 111 | INVALID = 31, | ||
| 112 | }; | ||
| 113 | |||
| 114 | BitField<0, 5, Semantic> map_x; | ||
| 115 | BitField<8, 5, Semantic> map_y; | ||
| 116 | BitField<16, 5, Semantic> map_z; | ||
| 117 | BitField<24, 5, Semantic> map_w; | ||
| 118 | } vs_output_attributes[7]; | ||
| 119 | |||
| 120 | INSERT_PADDING_WORDS(0xe); | ||
| 121 | |||
| 122 | enum class ScissorMode : u32 { | ||
| 123 | Disabled = 0, | ||
| 124 | Exclude = 1, // Exclude pixels inside the scissor box | ||
| 125 | |||
| 126 | Include = 3 // Exclude pixels outside the scissor box | ||
| 127 | }; | ||
| 128 | |||
| 129 | struct { | ||
| 130 | BitField<0, 2, ScissorMode> mode; | ||
| 131 | |||
| 132 | union { | ||
| 133 | BitField<0, 16, u32> x1; | ||
| 134 | BitField<16, 16, u32> y1; | ||
| 135 | }; | ||
| 136 | |||
| 137 | union { | ||
| 138 | BitField<0, 16, u32> x2; | ||
| 139 | BitField<16, 16, u32> y2; | ||
| 140 | }; | ||
| 141 | } scissor_test; | ||
| 142 | |||
| 143 | union { | ||
| 144 | BitField<0, 10, s32> x; | ||
| 145 | BitField<16, 10, s32> y; | ||
| 146 | } viewport_corner; | ||
| 147 | |||
| 148 | INSERT_PADDING_WORDS(0x1); | ||
| 149 | |||
| 150 | // TODO: early depth | ||
| 151 | INSERT_PADDING_WORDS(0x1); | ||
| 152 | |||
| 153 | INSERT_PADDING_WORDS(0x2); | ||
| 154 | |||
| 155 | enum DepthBuffering : u32 { | ||
| 156 | WBuffering = 0, | ||
| 157 | ZBuffering = 1, | ||
| 158 | }; | ||
| 159 | BitField<0, 1, DepthBuffering> depthmap_enable; | ||
| 160 | |||
| 161 | INSERT_PADDING_WORDS(0x12); | ||
| 162 | 52 | ||
| 163 | struct TextureConfig { | 53 | struct TextureConfig { |
| 164 | enum TextureType : u32 { | 54 | enum TextureType : u32 { |
| @@ -1338,16 +1228,19 @@ private: | |||
| 1338 | "Field " #field_name " has invalid position") | 1228 | "Field " #field_name " has invalid position") |
| 1339 | 1229 | ||
| 1340 | ASSERT_REG_POSITION(trigger_irq, 0x10); | 1230 | ASSERT_REG_POSITION(trigger_irq, 0x10); |
| 1341 | ASSERT_REG_POSITION(cull_mode, 0x40); | 1231 | |
| 1342 | ASSERT_REG_POSITION(viewport_size_x, 0x41); | 1232 | ASSERT_REG_POSITION(rasterizer, 0x40); |
| 1343 | ASSERT_REG_POSITION(viewport_size_y, 0x43); | 1233 | ASSERT_REG_POSITION(rasterizer.cull_mode, 0x40); |
| 1344 | ASSERT_REG_POSITION(viewport_depth_range, 0x4d); | 1234 | ASSERT_REG_POSITION(rasterizer.viewport_size_x, 0x41); |
| 1345 | ASSERT_REG_POSITION(viewport_depth_near_plane, 0x4e); | 1235 | ASSERT_REG_POSITION(rasterizer.viewport_size_y, 0x43); |
| 1346 | ASSERT_REG_POSITION(vs_output_attributes[0], 0x50); | 1236 | ASSERT_REG_POSITION(rasterizer.viewport_depth_range, 0x4d); |
| 1347 | ASSERT_REG_POSITION(vs_output_attributes[1], 0x51); | 1237 | ASSERT_REG_POSITION(rasterizer.viewport_depth_near_plane, 0x4e); |
| 1348 | ASSERT_REG_POSITION(scissor_test, 0x65); | 1238 | ASSERT_REG_POSITION(rasterizer.vs_output_attributes[0], 0x50); |
| 1349 | ASSERT_REG_POSITION(viewport_corner, 0x68); | 1239 | ASSERT_REG_POSITION(rasterizer.vs_output_attributes[1], 0x51); |
| 1350 | ASSERT_REG_POSITION(depthmap_enable, 0x6D); | 1240 | ASSERT_REG_POSITION(rasterizer.scissor_test, 0x65); |
| 1241 | ASSERT_REG_POSITION(rasterizer.viewport_corner, 0x68); | ||
| 1242 | ASSERT_REG_POSITION(rasterizer.depthmap_enable, 0x6D); | ||
| 1243 | |||
| 1351 | ASSERT_REG_POSITION(texture0_enable, 0x80); | 1244 | ASSERT_REG_POSITION(texture0_enable, 0x80); |
| 1352 | ASSERT_REG_POSITION(texture0, 0x81); | 1245 | ASSERT_REG_POSITION(texture0, 0x81); |
| 1353 | ASSERT_REG_POSITION(texture0_format, 0x8e); | 1246 | ASSERT_REG_POSITION(texture0_format, 0x8e); |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 287d732b5..f82873480 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -327,14 +327,14 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 327 | ScreenToRasterizerCoordinates(v1.screenpos), | 327 | ScreenToRasterizerCoordinates(v1.screenpos), |
| 328 | ScreenToRasterizerCoordinates(v2.screenpos)}; | 328 | ScreenToRasterizerCoordinates(v2.screenpos)}; |
| 329 | 329 | ||
| 330 | if (regs.cull_mode == Regs::CullMode::KeepAll) { | 330 | if (regs.rasterizer.cull_mode == RasterizerRegs::CullMode::KeepAll) { |
| 331 | // Make sure we always end up with a triangle wound counter-clockwise | 331 | // Make sure we always end up with a triangle wound counter-clockwise |
| 332 | if (!reversed && SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0) { | 332 | if (!reversed && SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0) { |
| 333 | ProcessTriangleInternal(v0, v2, v1, true); | 333 | ProcessTriangleInternal(v0, v2, v1, true); |
| 334 | return; | 334 | return; |
| 335 | } | 335 | } |
| 336 | } else { | 336 | } else { |
| 337 | if (!reversed && regs.cull_mode == Regs::CullMode::KeepClockWise) { | 337 | if (!reversed && regs.rasterizer.cull_mode == RasterizerRegs::CullMode::KeepClockWise) { |
| 338 | // Reverse vertex order and use the CCW code path. | 338 | // Reverse vertex order and use the CCW code path. |
| 339 | ProcessTriangleInternal(v0, v2, v1, true); | 339 | ProcessTriangleInternal(v0, v2, v1, true); |
| 340 | return; | 340 | return; |
| @@ -351,13 +351,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 351 | u16 max_y = std::max({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); | 351 | u16 max_y = std::max({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); |
| 352 | 352 | ||
| 353 | // Convert the scissor box coordinates to 12.4 fixed point | 353 | // Convert the scissor box coordinates to 12.4 fixed point |
| 354 | u16 scissor_x1 = (u16)(regs.scissor_test.x1 << 4); | 354 | u16 scissor_x1 = (u16)(regs.rasterizer.scissor_test.x1 << 4); |
| 355 | u16 scissor_y1 = (u16)(regs.scissor_test.y1 << 4); | 355 | u16 scissor_y1 = (u16)(regs.rasterizer.scissor_test.y1 << 4); |
| 356 | // x2,y2 have +1 added to cover the entire sub-pixel area | 356 | // x2,y2 have +1 added to cover the entire sub-pixel area |
| 357 | u16 scissor_x2 = (u16)((regs.scissor_test.x2 + 1) << 4); | 357 | u16 scissor_x2 = (u16)((regs.rasterizer.scissor_test.x2 + 1) << 4); |
| 358 | u16 scissor_y2 = (u16)((regs.scissor_test.y2 + 1) << 4); | 358 | u16 scissor_y2 = (u16)((regs.rasterizer.scissor_test.y2 + 1) << 4); |
| 359 | 359 | ||
| 360 | if (regs.scissor_test.mode == Regs::ScissorMode::Include) { | 360 | if (regs.rasterizer.scissor_test.mode == RasterizerRegs::ScissorMode::Include) { |
| 361 | // Calculate the new bounds | 361 | // Calculate the new bounds |
| 362 | min_x = std::max(min_x, scissor_x1); | 362 | min_x = std::max(min_x, scissor_x1); |
| 363 | min_y = std::max(min_y, scissor_y1); | 363 | min_y = std::max(min_y, scissor_y1); |
| @@ -411,7 +411,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 411 | 411 | ||
| 412 | // Do not process the pixel if it's inside the scissor box and the scissor mode is set | 412 | // Do not process the pixel if it's inside the scissor box and the scissor mode is set |
| 413 | // to Exclude | 413 | // to Exclude |
| 414 | if (regs.scissor_test.mode == Regs::ScissorMode::Exclude) { | 414 | if (regs.rasterizer.scissor_test.mode == RasterizerRegs::ScissorMode::Exclude) { |
| 415 | if (x >= scissor_x1 && x < scissor_x2 && y >= scissor_y1 && y < scissor_y2) | 415 | if (x >= scissor_x1 && x < scissor_x2 && y >= scissor_y1 && y < scissor_y2) |
| 416 | continue; | 416 | continue; |
| 417 | } | 417 | } |
| @@ -441,12 +441,14 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 441 | 441 | ||
| 442 | // Not fully accurate. About 3 bits in precision are missing. | 442 | // Not fully accurate. About 3 bits in precision are missing. |
| 443 | // Z-Buffer (z / w * scale + offset) | 443 | // Z-Buffer (z / w * scale + offset) |
| 444 | float depth_scale = float24::FromRaw(regs.viewport_depth_range).ToFloat32(); | 444 | float depth_scale = float24::FromRaw(regs.rasterizer.viewport_depth_range).ToFloat32(); |
| 445 | float depth_offset = float24::FromRaw(regs.viewport_depth_near_plane).ToFloat32(); | 445 | float depth_offset = |
| 446 | float24::FromRaw(regs.rasterizer.viewport_depth_near_plane).ToFloat32(); | ||
| 446 | float depth = interpolated_z_over_w * depth_scale + depth_offset; | 447 | float depth = interpolated_z_over_w * depth_scale + depth_offset; |
| 447 | 448 | ||
| 448 | // Potentially switch to W-Buffer | 449 | // Potentially switch to W-Buffer |
| 449 | if (regs.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { | 450 | if (regs.rasterizer.depthmap_enable == |
| 451 | Pica::RasterizerRegs::DepthBuffering::WBuffering) { | ||
| 450 | // W-Buffer (z * scale + w * offset = (z / w * scale + offset) * w) | 452 | // W-Buffer (z * scale + w * offset = (z / w * scale + offset) * w) |
| 451 | depth *= interpolated_w_inverse.ToFloat32() * wsum; | 453 | depth *= interpolated_w_inverse.ToFloat32() * wsum; |
| 452 | } | 454 | } |
diff --git a/src/video_core/regs_rasterizer.h b/src/video_core/regs_rasterizer.h new file mode 100644 index 000000000..a471a3b38 --- /dev/null +++ b/src/video_core/regs_rasterizer.h | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | |||
| 9 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_funcs.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | |||
| 13 | namespace Pica { | ||
| 14 | |||
| 15 | struct RasterizerRegs { | ||
| 16 | enum class CullMode : u32 { | ||
| 17 | // Select which polygons are considered to be "frontfacing". | ||
| 18 | KeepAll = 0, | ||
| 19 | KeepClockWise = 1, | ||
| 20 | KeepCounterClockWise = 2, | ||
| 21 | // TODO: What does the third value imply? | ||
| 22 | }; | ||
| 23 | |||
| 24 | union { | ||
| 25 | BitField<0, 2, CullMode> cull_mode; | ||
| 26 | }; | ||
| 27 | |||
| 28 | BitField<0, 24, u32> viewport_size_x; | ||
| 29 | |||
| 30 | INSERT_PADDING_WORDS(0x1); | ||
| 31 | |||
| 32 | BitField<0, 24, u32> viewport_size_y; | ||
| 33 | |||
| 34 | INSERT_PADDING_WORDS(0x9); | ||
| 35 | |||
| 36 | BitField<0, 24, u32> viewport_depth_range; // float24 | ||
| 37 | BitField<0, 24, u32> viewport_depth_near_plane; // float24 | ||
| 38 | |||
| 39 | BitField<0, 3, u32> vs_output_total; | ||
| 40 | |||
| 41 | union VSOutputAttributes { | ||
| 42 | // Maps components of output vertex attributes to semantics | ||
| 43 | enum Semantic : u32 { | ||
| 44 | POSITION_X = 0, | ||
| 45 | POSITION_Y = 1, | ||
| 46 | POSITION_Z = 2, | ||
| 47 | POSITION_W = 3, | ||
| 48 | |||
| 49 | QUATERNION_X = 4, | ||
| 50 | QUATERNION_Y = 5, | ||
| 51 | QUATERNION_Z = 6, | ||
| 52 | QUATERNION_W = 7, | ||
| 53 | |||
| 54 | COLOR_R = 8, | ||
| 55 | COLOR_G = 9, | ||
| 56 | COLOR_B = 10, | ||
| 57 | COLOR_A = 11, | ||
| 58 | |||
| 59 | TEXCOORD0_U = 12, | ||
| 60 | TEXCOORD0_V = 13, | ||
| 61 | TEXCOORD1_U = 14, | ||
| 62 | TEXCOORD1_V = 15, | ||
| 63 | |||
| 64 | TEXCOORD0_W = 16, | ||
| 65 | |||
| 66 | VIEW_X = 18, | ||
| 67 | VIEW_Y = 19, | ||
| 68 | VIEW_Z = 20, | ||
| 69 | |||
| 70 | TEXCOORD2_U = 22, | ||
| 71 | TEXCOORD2_V = 23, | ||
| 72 | |||
| 73 | INVALID = 31, | ||
| 74 | }; | ||
| 75 | |||
| 76 | BitField<0, 5, Semantic> map_x; | ||
| 77 | BitField<8, 5, Semantic> map_y; | ||
| 78 | BitField<16, 5, Semantic> map_z; | ||
| 79 | BitField<24, 5, Semantic> map_w; | ||
| 80 | } vs_output_attributes[7]; | ||
| 81 | |||
| 82 | INSERT_PADDING_WORDS(0xe); | ||
| 83 | |||
| 84 | enum class ScissorMode : u32 { | ||
| 85 | Disabled = 0, | ||
| 86 | Exclude = 1, // Exclude pixels inside the scissor box | ||
| 87 | |||
| 88 | Include = 3 // Exclude pixels outside the scissor box | ||
| 89 | }; | ||
| 90 | |||
| 91 | struct { | ||
| 92 | BitField<0, 2, ScissorMode> mode; | ||
| 93 | |||
| 94 | union { | ||
| 95 | BitField<0, 16, u32> x1; | ||
| 96 | BitField<16, 16, u32> y1; | ||
| 97 | }; | ||
| 98 | |||
| 99 | union { | ||
| 100 | BitField<0, 16, u32> x2; | ||
| 101 | BitField<16, 16, u32> y2; | ||
| 102 | }; | ||
| 103 | } scissor_test; | ||
| 104 | |||
| 105 | union { | ||
| 106 | BitField<0, 10, s32> x; | ||
| 107 | BitField<16, 10, s32> y; | ||
| 108 | } viewport_corner; | ||
| 109 | |||
| 110 | INSERT_PADDING_WORDS(0x1); | ||
| 111 | |||
| 112 | // TODO: early depth | ||
| 113 | INSERT_PADDING_WORDS(0x1); | ||
| 114 | |||
| 115 | INSERT_PADDING_WORDS(0x2); | ||
| 116 | |||
| 117 | enum DepthBuffering : u32 { | ||
| 118 | WBuffering = 0, | ||
| 119 | ZBuffering = 1, | ||
| 120 | }; | ||
| 121 | BitField<0, 1, DepthBuffering> depthmap_enable; | ||
| 122 | |||
| 123 | INSERT_PADDING_WORDS(0x12); | ||
| 124 | }; | ||
| 125 | |||
| 126 | static_assert(sizeof(RasterizerRegs) == 0x40 * sizeof(u32), | ||
| 127 | "RasterizerRegs struct has incorrect size"); | ||
| 128 | |||
| 129 | } // namespace Pica | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 071e4ace0..c4061c005 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -197,13 +197,16 @@ void RasterizerOpenGL::DrawTriangles() { | |||
| 197 | 197 | ||
| 198 | // Sync the viewport | 198 | // Sync the viewport |
| 199 | // These registers hold half-width and half-height, so must be multiplied by 2 | 199 | // These registers hold half-width and half-height, so must be multiplied by 2 |
| 200 | GLsizei viewport_width = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_x).ToFloat32() * 2; | 200 | GLsizei viewport_width = |
| 201 | GLsizei viewport_height = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_y).ToFloat32() * 2; | 201 | (GLsizei)Pica::float24::FromRaw(regs.rasterizer.viewport_size_x).ToFloat32() * 2; |
| 202 | GLsizei viewport_height = | ||
| 203 | (GLsizei)Pica::float24::FromRaw(regs.rasterizer.viewport_size_y).ToFloat32() * 2; | ||
| 202 | 204 | ||
| 203 | glViewport((GLint)(rect.left + regs.viewport_corner.x * color_surface->res_scale_width), | 205 | glViewport( |
| 204 | (GLint)(rect.bottom + regs.viewport_corner.y * color_surface->res_scale_height), | 206 | (GLint)(rect.left + regs.rasterizer.viewport_corner.x * color_surface->res_scale_width), |
| 205 | (GLsizei)(viewport_width * color_surface->res_scale_width), | 207 | (GLint)(rect.bottom + regs.rasterizer.viewport_corner.y * color_surface->res_scale_height), |
| 206 | (GLsizei)(viewport_height * color_surface->res_scale_height)); | 208 | (GLsizei)(viewport_width * color_surface->res_scale_width), |
| 209 | (GLsizei)(viewport_height * color_surface->res_scale_height)); | ||
| 207 | 210 | ||
| 208 | if (uniform_block_data.data.framebuffer_scale[0] != color_surface->res_scale_width || | 211 | if (uniform_block_data.data.framebuffer_scale[0] != color_surface->res_scale_width || |
| 209 | uniform_block_data.data.framebuffer_scale[1] != color_surface->res_scale_height) { | 212 | uniform_block_data.data.framebuffer_scale[1] != color_surface->res_scale_height) { |
| @@ -215,16 +218,16 @@ void RasterizerOpenGL::DrawTriangles() { | |||
| 215 | 218 | ||
| 216 | // Scissor checks are window-, not viewport-relative, which means that if the cached texture | 219 | // Scissor checks are window-, not viewport-relative, which means that if the cached texture |
| 217 | // sub-rect changes, the scissor bounds also need to be updated. | 220 | // sub-rect changes, the scissor bounds also need to be updated. |
| 218 | GLint scissor_x1 = | 221 | GLint scissor_x1 = static_cast<GLint>( |
| 219 | static_cast<GLint>(rect.left + regs.scissor_test.x1 * color_surface->res_scale_width); | 222 | rect.left + regs.rasterizer.scissor_test.x1 * color_surface->res_scale_width); |
| 220 | GLint scissor_y1 = | 223 | GLint scissor_y1 = static_cast<GLint>( |
| 221 | static_cast<GLint>(rect.bottom + regs.scissor_test.y1 * color_surface->res_scale_height); | 224 | rect.bottom + regs.rasterizer.scissor_test.y1 * color_surface->res_scale_height); |
| 222 | // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when | 225 | // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when |
| 223 | // scaling or doing multisampling. | 226 | // scaling or doing multisampling. |
| 224 | GLint scissor_x2 = | 227 | GLint scissor_x2 = static_cast<GLint>( |
| 225 | static_cast<GLint>(rect.left + (regs.scissor_test.x2 + 1) * color_surface->res_scale_width); | 228 | rect.left + (regs.rasterizer.scissor_test.x2 + 1) * color_surface->res_scale_width); |
| 226 | GLint scissor_y2 = static_cast<GLint>( | 229 | GLint scissor_y2 = static_cast<GLint>( |
| 227 | rect.bottom + (regs.scissor_test.y2 + 1) * color_surface->res_scale_height); | 230 | rect.bottom + (regs.rasterizer.scissor_test.y2 + 1) * color_surface->res_scale_height); |
| 228 | 231 | ||
| 229 | if (uniform_block_data.data.scissor_x1 != scissor_x1 || | 232 | if (uniform_block_data.data.scissor_x1 != scissor_x1 || |
| 230 | uniform_block_data.data.scissor_x2 != scissor_x2 || | 233 | uniform_block_data.data.scissor_x2 != scissor_x2 || |
| @@ -316,20 +319,20 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 316 | 319 | ||
| 317 | switch (id) { | 320 | switch (id) { |
| 318 | // Culling | 321 | // Culling |
| 319 | case PICA_REG_INDEX(cull_mode): | 322 | case PICA_REG_INDEX(rasterizer.cull_mode): |
| 320 | SyncCullMode(); | 323 | SyncCullMode(); |
| 321 | break; | 324 | break; |
| 322 | 325 | ||
| 323 | // Depth modifiers | 326 | // Depth modifiers |
| 324 | case PICA_REG_INDEX(viewport_depth_range): | 327 | case PICA_REG_INDEX(rasterizer.viewport_depth_range): |
| 325 | SyncDepthScale(); | 328 | SyncDepthScale(); |
| 326 | break; | 329 | break; |
| 327 | case PICA_REG_INDEX(viewport_depth_near_plane): | 330 | case PICA_REG_INDEX(rasterizer.viewport_depth_near_plane): |
| 328 | SyncDepthOffset(); | 331 | SyncDepthOffset(); |
| 329 | break; | 332 | break; |
| 330 | 333 | ||
| 331 | // Depth buffering | 334 | // Depth buffering |
| 332 | case PICA_REG_INDEX(depthmap_enable): | 335 | case PICA_REG_INDEX(rasterizer.depthmap_enable): |
| 333 | shader_dirty = true; | 336 | shader_dirty = true; |
| 334 | break; | 337 | break; |
| 335 | 338 | ||
| @@ -398,7 +401,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 398 | break; | 401 | break; |
| 399 | 402 | ||
| 400 | // Scissor test | 403 | // Scissor test |
| 401 | case PICA_REG_INDEX(scissor_test.mode): | 404 | case PICA_REG_INDEX(rasterizer.scissor_test.mode): |
| 402 | shader_dirty = true; | 405 | shader_dirty = true; |
| 403 | break; | 406 | break; |
| 404 | 407 | ||
| @@ -1110,30 +1113,31 @@ void RasterizerOpenGL::SetShader() { | |||
| 1110 | void RasterizerOpenGL::SyncCullMode() { | 1113 | void RasterizerOpenGL::SyncCullMode() { |
| 1111 | const auto& regs = Pica::g_state.regs; | 1114 | const auto& regs = Pica::g_state.regs; |
| 1112 | 1115 | ||
| 1113 | switch (regs.cull_mode) { | 1116 | switch (regs.rasterizer.cull_mode) { |
| 1114 | case Pica::Regs::CullMode::KeepAll: | 1117 | case Pica::RasterizerRegs::CullMode::KeepAll: |
| 1115 | state.cull.enabled = false; | 1118 | state.cull.enabled = false; |
| 1116 | break; | 1119 | break; |
| 1117 | 1120 | ||
| 1118 | case Pica::Regs::CullMode::KeepClockWise: | 1121 | case Pica::RasterizerRegs::CullMode::KeepClockWise: |
| 1119 | state.cull.enabled = true; | 1122 | state.cull.enabled = true; |
| 1120 | state.cull.front_face = GL_CW; | 1123 | state.cull.front_face = GL_CW; |
| 1121 | break; | 1124 | break; |
| 1122 | 1125 | ||
| 1123 | case Pica::Regs::CullMode::KeepCounterClockWise: | 1126 | case Pica::RasterizerRegs::CullMode::KeepCounterClockWise: |
| 1124 | state.cull.enabled = true; | 1127 | state.cull.enabled = true; |
| 1125 | state.cull.front_face = GL_CCW; | 1128 | state.cull.front_face = GL_CCW; |
| 1126 | break; | 1129 | break; |
| 1127 | 1130 | ||
| 1128 | default: | 1131 | default: |
| 1129 | LOG_CRITICAL(Render_OpenGL, "Unknown cull mode %d", regs.cull_mode.Value()); | 1132 | LOG_CRITICAL(Render_OpenGL, "Unknown cull mode %d", regs.rasterizer.cull_mode.Value()); |
| 1130 | UNIMPLEMENTED(); | 1133 | UNIMPLEMENTED(); |
| 1131 | break; | 1134 | break; |
| 1132 | } | 1135 | } |
| 1133 | } | 1136 | } |
| 1134 | 1137 | ||
| 1135 | void RasterizerOpenGL::SyncDepthScale() { | 1138 | void RasterizerOpenGL::SyncDepthScale() { |
| 1136 | float depth_scale = Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_range).ToFloat32(); | 1139 | float depth_scale = |
| 1140 | Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); | ||
| 1137 | if (depth_scale != uniform_block_data.data.depth_scale) { | 1141 | if (depth_scale != uniform_block_data.data.depth_scale) { |
| 1138 | uniform_block_data.data.depth_scale = depth_scale; | 1142 | uniform_block_data.data.depth_scale = depth_scale; |
| 1139 | uniform_block_data.dirty = true; | 1143 | uniform_block_data.dirty = true; |
| @@ -1142,7 +1146,7 @@ void RasterizerOpenGL::SyncDepthScale() { | |||
| 1142 | 1146 | ||
| 1143 | void RasterizerOpenGL::SyncDepthOffset() { | 1147 | void RasterizerOpenGL::SyncDepthOffset() { |
| 1144 | float depth_offset = | 1148 | float depth_offset = |
| 1145 | Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_near_plane).ToFloat32(); | 1149 | Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); |
| 1146 | if (depth_offset != uniform_block_data.data.depth_offset) { | 1150 | if (depth_offset != uniform_block_data.data.depth_offset) { |
| 1147 | uniform_block_data.data.depth_offset = depth_offset; | 1151 | uniform_block_data.data.depth_offset = depth_offset; |
| 1148 | uniform_block_data.dirty = true; | 1152 | uniform_block_data.dirty = true; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index a1aa07074..bd7b6874a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -52,9 +52,9 @@ union PicaShaderConfig { | |||
| 52 | 52 | ||
| 53 | const auto& regs = Pica::g_state.regs; | 53 | const auto& regs = Pica::g_state.regs; |
| 54 | 54 | ||
| 55 | state.scissor_test_mode = regs.scissor_test.mode; | 55 | state.scissor_test_mode = regs.rasterizer.scissor_test.mode; |
| 56 | 56 | ||
| 57 | state.depthmap_enable = regs.depthmap_enable; | 57 | state.depthmap_enable = regs.rasterizer.depthmap_enable; |
| 58 | 58 | ||
| 59 | state.alpha_test_func = regs.output_merger.alpha_test.enable | 59 | state.alpha_test_func = regs.output_merger.alpha_test.enable |
| 60 | ? regs.output_merger.alpha_test.func.Value() | 60 | ? regs.output_merger.alpha_test.func.Value() |
| @@ -172,12 +172,12 @@ union PicaShaderConfig { | |||
| 172 | 172 | ||
| 173 | struct State { | 173 | struct State { |
| 174 | Pica::Regs::CompareFunc alpha_test_func; | 174 | Pica::Regs::CompareFunc alpha_test_func; |
| 175 | Pica::Regs::ScissorMode scissor_test_mode; | 175 | Pica::RasterizerRegs::ScissorMode scissor_test_mode; |
| 176 | Pica::Regs::TextureConfig::TextureType texture0_type; | 176 | Pica::Regs::TextureConfig::TextureType texture0_type; |
| 177 | std::array<TevStageConfigRaw, 6> tev_stages; | 177 | std::array<TevStageConfigRaw, 6> tev_stages; |
| 178 | u8 combiner_buffer_input; | 178 | u8 combiner_buffer_input; |
| 179 | 179 | ||
| 180 | Pica::Regs::DepthBuffering depthmap_enable; | 180 | Pica::RasterizerRegs::DepthBuffering depthmap_enable; |
| 181 | Pica::Regs::FogMode fog_mode; | 181 | Pica::Regs::FogMode fog_mode; |
| 182 | bool fog_flip; | 182 | bool fog_flip; |
| 183 | 183 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 4c4f98ac9..c34c3463f 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "video_core/renderer_opengl/gl_shader_util.h" | 13 | #include "video_core/renderer_opengl/gl_shader_util.h" |
| 14 | 14 | ||
| 15 | using Pica::Regs; | 15 | using Pica::Regs; |
| 16 | using Pica::RasterizerRegs; | ||
| 16 | using TevStageConfig = Regs::TevStageConfig; | 17 | using TevStageConfig = Regs::TevStageConfig; |
| 17 | 18 | ||
| 18 | namespace GLShader { | 19 | namespace GLShader { |
| @@ -639,10 +640,10 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 639 | } | 640 | } |
| 640 | 641 | ||
| 641 | // Append the scissor test | 642 | // Append the scissor test |
| 642 | if (state.scissor_test_mode != Regs::ScissorMode::Disabled) { | 643 | if (state.scissor_test_mode != RasterizerRegs::ScissorMode::Disabled) { |
| 643 | out += "if ("; | 644 | out += "if ("; |
| 644 | // Negate the condition if we have to keep only the pixels outside the scissor box | 645 | // Negate the condition if we have to keep only the pixels outside the scissor box |
| 645 | if (state.scissor_test_mode == Regs::ScissorMode::Include) | 646 | if (state.scissor_test_mode == RasterizerRegs::ScissorMode::Include) |
| 646 | out += "!"; | 647 | out += "!"; |
| 647 | out += "(gl_FragCoord.x >= scissor_x1 && " | 648 | out += "(gl_FragCoord.x >= scissor_x1 && " |
| 648 | "gl_FragCoord.y >= scissor_y1 && " | 649 | "gl_FragCoord.y >= scissor_y1 && " |
| @@ -652,7 +653,7 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 652 | 653 | ||
| 653 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | 654 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; |
| 654 | out += "float depth = z_over_w * depth_scale + depth_offset;\n"; | 655 | out += "float depth = z_over_w * depth_scale + depth_offset;\n"; |
| 655 | if (state.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { | 656 | if (state.depthmap_enable == Pica::RasterizerRegs::DepthBuffering::WBuffering) { |
| 656 | out += "depth /= gl_FragCoord.w;\n"; | 657 | out += "depth /= gl_FragCoord.w;\n"; |
| 657 | } | 658 | } |
| 658 | 659 | ||
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index f5f7ea61d..916ea8823 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp | |||
| @@ -20,7 +20,7 @@ namespace Pica { | |||
| 20 | 20 | ||
| 21 | namespace Shader { | 21 | namespace Shader { |
| 22 | 22 | ||
| 23 | OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer& input) { | 23 | OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs, AttributeBuffer& input) { |
| 24 | // Setup output data | 24 | // Setup output data |
| 25 | union { | 25 | union { |
| 26 | OutputVertex ret{}; | 26 | OutputVertex ret{}; |
| @@ -33,16 +33,16 @@ OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer | |||
| 33 | for (unsigned int i = 0; i < num_attributes; ++i) { | 33 | for (unsigned int i = 0; i < num_attributes; ++i) { |
| 34 | const auto& output_register_map = regs.vs_output_attributes[i]; | 34 | const auto& output_register_map = regs.vs_output_attributes[i]; |
| 35 | 35 | ||
| 36 | Regs::VSOutputAttributes::Semantic semantics[4] = { | 36 | RasterizerRegs::VSOutputAttributes::Semantic semantics[4] = { |
| 37 | output_register_map.map_x, output_register_map.map_y, output_register_map.map_z, | 37 | output_register_map.map_x, output_register_map.map_y, output_register_map.map_z, |
| 38 | output_register_map.map_w}; | 38 | output_register_map.map_w}; |
| 39 | 39 | ||
| 40 | for (unsigned comp = 0; comp < 4; ++comp) { | 40 | for (unsigned comp = 0; comp < 4; ++comp) { |
| 41 | Regs::VSOutputAttributes::Semantic semantic = semantics[comp]; | 41 | RasterizerRegs::VSOutputAttributes::Semantic semantic = semantics[comp]; |
| 42 | float24* out = &vertex_slots[semantic]; | 42 | float24* out = &vertex_slots[semantic]; |
| 43 | if (semantic < vertex_slots.size()) { | 43 | if (semantic < vertex_slots.size()) { |
| 44 | *out = input.attr[i][comp]; | 44 | *out = input.attr[i][comp]; |
| 45 | } else if (semantic != Regs::VSOutputAttributes::INVALID) { | 45 | } else if (semantic != RasterizerRegs::VSOutputAttributes::INVALID) { |
| 46 | LOG_ERROR(HW_GPU, "Invalid/unknown semantic id: %u", (unsigned int)semantic); | 46 | LOG_ERROR(HW_GPU, "Invalid/unknown semantic id: %u", (unsigned int)semantic); |
| 47 | } | 47 | } |
| 48 | } | 48 | } |
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index b188d3edf..e4b68f958 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h | |||
| @@ -39,19 +39,19 @@ struct OutputVertex { | |||
| 39 | INSERT_PADDING_WORDS(1); | 39 | INSERT_PADDING_WORDS(1); |
| 40 | Math::Vec2<float24> tc2; | 40 | Math::Vec2<float24> tc2; |
| 41 | 41 | ||
| 42 | static OutputVertex FromAttributeBuffer(const Regs& regs, AttributeBuffer& output); | 42 | static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs, AttributeBuffer& output); |
| 43 | }; | 43 | }; |
| 44 | #define ASSERT_POS(var, pos) \ | 44 | #define ASSERT_POS(var, pos) \ |
| 45 | static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ | 45 | static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ |
| 46 | "offset.") | 46 | "offset.") |
| 47 | ASSERT_POS(pos, Regs::VSOutputAttributes::POSITION_X); | 47 | ASSERT_POS(pos, RasterizerRegs::VSOutputAttributes::POSITION_X); |
| 48 | ASSERT_POS(quat, Regs::VSOutputAttributes::QUATERNION_X); | 48 | ASSERT_POS(quat, RasterizerRegs::VSOutputAttributes::QUATERNION_X); |
| 49 | ASSERT_POS(color, Regs::VSOutputAttributes::COLOR_R); | 49 | ASSERT_POS(color, RasterizerRegs::VSOutputAttributes::COLOR_R); |
| 50 | ASSERT_POS(tc0, Regs::VSOutputAttributes::TEXCOORD0_U); | 50 | ASSERT_POS(tc0, RasterizerRegs::VSOutputAttributes::TEXCOORD0_U); |
| 51 | ASSERT_POS(tc1, Regs::VSOutputAttributes::TEXCOORD1_U); | 51 | ASSERT_POS(tc1, RasterizerRegs::VSOutputAttributes::TEXCOORD1_U); |
| 52 | ASSERT_POS(tc0_w, Regs::VSOutputAttributes::TEXCOORD0_W); | 52 | ASSERT_POS(tc0_w, RasterizerRegs::VSOutputAttributes::TEXCOORD0_W); |
| 53 | ASSERT_POS(view, Regs::VSOutputAttributes::VIEW_X); | 53 | ASSERT_POS(view, RasterizerRegs::VSOutputAttributes::VIEW_X); |
| 54 | ASSERT_POS(tc2, Regs::VSOutputAttributes::TEXCOORD2_U); | 54 | ASSERT_POS(tc2, RasterizerRegs::VSOutputAttributes::TEXCOORD2_U); |
| 55 | #undef ASSERT_POS | 55 | #undef ASSERT_POS |
| 56 | static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); | 56 | static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); |
| 57 | static_assert(sizeof(OutputVertex) == 24 * sizeof(float), "OutputVertex has invalid size"); | 57 | static_assert(sizeof(OutputVertex) == 24 * sizeof(float), "OutputVertex has invalid size"); |