diff options
| author | 2017-08-03 01:40:42 +0300 | |
|---|---|---|
| committer | 2017-08-07 10:30:05 +0300 | |
| commit | baa24f4ea9d9c4d7c1bd60ba8a6fc188dfa9cc8f (patch) | |
| tree | fb4aff72d838100708e45cc022287af349d245e6 /src | |
| parent | Merge pull request #2848 from wwylele/shader-loop-fix (diff) | |
| download | yuzu-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.cpp | 62 | ||||
| -rw-r--r-- | src/video_core/regs_pipeline.h | 9 |
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 | ||
| 122 | static 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 | |||
| 133 | static 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 | |||
| 143 | static void WritePicaReg(u32 id, u32 value, u32 mask) { | 122 | static 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, |