summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp2
-rw-r--r--src/video_core/debug_utils/debug_utils.h2
-rw-r--r--src/video_core/pica.h97
-rw-r--r--src/video_core/regs_shader.h104
-rw-r--r--src/video_core/shader/shader.cpp4
-rw-r--r--src/video_core/shader/shader.h4
-rw-r--r--src/video_core/shader/shader_interpreter.cpp2
-rw-r--r--src/video_core/shader/shader_interpreter.h2
9 files changed, 116 insertions, 102 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index c8d2675ae..2b0bf0960 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -36,6 +36,7 @@ set(HEADERS
36 regs_lighting.h 36 regs_lighting.h
37 regs_pipeline.h 37 regs_pipeline.h
38 regs_rasterizer.h 38 regs_rasterizer.h
39 regs_shader.h
39 regs_texturing.h 40 regs_texturing.h
40 renderer_base.h 41 renderer_base.h
41 renderer_opengl/gl_rasterizer.h 42 renderer_opengl/gl_rasterizer.h
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index 81cd35cd9..ec8a9ee4a 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -88,7 +88,7 @@ std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this global
88 88
89namespace DebugUtils { 89namespace DebugUtils {
90 90
91void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, 91void DumpShader(const std::string& filename, const ShaderRegs& config,
92 const Shader::ShaderSetup& setup, 92 const Shader::ShaderSetup& setup,
93 const RasterizerRegs::VSOutputAttributes* output_attributes) { 93 const RasterizerRegs::VSOutputAttributes* output_attributes) {
94 struct StuffToWrite { 94 struct StuffToWrite {
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index e58b76d41..44d5af462 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -182,7 +182,7 @@ namespace DebugUtils {
182#define PICA_DUMP_TEXTURES 0 182#define PICA_DUMP_TEXTURES 0
183#define PICA_LOG_TEV 0 183#define PICA_LOG_TEV 0
184 184
185void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, 185void DumpShader(const std::string& filename, const ShaderRegs& config,
186 const Shader::ShaderSetup& setup, 186 const Shader::ShaderSetup& setup,
187 const RasterizerRegs::VSOutputAttributes* output_attributes); 187 const RasterizerRegs::VSOutputAttributes* output_attributes);
188 188
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 765fa5dd4..099dc84f0 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -22,6 +22,7 @@
22#include "video_core/regs_lighting.h" 22#include "video_core/regs_lighting.h"
23#include "video_core/regs_pipeline.h" 23#include "video_core/regs_pipeline.h"
24#include "video_core/regs_rasterizer.h" 24#include "video_core/regs_rasterizer.h"
25#include "video_core/regs_shader.h"
25#include "video_core/regs_texturing.h" 26#include "video_core/regs_texturing.h"
26 27
27namespace Pica { 28namespace Pica {
@@ -57,97 +58,8 @@ struct Regs {
57 FramebufferRegs framebuffer; 58 FramebufferRegs framebuffer;
58 LightingRegs lighting; 59 LightingRegs lighting;
59 PipelineRegs pipeline; 60 PipelineRegs pipeline;
60 61 ShaderRegs gs;
61 struct ShaderConfig { 62 ShaderRegs vs;
62 BitField<0, 16, u32> bool_uniforms;
63
64 union {
65 BitField<0, 8, u32> x;
66 BitField<8, 8, u32> y;
67 BitField<16, 8, u32> z;
68 BitField<24, 8, u32> w;
69 } int_uniforms[4];
70
71 INSERT_PADDING_WORDS(0x4);
72
73 union {
74 // Number of input attributes to shader unit - 1
75 BitField<0, 4, u32> max_input_attribute_index;
76 };
77
78 // Offset to shader program entry point (in words)
79 BitField<0, 16, u32> main_offset;
80
81 /// Maps input attributes to registers. 4-bits per attribute, specifying a register index
82 u32 input_attribute_to_register_map_low;
83 u32 input_attribute_to_register_map_high;
84
85 unsigned int GetRegisterForAttribute(unsigned int attribute_index) const {
86 u64 map = ((u64)input_attribute_to_register_map_high << 32) |
87 (u64)input_attribute_to_register_map_low;
88 return (map >> (attribute_index * 4)) & 0b1111;
89 }
90
91 BitField<0, 16, u32> output_mask;
92
93 // 0x28E, CODETRANSFER_END
94 INSERT_PADDING_WORDS(0x2);
95
96 struct {
97 enum Format : u32 {
98 FLOAT24 = 0,
99 FLOAT32 = 1,
100 };
101
102 bool IsFloat32() const {
103 return format == FLOAT32;
104 }
105
106 union {
107 // Index of the next uniform to write to
108 // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
109 // indices
110 // TODO: Maybe the uppermost index is for the geometry shader? Investigate!
111 BitField<0, 7, u32> index;
112
113 BitField<31, 1, Format> format;
114 };
115
116 // Writing to these registers sets the current uniform.
117 u32 set_value[8];
118
119 } uniform_setup;
120
121 INSERT_PADDING_WORDS(0x2);
122
123 struct {
124 // Offset of the next instruction to write code to.
125 // Incremented with each instruction write.
126 u32 offset;
127
128 // Writing to these registers sets the "current" word in the shader program.
129 u32 set_word[8];
130 } program;
131
132 INSERT_PADDING_WORDS(0x1);
133
134 // This register group is used to load an internal table of swizzling patterns,
135 // which are indexed by each shader instruction to specify vector component swizzling.
136 struct {
137 // Offset of the next swizzle pattern to write code to.
138 // Incremented with each instruction write.
139 u32 offset;
140
141 // Writing to these registers sets the current swizzle pattern in the table.
142 u32 set_word[8];
143 } swizzle_patterns;
144
145 INSERT_PADDING_WORDS(0x2);
146 };
147
148 ShaderConfig gs;
149 ShaderConfig vs;
150
151 INSERT_PADDING_WORDS(0x20); 63 INSERT_PADDING_WORDS(0x20);
152 64
153 // Map register indices to names readable by humans 65 // Map register indices to names readable by humans
@@ -247,9 +159,6 @@ ASSERT_REG_POSITION(vs, 0x2b0);
247#undef ASSERT_REG_POSITION 159#undef ASSERT_REG_POSITION
248#endif // !defined(_MSC_VER) 160#endif // !defined(_MSC_VER)
249 161
250static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32),
251 "ShaderConfig structure has incorrect size");
252
253// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value 162// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value
254// anyway. 163// anyway.
255static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), 164static_assert(sizeof(Regs) <= 0x300 * sizeof(u32),
diff --git a/src/video_core/regs_shader.h b/src/video_core/regs_shader.h
new file mode 100644
index 000000000..ddb1ee451
--- /dev/null
+++ b/src/video_core/regs_shader.h
@@ -0,0 +1,104 @@
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
13namespace Pica {
14
15struct ShaderRegs {
16 BitField<0, 16, u32> bool_uniforms;
17
18 union {
19 BitField<0, 8, u32> x;
20 BitField<8, 8, u32> y;
21 BitField<16, 8, u32> z;
22 BitField<24, 8, u32> w;
23 } int_uniforms[4];
24
25 INSERT_PADDING_WORDS(0x4);
26
27 union {
28 // Number of input attributes to shader unit - 1
29 BitField<0, 4, u32> max_input_attribute_index;
30 };
31
32 // Offset to shader program entry point (in words)
33 BitField<0, 16, u32> main_offset;
34
35 /// Maps input attributes to registers. 4-bits per attribute, specifying a register index
36 u32 input_attribute_to_register_map_low;
37 u32 input_attribute_to_register_map_high;
38
39 unsigned int GetRegisterForAttribute(unsigned int attribute_index) const {
40 u64 map = ((u64)input_attribute_to_register_map_high << 32) |
41 (u64)input_attribute_to_register_map_low;
42 return (map >> (attribute_index * 4)) & 0b1111;
43 }
44
45 BitField<0, 16, u32> output_mask;
46
47 // 0x28E, CODETRANSFER_END
48 INSERT_PADDING_WORDS(0x2);
49
50 struct {
51 enum Format : u32 {
52 FLOAT24 = 0,
53 FLOAT32 = 1,
54 };
55
56 bool IsFloat32() const {
57 return format == FLOAT32;
58 }
59
60 union {
61 // Index of the next uniform to write to
62 // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
63 // indices
64 // TODO: Maybe the uppermost index is for the geometry shader? Investigate!
65 BitField<0, 7, u32> index;
66
67 BitField<31, 1, Format> format;
68 };
69
70 // Writing to these registers sets the current uniform.
71 u32 set_value[8];
72
73 } uniform_setup;
74
75 INSERT_PADDING_WORDS(0x2);
76
77 struct {
78 // Offset of the next instruction to write code to.
79 // Incremented with each instruction write.
80 u32 offset;
81
82 // Writing to these registers sets the "current" word in the shader program.
83 u32 set_word[8];
84 } program;
85
86 INSERT_PADDING_WORDS(0x1);
87
88 // This register group is used to load an internal table of swizzling patterns,
89 // which are indexed by each shader instruction to specify vector component swizzling.
90 struct {
91 // Offset of the next swizzle pattern to write code to.
92 // Incremented with each instruction write.
93 u32 offset;
94
95 // Writing to these registers sets the current swizzle pattern in the table.
96 u32 set_word[8];
97 } swizzle_patterns;
98
99 INSERT_PADDING_WORDS(0x2);
100};
101
102static_assert(sizeof(ShaderRegs) == 0x30 * sizeof(u32), "ShaderRegs struct has incorrect size");
103
104} // namespace Pica
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 916ea8823..840777a66 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -66,7 +66,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs, Attri
66 return ret; 66 return ret;
67} 67}
68 68
69void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input) { 69void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input) {
70 const unsigned max_attribute = config.max_input_attribute_index; 70 const unsigned max_attribute = config.max_input_attribute_index;
71 71
72 for (unsigned attr = 0; attr <= max_attribute; ++attr) { 72 for (unsigned attr = 0; attr <= max_attribute; ++attr) {
@@ -75,7 +75,7 @@ void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffe
75 } 75 }
76} 76}
77 77
78void UnitState::WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output) { 78void UnitState::WriteOutput(const ShaderRegs& config, AttributeBuffer& output) {
79 unsigned int output_i = 0; 79 unsigned int output_i = 0;
80 for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) { 80 for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) {
81 output.attr[output_i++] = registers.output[reg]; 81 output.attr[output_i++] = registers.output[reg];
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h
index e4b68f958..a469e294b 100644
--- a/src/video_core/shader/shader.h
+++ b/src/video_core/shader/shader.h
@@ -116,9 +116,9 @@ struct UnitState {
116 * @param config Shader configuration registers corresponding to the unit. 116 * @param config Shader configuration registers corresponding to the unit.
117 * @param input Attribute buffer to load into the input registers. 117 * @param input Attribute buffer to load into the input registers.
118 */ 118 */
119 void LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input); 119 void LoadInput(const ShaderRegs& config, const AttributeBuffer& input);
120 120
121 void WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output); 121 void WriteOutput(const ShaderRegs& config, AttributeBuffer& output);
122}; 122};
123 123
124struct ShaderSetup { 124struct ShaderSetup {
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 81522b8f5..f4d1c46c5 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -669,7 +669,7 @@ void InterpreterEngine::Run(const ShaderSetup& setup, UnitState& state) const {
669 669
670DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, 670DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup,
671 const AttributeBuffer& input, 671 const AttributeBuffer& input,
672 const Regs::ShaderConfig& config) const { 672 const ShaderRegs& config) const {
673 UnitState state; 673 UnitState state;
674 DebugData<true> debug_data; 674 DebugData<true> debug_data;
675 675
diff --git a/src/video_core/shader/shader_interpreter.h b/src/video_core/shader/shader_interpreter.h
index d7a61e122..5682b3a39 100644
--- a/src/video_core/shader/shader_interpreter.h
+++ b/src/video_core/shader/shader_interpreter.h
@@ -23,7 +23,7 @@ public:
23 * @return Debug information for this shader with regards to the given vertex 23 * @return Debug information for this shader with regards to the given vertex
24 */ 24 */
25 DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input, 25 DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input,
26 const Regs::ShaderConfig& config) const; 26 const ShaderRegs& config) const;
27}; 27};
28 28
29} // namespace 29} // namespace