diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 40 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | 26 | ||||
| -rw-r--r-- | src/shader_recompiler/program_header.h | 45 |
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; |