summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar wwylele2017-08-03 01:40:42 +0300
committerGravatar wwylele2017-08-07 10:30:05 +0300
commitbaa24f4ea9d9c4d7c1bd60ba8a6fc188dfa9cc8f (patch)
treefb4aff72d838100708e45cc022287af349d245e6 /src
parentMerge pull request #2848 from wwylele/shader-loop-fix (diff)
downloadyuzu-baa24f4ea9d9c4d7c1bd60ba8a6fc188dfa9cc8f.tar.gz
yuzu-baa24f4ea9d9c4d7c1bd60ba8a6fc188dfa9cc8f.tar.xz
yuzu-baa24f4ea9d9c4d7c1bd60ba8a6fc188dfa9cc8f.zip
pica: upload shared shader code to both unit
Diffstat (limited to 'src')
-rw-r--r--src/video_core/command_processor.cpp62
-rw-r--r--src/video_core/regs_pipeline.h9
2 files changed, 45 insertions, 26 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 4633a1df1..f98ca3302 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -119,27 +119,6 @@ static void WriteUniformFloatReg(ShaderRegs& config, Shader::ShaderSetup& setup,
119 } 119 }
120} 120}
121 121
122static void WriteProgramCode(ShaderRegs& config, Shader::ShaderSetup& setup,
123 unsigned max_program_code_length, u32 value) {
124 if (config.program.offset >= max_program_code_length) {
125 LOG_ERROR(HW_GPU, "Invalid %s program offset %d", GetShaderSetupTypeName(setup),
126 (int)config.program.offset);
127 } else {
128 setup.program_code[config.program.offset] = value;
129 config.program.offset++;
130 }
131}
132
133static void WriteSwizzlePatterns(ShaderRegs& config, Shader::ShaderSetup& setup, u32 value) {
134 if (config.swizzle_patterns.offset >= setup.swizzle_data.size()) {
135 LOG_ERROR(HW_GPU, "Invalid %s swizzle pattern offset %d", GetShaderSetupTypeName(setup),
136 (int)config.swizzle_patterns.offset);
137 } else {
138 setup.swizzle_data[config.swizzle_patterns.offset] = value;
139 config.swizzle_patterns.offset++;
140 }
141}
142
143static void WritePicaReg(u32 id, u32 value, u32 mask) { 122static void WritePicaReg(u32 id, u32 value, u32 mask) {
144 auto& regs = g_state.regs; 123 auto& regs = g_state.regs;
145 124
@@ -458,7 +437,13 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
458 case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[5], 0x2a1): 437 case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[5], 0x2a1):
459 case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[6], 0x2a2): 438 case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[6], 0x2a2):
460 case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[7], 0x2a3): { 439 case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[7], 0x2a3): {
461 WriteProgramCode(g_state.regs.gs, g_state.gs, 4096, value); 440 u32& offset = g_state.regs.gs.program.offset;
441 if (offset >= 4096) {
442 LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset);
443 } else {
444 g_state.gs.program_code[offset] = value;
445 offset++;
446 }
462 break; 447 break;
463 } 448 }
464 449
@@ -470,11 +455,18 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
470 case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[5], 0x2ab): 455 case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[5], 0x2ab):
471 case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[6], 0x2ac): 456 case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[6], 0x2ac):
472 case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[7], 0x2ad): { 457 case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[7], 0x2ad): {
473 WriteSwizzlePatterns(g_state.regs.gs, g_state.gs, value); 458 u32& offset = g_state.regs.gs.swizzle_patterns.offset;
459 if (offset >= g_state.gs.swizzle_data.size()) {
460 LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset);
461 } else {
462 g_state.gs.swizzle_data[offset] = value;
463 offset++;
464 }
474 break; 465 break;
475 } 466 }
476 467
477 case PICA_REG_INDEX(vs.bool_uniforms): 468 case PICA_REG_INDEX(vs.bool_uniforms):
469 // TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
478 WriteUniformBoolReg(g_state.vs, g_state.regs.vs.bool_uniforms.Value()); 470 WriteUniformBoolReg(g_state.vs, g_state.regs.vs.bool_uniforms.Value());
479 break; 471 break;
480 472
@@ -482,6 +474,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
482 case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2): 474 case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2):
483 case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3): 475 case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3):
484 case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): { 476 case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): {
477 // TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
485 unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1)); 478 unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
486 auto values = regs.vs.int_uniforms[index]; 479 auto values = regs.vs.int_uniforms[index];
487 WriteUniformIntReg(g_state.vs, index, 480 WriteUniformIntReg(g_state.vs, index,
@@ -497,6 +490,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
497 case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6): 490 case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6):
498 case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7): 491 case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7):
499 case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): { 492 case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): {
493 // TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
500 WriteUniformFloatReg(g_state.regs.vs, g_state.vs, vs_float_regs_counter, 494 WriteUniformFloatReg(g_state.regs.vs, g_state.vs, vs_float_regs_counter,
501 vs_uniform_write_buffer, value); 495 vs_uniform_write_buffer, value);
502 break; 496 break;
@@ -510,7 +504,16 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
510 case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1): 504 case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1):
511 case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2): 505 case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2):
512 case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): { 506 case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): {
513 WriteProgramCode(g_state.regs.vs, g_state.vs, 512, value); 507 u32& offset = g_state.regs.vs.program.offset;
508 if (offset >= 512) {
509 LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset);
510 } else {
511 g_state.vs.program_code[offset] = value;
512 if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
513 g_state.gs.program_code[offset] = value;
514 }
515 offset++;
516 }
514 break; 517 break;
515 } 518 }
516 519
@@ -522,7 +525,16 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
522 case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db): 525 case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db):
523 case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc): 526 case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc):
524 case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): { 527 case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): {
525 WriteSwizzlePatterns(g_state.regs.vs, g_state.vs, value); 528 u32& offset = g_state.regs.vs.swizzle_patterns.offset;
529 if (offset >= g_state.vs.swizzle_data.size()) {
530 LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset);
531 } else {
532 g_state.vs.swizzle_data[offset] = value;
533 if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
534 g_state.gs.swizzle_data[offset] = value;
535 }
536 offset++;
537 }
526 break; 538 break;
527 } 539 }
528 540
diff --git a/src/video_core/regs_pipeline.h b/src/video_core/regs_pipeline.h
index 31c747d77..8b6369297 100644
--- a/src/video_core/regs_pipeline.h
+++ b/src/video_core/regs_pipeline.h
@@ -202,7 +202,14 @@ struct PipelineRegs {
202 /// Number of input attributes to the vertex shader minus 1 202 /// Number of input attributes to the vertex shader minus 1
203 BitField<0, 4, u32> max_input_attrib_index; 203 BitField<0, 4, u32> max_input_attrib_index;
204 204
205 INSERT_PADDING_WORDS(2); 205 INSERT_PADDING_WORDS(1);
206
207 // The shader unit 3, which can be used for both vertex and geometry shader, gets its
208 // configuration depending on this register. If this is not set, unit 3 will share some
209 // configuration with other units. It is known that program code and swizzle pattern uploaded
210 // via regs.vs will be also uploaded to unit 3 if this is not set. Although very likely, it is
211 // still unclear whether uniforms and other configuration can be also shared.
212 BitField<0, 1, u32> gs_unit_exclusive_configuration;
206 213
207 enum class GPUMode : u32 { 214 enum class GPUMode : u32 {
208 Drawing = 0, 215 Drawing = 0,