summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-16 01:34:45 -0300
committerGravatar ReinUsesLisp2020-04-23 18:00:06 -0300
commit72deb773fdcc59b1df9752de4e846422b7bb5280 (patch)
tree524006956b6dbb6789831652129013e54f185f16 /src/video_core/shader/decode
parentMerge pull request #3768 from H27CK/cmd-title-fmt (diff)
downloadyuzu-72deb773fdcc59b1df9752de4e846422b7bb5280.tar.gz
yuzu-72deb773fdcc59b1df9752de4e846422b7bb5280.tar.xz
yuzu-72deb773fdcc59b1df9752de4e846422b7bb5280.zip
shader_ir: Turn classes into data structures
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/image.cpp18
-rw-r--r--src/video_core/shader/decode/texture.cpp99
2 files changed, 58 insertions, 59 deletions
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 85ee9aa5e..60b6ad72a 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -485,11 +485,10 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
485Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { 485Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) {
486 const auto offset = static_cast<u32>(image.index.Value()); 486 const auto offset = static_cast<u32>(image.index.Value());
487 487
488 const auto it = 488 const auto it = std::find_if(std::begin(used_images), std::end(used_images),
489 std::find_if(std::begin(used_images), std::end(used_images), 489 [offset](const Image& entry) { return entry.offset == offset; });
490 [offset](const Image& entry) { return entry.GetOffset() == offset; });
491 if (it != std::end(used_images)) { 490 if (it != std::end(used_images)) {
492 ASSERT(!it->IsBindless() && it->GetType() == it->GetType()); 491 ASSERT(!it->is_bindless && it->type == type);
493 return *it; 492 return *it;
494 } 493 }
495 494
@@ -505,13 +504,12 @@ Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::Im
505 const auto buffer = std::get<1>(result); 504 const auto buffer = std::get<1>(result);
506 const auto offset = std::get<2>(result); 505 const auto offset = std::get<2>(result);
507 506
508 const auto it = 507 const auto it = std::find_if(std::begin(used_images), std::end(used_images),
509 std::find_if(std::begin(used_images), std::end(used_images), 508 [buffer, offset](const Image& entry) {
510 [buffer = buffer, offset = offset](const Image& entry) { 509 return entry.buffer == buffer && entry.offset == offset;
511 return entry.GetBuffer() == buffer && entry.GetOffset() == offset; 510 });
512 });
513 if (it != std::end(used_images)) { 511 if (it != std::end(used_images)) {
514 ASSERT(it->IsBindless() && it->GetType() == it->GetType()); 512 ASSERT(it->is_bindless && it->type == type);
515 return *it; 513 return *it;
516 } 514 }
517 515
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index e68f1d305..193368c29 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -140,14 +140,13 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
140 const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); 140 const Node component = Immediate(static_cast<u32>(instr.tld4s.component));
141 141
142 const SamplerInfo info{TextureType::Texture2D, false, is_depth_compare, false}; 142 const SamplerInfo info{TextureType::Texture2D, false, is_depth_compare, false};
143 const Sampler& sampler = *GetSampler(instr.sampler, info); 143 const std::optional<Sampler> sampler = GetSampler(instr.sampler, info);
144 144
145 Node4 values; 145 Node4 values;
146 for (u32 element = 0; element < values.size(); ++element) { 146 for (u32 element = 0; element < values.size(); ++element) {
147 auto coords_copy = coords; 147 MetaTexture meta{*sampler, {}, depth_compare, aoffi, {}, {},
148 MetaTexture meta{sampler, {}, depth_compare, aoffi, {}, {}, 148 {}, {}, component, element, {}};
149 {}, {}, component, element, {}}; 149 values[element] = Operation(OperationCode::TextureGather, meta, coords);
150 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
151 } 150 }
152 151
153 if (instr.tld4s.fp16_flag) { 152 if (instr.tld4s.fp16_flag) {
@@ -170,13 +169,15 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
170 const auto texture_type = instr.txd.texture_type.Value(); 169 const auto texture_type = instr.txd.texture_type.Value();
171 const auto coord_count = GetCoordCount(texture_type); 170 const auto coord_count = GetCoordCount(texture_type);
172 Node index_var{}; 171 Node index_var{};
173 const Sampler* sampler = 172 const std::optional<Sampler> sampler =
174 is_bindless 173 is_bindless
175 ? GetBindlessSampler(base_reg, index_var, {{texture_type, is_array, false, false}}) 174 ? GetBindlessSampler(base_reg, index_var, {{texture_type, is_array, false, false}})
176 : GetSampler(instr.sampler, {{texture_type, is_array, false, false}}); 175 : GetSampler(instr.sampler, {{texture_type, is_array, false, false}});
177 Node4 values; 176 Node4 values;
178 if (sampler == nullptr) { 177 if (!sampler) {
179 std::generate(values.begin(), values.end(), [] { return Immediate(0); }); 178 for (u32 element = 0; element < values.size(); ++element) {
179 values[element] = Immediate(0);
180 }
180 WriteTexInstructionFloat(bb, instr, values); 181 WriteTexInstructionFloat(bb, instr, values);
181 break; 182 break;
182 } 183 }
@@ -218,10 +219,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
218 // Sadly, not all texture instructions specify the type of texture their sampler 219 // Sadly, not all texture instructions specify the type of texture their sampler
219 // uses. This must be fixed at a later instance. 220 // uses. This must be fixed at a later instance.
220 Node index_var{}; 221 Node index_var{};
221 const Sampler* sampler = 222 const std::optional<Sampler> sampler =
222 is_bindless ? GetBindlessSampler(instr.gpr8, index_var) : GetSampler(instr.sampler); 223 is_bindless ? GetBindlessSampler(instr.gpr8, index_var) : GetSampler(instr.sampler);
223 224
224 if (sampler == nullptr) { 225 if (!sampler) {
225 u32 indexer = 0; 226 u32 indexer = 0;
226 for (u32 element = 0; element < 4; ++element) { 227 for (u32 element = 0; element < 4; ++element) {
227 if (!instr.txq.IsComponentEnabled(element)) { 228 if (!instr.txq.IsComponentEnabled(element)) {
@@ -269,10 +270,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
269 270
270 auto texture_type = instr.tmml.texture_type.Value(); 271 auto texture_type = instr.tmml.texture_type.Value();
271 Node index_var{}; 272 Node index_var{};
272 const Sampler* sampler = 273 const std::optional<Sampler> sampler =
273 is_bindless ? GetBindlessSampler(instr.gpr20, index_var) : GetSampler(instr.sampler); 274 is_bindless ? GetBindlessSampler(instr.gpr20, index_var) : GetSampler(instr.sampler);
274 275
275 if (sampler == nullptr) { 276 if (!sampler) {
276 u32 indexer = 0; 277 u32 indexer = 0;
277 for (u32 element = 0; element < 2; ++element) { 278 for (u32 element = 0; element < 2; ++element) {
278 if (!instr.tmml.IsComponentEnabled(element)) { 279 if (!instr.tmml.IsComponentEnabled(element)) {
@@ -368,35 +369,34 @@ ShaderIR::SamplerInfo ShaderIR::GetSamplerInfo(std::optional<SamplerInfo> sample
368 sampler->is_buffer != 0}; 369 sampler->is_buffer != 0};
369} 370}
370 371
371const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, 372std::optional<Sampler> ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
372 std::optional<SamplerInfo> sampler_info) { 373 std::optional<SamplerInfo> sampler_info) {
373 const auto offset = static_cast<u32>(sampler.index.Value()); 374 const auto offset = static_cast<u32>(sampler.index.Value());
374 const auto info = GetSamplerInfo(sampler_info, offset); 375 const auto info = GetSamplerInfo(sampler_info, offset);
375 376
376 // If this sampler has already been used, return the existing mapping. 377 // If this sampler has already been used, return the existing mapping.
377 const auto it = 378 const auto it = std::find_if(used_samplers.begin(), used_samplers.end(),
378 std::find_if(used_samplers.begin(), used_samplers.end(), 379 [offset](const Sampler& entry) { return entry.offset == offset; });
379 [offset](const Sampler& entry) { return entry.GetOffset() == offset; });
380 if (it != used_samplers.end()) { 380 if (it != used_samplers.end()) {
381 ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && 381 ASSERT(!it->is_bindless && it->type == info.type && it->is_array == info.is_array &&
382 it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer); 382 it->is_shadow == info.is_shadow && it->is_buffer == info.is_buffer);
383 return &*it; 383 return *it;
384 } 384 }
385 385
386 // Otherwise create a new mapping for this sampler 386 // Otherwise create a new mapping for this sampler
387 const auto next_index = static_cast<u32>(used_samplers.size()); 387 const auto next_index = static_cast<u32>(used_samplers.size());
388 return &used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, 388 return used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow,
389 info.is_buffer, false); 389 info.is_buffer, false);
390} 390}
391 391
392const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, Node& index_var, 392std::optional<Sampler> ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, Node& index_var,
393 std::optional<SamplerInfo> sampler_info) { 393 std::optional<SamplerInfo> sampler_info) {
394 const Node sampler_register = GetRegister(reg); 394 const Node sampler_register = GetRegister(reg);
395 const auto [base_node, tracked_sampler_info] = 395 const auto [base_node, tracked_sampler_info] =
396 TrackBindlessSampler(sampler_register, global_code, static_cast<s64>(global_code.size())); 396 TrackBindlessSampler(sampler_register, global_code, static_cast<s64>(global_code.size()));
397 ASSERT(base_node != nullptr); 397 ASSERT(base_node != nullptr);
398 if (base_node == nullptr) { 398 if (base_node == nullptr) {
399 return nullptr; 399 return std::nullopt;
400 } 400 }
401 401
402 if (const auto bindless_sampler_info = 402 if (const auto bindless_sampler_info =
@@ -406,23 +406,22 @@ const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, Node& i
406 const auto info = GetSamplerInfo(sampler_info, offset, buffer); 406 const auto info = GetSamplerInfo(sampler_info, offset, buffer);
407 407
408 // If this sampler has already been used, return the existing mapping. 408 // If this sampler has already been used, return the existing mapping.
409 const auto it = 409 const auto it = std::find_if(used_samplers.begin(), used_samplers.end(),
410 std::find_if(used_samplers.begin(), used_samplers.end(), 410 [buffer = buffer, offset = offset](const Sampler& entry) {
411 [buffer = buffer, offset = offset](const Sampler& entry) { 411 return entry.buffer == buffer && entry.offset == offset;
412 return entry.GetBuffer() == buffer && entry.GetOffset() == offset; 412 });
413 });
414 if (it != used_samplers.end()) { 413 if (it != used_samplers.end()) {
415 ASSERT(it->IsBindless() && it->GetType() == info.type && 414 ASSERT(it->is_bindless && it->type == info.type && it->is_array == info.is_array &&
416 it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow); 415 it->is_shadow == info.is_shadow);
417 return &*it; 416 return *it;
418 } 417 }
419 418
420 // Otherwise create a new mapping for this sampler 419 // Otherwise create a new mapping for this sampler
421 const auto next_index = static_cast<u32>(used_samplers.size()); 420 const auto next_index = static_cast<u32>(used_samplers.size());
422 return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, 421 return used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array,
423 info.is_shadow, info.is_buffer, false); 422 info.is_shadow, info.is_buffer, false);
424 } else if (const auto array_sampler_info = 423 }
425 std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) { 424 if (const auto array_sampler_info = std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) {
426 const u32 base_offset = array_sampler_info->GetBaseOffset() / 4; 425 const u32 base_offset = array_sampler_info->GetBaseOffset() / 4;
427 index_var = GetCustomVariable(array_sampler_info->GetIndexVar()); 426 index_var = GetCustomVariable(array_sampler_info->GetIndexVar());
428 const auto info = GetSamplerInfo(sampler_info, base_offset); 427 const auto info = GetSamplerInfo(sampler_info, base_offset);
@@ -430,21 +429,21 @@ const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, Node& i
430 // If this sampler has already been used, return the existing mapping. 429 // If this sampler has already been used, return the existing mapping.
431 const auto it = std::find_if( 430 const auto it = std::find_if(
432 used_samplers.begin(), used_samplers.end(), 431 used_samplers.begin(), used_samplers.end(),
433 [base_offset](const Sampler& entry) { return entry.GetOffset() == base_offset; }); 432 [base_offset](const Sampler& entry) { return entry.offset == base_offset; });
434 if (it != used_samplers.end()) { 433 if (it != used_samplers.end()) {
435 ASSERT(!it->IsBindless() && it->GetType() == info.type && 434 ASSERT(!it->is_bindless && it->type == info.type && it->is_array == info.is_array &&
436 it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow && 435 it->is_shadow == info.is_shadow && it->is_buffer == info.is_buffer &&
437 it->IsBuffer() == info.is_buffer && it->IsIndexed()); 436 it->is_indexed);
438 return &*it; 437 return *it;
439 } 438 }
440 439
441 uses_indexed_samplers = true; 440 uses_indexed_samplers = true;
442 // Otherwise create a new mapping for this sampler 441 // Otherwise create a new mapping for this sampler
443 const auto next_index = static_cast<u32>(used_samplers.size()); 442 const auto next_index = static_cast<u32>(used_samplers.size());
444 return &used_samplers.emplace_back(next_index, base_offset, info.type, info.is_array, 443 return used_samplers.emplace_back(next_index, base_offset, info.type, info.is_array,
445 info.is_shadow, info.is_buffer, true); 444 info.is_shadow, info.is_buffer, true);
446 } 445 }
447 return nullptr; 446 return std::nullopt;
448} 447}
449 448
450void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { 449void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) {
@@ -531,7 +530,8 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
531 530
532 const SamplerInfo info{texture_type, is_array, is_shadow, false}; 531 const SamplerInfo info{texture_type, is_array, is_shadow, false};
533 Node index_var; 532 Node index_var;
534 const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, index_var, info) 533 std::optional<Sampler> sampler = is_bindless
534 ? GetBindlessSampler(*bindless_reg, index_var, info)
535 : GetSampler(instr.sampler, info); 535 : GetSampler(instr.sampler, info);
536 if (!sampler) { 536 if (!sampler) {
537 return {Immediate(0), Immediate(0), Immediate(0), Immediate(0)}; 537 return {Immediate(0), Immediate(0), Immediate(0), Immediate(0)};
@@ -685,10 +685,11 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
685 685
686 const SamplerInfo info{texture_type, is_array, depth_compare, false}; 686 const SamplerInfo info{texture_type, is_array, depth_compare, false};
687 Node index_var{}; 687 Node index_var{};
688 const Sampler* sampler = is_bindless ? GetBindlessSampler(parameter_register++, index_var, info) 688 const std::optional<Sampler> sampler =
689 : GetSampler(instr.sampler, info); 689 is_bindless ? GetBindlessSampler(parameter_register++, index_var, info)
690 : GetSampler(instr.sampler, info);
690 Node4 values; 691 Node4 values;
691 if (sampler == nullptr) { 692 if (!sampler) {
692 for (u32 element = 0; element < values.size(); ++element) { 693 for (u32 element = 0; element < values.size(); ++element) {
693 values[element] = Immediate(0); 694 values[element] = Immediate(0);
694 } 695 }