summaryrefslogtreecommitdiff
path: root/src/video_core/shader/shader.cpp
diff options
context:
space:
mode:
authorGravatar wwylele2017-07-25 22:30:29 +0300
committerGravatar wwylele2017-08-19 10:13:20 +0300
commit46c6973d2bde25a2a8ae9ac434660798fd1dfaee (patch)
tree3910b3b8b95de67f70a482f08351e807c532b784 /src/video_core/shader/shader.cpp
parentpica/regs: layout geometry shader configuration regs (diff)
downloadyuzu-46c6973d2bde25a2a8ae9ac434660798fd1dfaee.tar.gz
yuzu-46c6973d2bde25a2a8ae9ac434660798fd1dfaee.tar.xz
yuzu-46c6973d2bde25a2a8ae9ac434660798fd1dfaee.zip
pica/shader: extend UnitState for GS
Among four shader units in pica, a special unit can be configured to run both VS and GS program. GSUnitState represents this unit, which extends UnitState (which represents the other three normal units) with extra state for primitive emitting. It uses lots of raw pointers to represent internal structure in order to keep it standard layout type for JIT to access. This unit doesn't handle triangle winding (inverting) itself; instead, it calls a WindingSetter handler. This will be explained in the following commits
Diffstat (limited to 'src/video_core/shader/shader.cpp')
-rw-r--r--src/video_core/shader/shader.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 67ed19ba8..b12468d3a 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -82,6 +82,44 @@ void UnitState::WriteOutput(const ShaderRegs& config, AttributeBuffer& output) {
82 } 82 }
83} 83}
84 84
85UnitState::UnitState(GSEmitter* emitter) : emitter_ptr(emitter) {}
86
87GSEmitter::GSEmitter() {
88 handlers = new Handlers;
89}
90
91GSEmitter::~GSEmitter() {
92 delete handlers;
93}
94
95void GSEmitter::Emit(Math::Vec4<float24> (&vertex)[16]) {
96 ASSERT(vertex_id < 3);
97 std::copy(std::begin(vertex), std::end(vertex), buffer[vertex_id].begin());
98 if (prim_emit) {
99 if (winding)
100 handlers->winding_setter();
101 for (size_t i = 0; i < buffer.size(); ++i) {
102 AttributeBuffer output;
103 unsigned int output_i = 0;
104 for (unsigned int reg : Common::BitSet<u32>(output_mask)) {
105 output.attr[output_i++] = buffer[i][reg];
106 }
107 handlers->vertex_handler(output);
108 }
109 }
110}
111
112GSUnitState::GSUnitState() : UnitState(&emitter) {}
113
114void GSUnitState::SetVertexHandler(VertexHandler vertex_handler, WindingSetter winding_setter) {
115 emitter.handlers->vertex_handler = std::move(vertex_handler);
116 emitter.handlers->winding_setter = std::move(winding_setter);
117}
118
119void GSUnitState::ConfigOutput(const ShaderRegs& config) {
120 emitter.output_mask = config.output_mask;
121}
122
85MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240)); 123MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240));
86 124
87#ifdef ARCHITECTURE_x86_64 125#ifdef ARCHITECTURE_x86_64