summaryrefslogtreecommitdiff
path: root/src/video_core/shader
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
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')
-rw-r--r--src/video_core/shader/decode.cpp18
-rw-r--r--src/video_core/shader/decode/image.cpp18
-rw-r--r--src/video_core/shader/decode/texture.cpp99
-rw-r--r--src/video_core/shader/node.h129
-rw-r--r--src/video_core/shader/shader_ir.h20
5 files changed, 102 insertions, 182 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 87ac9ac6c..8427837b7 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -42,11 +42,11 @@ void DeduceTextureHandlerSize(VideoCore::GuestDriverProfile& gpu_driver,
42 u32 count{}; 42 u32 count{};
43 std::vector<u32> bound_offsets; 43 std::vector<u32> bound_offsets;
44 for (const auto& sampler : used_samplers) { 44 for (const auto& sampler : used_samplers) {
45 if (sampler.IsBindless()) { 45 if (sampler.is_bindless) {
46 continue; 46 continue;
47 } 47 }
48 ++count; 48 ++count;
49 bound_offsets.emplace_back(sampler.GetOffset()); 49 bound_offsets.emplace_back(sampler.offset);
50 } 50 }
51 if (count > 1) { 51 if (count > 1) {
52 gpu_driver.DeduceTextureHandlerSize(std::move(bound_offsets)); 52 gpu_driver.DeduceTextureHandlerSize(std::move(bound_offsets));
@@ -56,14 +56,14 @@ void DeduceTextureHandlerSize(VideoCore::GuestDriverProfile& gpu_driver,
56std::optional<u32> TryDeduceSamplerSize(const Sampler& sampler_to_deduce, 56std::optional<u32> TryDeduceSamplerSize(const Sampler& sampler_to_deduce,
57 VideoCore::GuestDriverProfile& gpu_driver, 57 VideoCore::GuestDriverProfile& gpu_driver,
58 const std::list<Sampler>& used_samplers) { 58 const std::list<Sampler>& used_samplers) {
59 const u32 base_offset = sampler_to_deduce.GetOffset(); 59 const u32 base_offset = sampler_to_deduce.offset;
60 u32 max_offset{std::numeric_limits<u32>::max()}; 60 u32 max_offset{std::numeric_limits<u32>::max()};
61 for (const auto& sampler : used_samplers) { 61 for (const auto& sampler : used_samplers) {
62 if (sampler.IsBindless()) { 62 if (sampler.is_bindless) {
63 continue; 63 continue;
64 } 64 }
65 if (sampler.GetOffset() > base_offset) { 65 if (sampler.offset > base_offset) {
66 max_offset = std::min(sampler.GetOffset(), max_offset); 66 max_offset = std::min(sampler.offset, max_offset);
67 } 67 }
68 } 68 }
69 if (max_offset == std::numeric_limits<u32>::max()) { 69 if (max_offset == std::numeric_limits<u32>::max()) {
@@ -363,14 +363,14 @@ void ShaderIR::PostDecode() {
363 return; 363 return;
364 } 364 }
365 for (auto& sampler : used_samplers) { 365 for (auto& sampler : used_samplers) {
366 if (!sampler.IsIndexed()) { 366 if (!sampler.is_indexed) {
367 continue; 367 continue;
368 } 368 }
369 if (const auto size = TryDeduceSamplerSize(sampler, gpu_driver, used_samplers)) { 369 if (const auto size = TryDeduceSamplerSize(sampler, gpu_driver, used_samplers)) {
370 sampler.SetSize(*size); 370 sampler.size = *size;
371 } else { 371 } else {
372 LOG_CRITICAL(HW_GPU, "Failed to deduce size of indexed sampler"); 372 LOG_CRITICAL(HW_GPU, "Failed to deduce size of indexed sampler");
373 sampler.SetSize(1); 373 sampler.size = 1;
374 } 374 }
375 } 375 }
376} 376}
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 }
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 3eee961f5..d0656b581 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -265,76 +265,30 @@ class ArraySamplerNode;
265using TrackSamplerData = std::variant<BindlessSamplerNode, ArraySamplerNode>; 265using TrackSamplerData = std::variant<BindlessSamplerNode, ArraySamplerNode>;
266using TrackSampler = std::shared_ptr<TrackSamplerData>; 266using TrackSampler = std::shared_ptr<TrackSamplerData>;
267 267
268class Sampler { 268struct Sampler {
269public: 269 /// Bound samplers constructor
270 /// This constructor is for bound samplers
271 constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type, 270 constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type,
272 bool is_array, bool is_shadow, bool is_buffer, bool is_indexed) 271 bool is_array, bool is_shadow, bool is_buffer, bool is_indexed)
273 : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow}, 272 : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow},
274 is_buffer{is_buffer}, is_indexed{is_indexed} {} 273 is_buffer{is_buffer}, is_indexed{is_indexed} {}
275 274
276 /// This constructor is for bindless samplers 275 /// Bindless samplers constructor
277 constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type, 276 constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type,
278 bool is_array, bool is_shadow, bool is_buffer, bool is_indexed) 277 bool is_array, bool is_shadow, bool is_buffer, bool is_indexed)
279 : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array}, 278 : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array},
280 is_shadow{is_shadow}, is_buffer{is_buffer}, is_bindless{true}, is_indexed{is_indexed} {} 279 is_shadow{is_shadow}, is_buffer{is_buffer}, is_bindless{true}, is_indexed{is_indexed} {}
281 280
282 constexpr u32 GetIndex() const { 281 u32 index = 0; ///< Emulated index given for the this sampler.
283 return index; 282 u32 offset = 0; ///< Offset in the const buffer from where the sampler is being read.
284 } 283 u32 buffer = 0; ///< Buffer where the bindless sampler is being read (unused on bound samplers).
285 284 u32 size = 1; ///< Size of the sampler.
286 constexpr u32 GetOffset() const {
287 return offset;
288 }
289
290 constexpr u32 GetBuffer() const {
291 return buffer;
292 }
293
294 constexpr Tegra::Shader::TextureType GetType() const {
295 return type;
296 }
297
298 constexpr bool IsArray() const {
299 return is_array;
300 }
301
302 constexpr bool IsShadow() const {
303 return is_shadow;
304 }
305
306 constexpr bool IsBuffer() const {
307 return is_buffer;
308 }
309
310 constexpr bool IsBindless() const {
311 return is_bindless;
312 }
313
314 constexpr bool IsIndexed() const {
315 return is_indexed;
316 }
317
318 constexpr u32 Size() const {
319 return size;
320 }
321
322 constexpr void SetSize(u32 new_size) {
323 size = new_size;
324 }
325
326private:
327 u32 index{}; ///< Emulated index given for the this sampler.
328 u32 offset{}; ///< Offset in the const buffer from where the sampler is being read.
329 u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers).
330 u32 size{1}; ///< Size of the sampler.
331 285
332 Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) 286 Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc)
333 bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. 287 bool is_array = false; ///< Whether the texture is being sampled as an array texture or not.
334 bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. 288 bool is_shadow = false; ///< Whether the texture is being sampled as a depth texture or not.
335 bool is_buffer{}; ///< Whether the texture is a texture buffer without sampler. 289 bool is_buffer = false; ///< Whether the texture is a texture buffer without sampler.
336 bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not. 290 bool is_bindless = false; ///< Whether this sampler belongs to a bindless texture or not.
337 bool is_indexed{}; ///< Whether this sampler is an indexed array of textures. 291 bool is_indexed = false; ///< Whether this sampler is an indexed array of textures.
338}; 292};
339 293
340/// Represents a tracked bindless sampler into a direct const buffer 294/// Represents a tracked bindless sampler into a direct const buffer
@@ -379,13 +333,13 @@ private:
379 u32 offset; 333 u32 offset;
380}; 334};
381 335
382class Image final { 336struct Image {
383public: 337public:
384 /// This constructor is for bound images 338 /// Bound images constructor
385 constexpr explicit Image(u32 index, u32 offset, Tegra::Shader::ImageType type) 339 constexpr explicit Image(u32 index, u32 offset, Tegra::Shader::ImageType type)
386 : index{index}, offset{offset}, type{type} {} 340 : index{index}, offset{offset}, type{type} {}
387 341
388 /// This constructor is for bindless samplers 342 /// Bindless samplers constructor
389 constexpr explicit Image(u32 index, u32 offset, u32 buffer, Tegra::Shader::ImageType type) 343 constexpr explicit Image(u32 index, u32 offset, u32 buffer, Tegra::Shader::ImageType type)
390 : index{index}, offset{offset}, buffer{buffer}, type{type}, is_bindless{true} {} 344 : index{index}, offset{offset}, buffer{buffer}, type{type}, is_bindless{true} {}
391 345
@@ -403,53 +357,20 @@ public:
403 is_atomic = true; 357 is_atomic = true;
404 } 358 }
405 359
406 constexpr u32 GetIndex() const { 360 u32 index = 0;
407 return index; 361 u32 offset = 0;
408 } 362 u32 buffer = 0;
409
410 constexpr u32 GetOffset() const {
411 return offset;
412 }
413
414 constexpr u32 GetBuffer() const {
415 return buffer;
416 }
417
418 constexpr Tegra::Shader::ImageType GetType() const {
419 return type;
420 }
421
422 constexpr bool IsBindless() const {
423 return is_bindless;
424 }
425
426 constexpr bool IsWritten() const {
427 return is_written;
428 }
429
430 constexpr bool IsRead() const {
431 return is_read;
432 }
433
434 constexpr bool IsAtomic() const {
435 return is_atomic;
436 }
437
438private:
439 u32 index{};
440 u32 offset{};
441 u32 buffer{};
442 363
443 Tegra::Shader::ImageType type{}; 364 Tegra::Shader::ImageType type{};
444 bool is_bindless{}; 365 bool is_bindless = false;
445 bool is_written{}; 366 bool is_written = false;
446 bool is_read{}; 367 bool is_read = false;
447 bool is_atomic{}; 368 bool is_atomic = false;
448}; 369};
449 370
450struct GlobalMemoryBase { 371struct GlobalMemoryBase {
451 u32 cbuf_index{}; 372 u32 cbuf_index = 0;
452 u32 cbuf_offset{}; 373 u32 cbuf_offset = 0;
453 374
454 bool operator<(const GlobalMemoryBase& rhs) const { 375 bool operator<(const GlobalMemoryBase& rhs) const {
455 return std::tie(cbuf_index, cbuf_offset) < std::tie(rhs.cbuf_index, rhs.cbuf_offset); 376 return std::tie(cbuf_index, cbuf_offset) < std::tie(rhs.cbuf_index, rhs.cbuf_offset);
@@ -463,7 +384,7 @@ struct MetaArithmetic {
463 384
464/// Parameters describing a texture sampler 385/// Parameters describing a texture sampler
465struct MetaTexture { 386struct MetaTexture {
466 const Sampler& sampler; 387 Sampler sampler;
467 Node array; 388 Node array;
468 Node depth_compare; 389 Node depth_compare;
469 std::vector<Node> aoffi; 390 std::vector<Node> aoffi;
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index c6e7bdf50..ae5e414cb 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -29,12 +29,11 @@ using ProgramCode = std::vector<u64>;
29 29
30constexpr u32 MAX_PROGRAM_LENGTH = 0x1000; 30constexpr u32 MAX_PROGRAM_LENGTH = 0x1000;
31 31
32class ConstBuffer { 32struct ConstBuffer {
33public: 33 constexpr explicit ConstBuffer(u32 max_offset, bool is_indirect)
34 explicit ConstBuffer(u32 max_offset, bool is_indirect)
35 : max_offset{max_offset}, is_indirect{is_indirect} {} 34 : max_offset{max_offset}, is_indirect{is_indirect} {}
36 35
37 ConstBuffer() = default; 36 constexpr ConstBuffer() = default;
38 37
39 void MarkAsUsed(u64 offset) { 38 void MarkAsUsed(u64 offset) {
40 max_offset = std::max(max_offset, static_cast<u32>(offset)); 39 max_offset = std::max(max_offset, static_cast<u32>(offset));
@@ -57,8 +56,8 @@ public:
57 } 56 }
58 57
59private: 58private:
60 u32 max_offset{}; 59 u32 max_offset = 0;
61 bool is_indirect{}; 60 bool is_indirect = false;
62}; 61};
63 62
64struct GlobalMemoryUsage { 63struct GlobalMemoryUsage {
@@ -332,12 +331,13 @@ private:
332 std::optional<u32> buffer = std::nullopt); 331 std::optional<u32> buffer = std::nullopt);
333 332
334 /// Accesses a texture sampler 333 /// Accesses a texture sampler
335 const Sampler* GetSampler(const Tegra::Shader::Sampler& sampler, 334 std::optional<Sampler> GetSampler(const Tegra::Shader::Sampler& sampler,
336 std::optional<SamplerInfo> sampler_info = std::nullopt); 335 std::optional<SamplerInfo> sampler_info = std::nullopt);
337 336
338 /// Accesses a texture sampler for a bindless texture. 337 /// Accesses a texture sampler for a bindless texture.
339 const Sampler* GetBindlessSampler(Tegra::Shader::Register reg, Node& index_var, 338 std::optional<Sampler> GetBindlessSampler(
340 std::optional<SamplerInfo> sampler_info = std::nullopt); 339 Tegra::Shader::Register reg, Node& index_var,
340 std::optional<SamplerInfo> sampler_info = std::nullopt);
341 341
342 /// Accesses an image. 342 /// Accesses an image.
343 Image& GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type); 343 Image& GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type);