summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar FernandoS272021-04-04 09:38:15 +0200
committerGravatar ameerj2021-07-22 21:51:26 -0400
commit73cb17f41bf019df504d2d2af4ebdf45aa3201c6 (patch)
tree97ca7cbbefaae73eb77d6e91bbcac4dbe4238c3a
parentshader: Implement indexed attributes (diff)
downloadyuzu-73cb17f41bf019df504d2d2af4ebdf45aa3201c6.tar.gz
yuzu-73cb17f41bf019df504d2d2af4ebdf45aa3201c6.tar.xz
yuzu-73cb17f41bf019df504d2d2af4ebdf45aa3201c6.zip
shader: Implement indexed Position and ClipDistances
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp40
-rw-r--r--src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp26
-rw-r--r--src/shader_recompiler/program_header.h45
3 files changed, 100 insertions, 11 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index eadecb064..e22bb5371 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -327,6 +327,10 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
327 const Id compare_index{OpShiftRightLogical(U32[1], base_index, Constant(U32[1], 2U))}; 327 const Id compare_index{OpShiftRightLogical(U32[1], base_index, Constant(U32[1], 2U))};
328 std::vector<Sirit::Literal> literals; 328 std::vector<Sirit::Literal> literals;
329 std::vector<Id> labels; 329 std::vector<Id> labels;
330 if (info.loads_position) {
331 literals.push_back(static_cast<u32>(IR::Attribute::PositionX) >> 2);
332 labels.push_back(OpLabel());
333 }
330 const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2; 334 const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2;
331 for (u32 i = 0; i < info.input_generics.size(); i++) { 335 for (u32 i = 0; i < info.input_generics.size(); i++) {
332 if (!info.input_generics[i].used) { 336 if (!info.input_generics[i].used) {
@@ -340,6 +344,12 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
340 AddLabel(default_label); 344 AddLabel(default_label);
341 OpReturnValue(Constant(F32[1], 0.0f)); 345 OpReturnValue(Constant(F32[1], 0.0f));
342 size_t label_index = 0; 346 size_t label_index = 0;
347 if (info.loads_position) {
348 AddLabel(labels[label_index]);
349 const Id result{OpLoad(F32[1], OpAccessChain(input_f32, input_position, masked_index))};
350 OpReturnValue(result);
351 label_index++;
352 }
343 for (u32 i = 0; i < info.input_generics.size(); i++) { 353 for (u32 i = 0; i < info.input_generics.size(); i++) {
344 if (!info.input_generics[i].used) { 354 if (!info.input_generics[i].used) {
345 continue; 355 continue;
@@ -377,6 +387,10 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
377 const Id compare_index{OpShiftRightLogical(U32[1], base_index, Constant(U32[1], 2U))}; 387 const Id compare_index{OpShiftRightLogical(U32[1], base_index, Constant(U32[1], 2U))};
378 std::vector<Sirit::Literal> literals; 388 std::vector<Sirit::Literal> literals;
379 std::vector<Id> labels; 389 std::vector<Id> labels;
390 if (info.stores_position) {
391 literals.push_back(static_cast<u32>(IR::Attribute::PositionX) >> 2);
392 labels.push_back(OpLabel());
393 }
380 const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2; 394 const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2;
381 for (u32 i = 0; i < info.stores_generics.size(); i++) { 395 for (u32 i = 0; i < info.stores_generics.size(); i++) {
382 if (!info.stores_generics[i]) { 396 if (!info.stores_generics[i]) {
@@ -385,11 +399,24 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
385 literals.push_back(base_attribute_value + i); 399 literals.push_back(base_attribute_value + i);
386 labels.push_back(OpLabel()); 400 labels.push_back(OpLabel());
387 } 401 }
402 if (info.stores_clip_distance) {
403 literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2);
404 labels.push_back(OpLabel());
405 literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance4) >> 2);
406 labels.push_back(OpLabel());
407 }
388 OpSelectionMerge(end_block, spv::SelectionControlMask::MaskNone); 408 OpSelectionMerge(end_block, spv::SelectionControlMask::MaskNone);
389 OpSwitch(compare_index, default_label, literals, labels); 409 OpSwitch(compare_index, default_label, literals, labels);
390 AddLabel(default_label); 410 AddLabel(default_label);
391 OpReturn(); 411 OpReturn();
392 size_t label_index = 0; 412 size_t label_index = 0;
413 if (info.stores_position) {
414 AddLabel(labels[label_index]);
415 const Id pointer{OpAccessChain(output_f32, output_position, masked_index)};
416 OpStore(pointer, store_value);
417 OpReturn();
418 label_index++;
419 }
393 for (u32 i = 0; i < info.stores_generics.size(); i++) { 420 for (u32 i = 0; i < info.stores_generics.size(); i++) {
394 if (!info.stores_generics[i]) { 421 if (!info.stores_generics[i]) {
395 continue; 422 continue;
@@ -401,6 +428,19 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
401 OpReturn(); 428 OpReturn();
402 label_index++; 429 label_index++;
403 } 430 }
431 if (info.stores_clip_distance) {
432 AddLabel(labels[label_index]);
433 const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)};
434 OpStore(pointer, store_value);
435 OpReturn();
436 label_index++;
437 AddLabel(labels[label_index]);
438 const Id fixed_index{OpIAdd(U32[1], masked_index, Constant(U32[1], 4))};
439 const Id pointer2{OpAccessChain(output_f32, clip_distances, fixed_index)};
440 OpStore(pointer2, store_value);
441 OpReturn();
442 label_index++;
443 }
404 AddLabel(end_block); 444 AddLabel(end_block);
405 OpUnreachable(); 445 OpUnreachable();
406 OpFunctionEnd(); 446 OpFunctionEnd();
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
index dbe9f1f40..a14465598 100644
--- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
+++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
@@ -517,22 +517,32 @@ void GatherInfoFromHeader(Environment& env, Info& info) {
517 } 517 }
518 const auto& header = env.SPH(); 518 const auto& header = env.SPH();
519 if (stage == Stage::Fragment) { 519 if (stage == Stage::Fragment) {
520 if (!info.loads_indexed_attributes) {
521 return;
522 }
520 for (size_t i = 0; i < info.input_generics.size(); i++) { 523 for (size_t i = 0; i < info.input_generics.size(); i++) {
521 info.input_generics[i].used = 524 info.input_generics[i].used =
522 info.input_generics[i].used || header.ps.IsGenericVectorActive(i); 525 info.input_generics[i].used || header.ps.IsGenericVectorActive(i);
523 } 526 }
527 info.loads_position = info.loads_position || header.ps.imap_systemb.position != 0;
524 return; 528 return;
525 } 529 }
526 for (size_t i = 0; i < info.input_generics.size(); i++) { 530 if (info.loads_indexed_attributes) {
527 info.input_generics[i].used = 531 for (size_t i = 0; i < info.input_generics.size(); i++) {
528 info.input_generics[i].used || header.vtg.IsInputGenericVectorActive(i); 532 info.input_generics[i].used =
533 info.input_generics[i].used || header.vtg.IsInputGenericVectorActive(i);
534 }
529 } 535 }
530 for (size_t i = 0; i < info.stores_generics.size(); i++) { 536 if (info.stores_indexed_attributes) {
531 info.stores_generics[i] = 537 info.loads_position = info.loads_position || header.vtg.imap_systemb.position != 0;
532 info.stores_generics[i] || header.vtg.IsOutputGenericVectorActive(i); 538 for (size_t i = 0; i < info.stores_generics.size(); i++) {
539 info.stores_generics[i] =
540 info.stores_generics[i] || header.vtg.IsOutputGenericVectorActive(i);
541 }
542 info.stores_clip_distance =
543 info.stores_clip_distance || header.vtg.omap_systemc.clip_distances != 0;
544 info.stores_position = info.stores_position || header.vtg.omap_systemb.position != 0;
533 } 545 }
534 info.stores_clip_distance =
535 info.stores_clip_distance || header.vtg.omap_systemc.clip_distances != 0;
536} 546}
537 547
538} // Anonymous namespace 548} // Anonymous namespace
diff --git a/src/shader_recompiler/program_header.h b/src/shader_recompiler/program_header.h
index ce65fc1a4..15f43f2d8 100644
--- a/src/shader_recompiler/program_header.h
+++ b/src/shader_recompiler/program_header.h
@@ -69,7 +69,20 @@ struct ProgramHeader {
69 union { 69 union {
70 struct { 70 struct {
71 INSERT_PADDING_BYTES_NOINIT(3); // ImapSystemValuesA 71 INSERT_PADDING_BYTES_NOINIT(3); // ImapSystemValuesA
72 INSERT_PADDING_BYTES_NOINIT(1); // ImapSystemValuesB 72
73 union {
74 BitField<0, 1, u8> primitive_array_id;
75 BitField<1, 1, u8> rt_array_index;
76 BitField<2, 1, u8> viewport_index;
77 BitField<3, 1, u8> point_size;
78 BitField<4, 1, u8> position_x;
79 BitField<5, 1, u8> position_y;
80 BitField<6, 1, u8> position_z;
81 BitField<7, 1, u8> position_w;
82 BitField<0, 4, u8> first;
83 BitField<4, 4, u8> position;
84 u8 raw;
85 } imap_systemb;
73 86
74 union { 87 union {
75 BitField<0, 1, u8> x; 88 BitField<0, 1, u8> x;
@@ -99,7 +112,20 @@ struct ProgramHeader {
99 INSERT_PADDING_BYTES_NOINIT(5); // ImapFixedFncTexture[10] 112 INSERT_PADDING_BYTES_NOINIT(5); // ImapFixedFncTexture[10]
100 INSERT_PADDING_BYTES_NOINIT(1); // ImapReserved 113 INSERT_PADDING_BYTES_NOINIT(1); // ImapReserved
101 INSERT_PADDING_BYTES_NOINIT(3); // OmapSystemValuesA 114 INSERT_PADDING_BYTES_NOINIT(3); // OmapSystemValuesA
102 INSERT_PADDING_BYTES_NOINIT(1); // OmapSystemValuesB 115
116 union {
117 BitField<0, 1, u8> primitive_array_id;
118 BitField<1, 1, u8> rt_array_index;
119 BitField<2, 1, u8> viewport_index;
120 BitField<3, 1, u8> point_size;
121 BitField<4, 1, u8> position_x;
122 BitField<5, 1, u8> position_y;
123 BitField<6, 1, u8> position_z;
124 BitField<7, 1, u8> position_w;
125 BitField<0, 4, u8> first;
126 BitField<4, 4, u8> position;
127 u8 raw;
128 } omap_systemb;
103 129
104 union { 130 union {
105 BitField<0, 1, u8> x; 131 BitField<0, 1, u8> x;
@@ -148,7 +174,20 @@ struct ProgramHeader {
148 174
149 struct { 175 struct {
150 INSERT_PADDING_BYTES_NOINIT(3); // ImapSystemValuesA 176 INSERT_PADDING_BYTES_NOINIT(3); // ImapSystemValuesA
151 INSERT_PADDING_BYTES_NOINIT(1); // ImapSystemValuesB 177
178 union {
179 BitField<0, 1, u8> primitive_array_id;
180 BitField<1, 1, u8> rt_array_index;
181 BitField<2, 1, u8> viewport_index;
182 BitField<3, 1, u8> point_size;
183 BitField<4, 1, u8> position_x;
184 BitField<5, 1, u8> position_y;
185 BitField<6, 1, u8> position_z;
186 BitField<7, 1, u8> position_w;
187 BitField<0, 4, u8> first;
188 BitField<4, 4, u8> position;
189 u8 raw;
190 } imap_systemb;
152 191
153 union { 192 union {
154 BitField<0, 2, PixelImap> x; 193 BitField<0, 2, PixelImap> x;