summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp26
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp99
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp21
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp26
-rw-r--r--src/video_core/shader/node.h2
8 files changed, 107 insertions, 74 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e1965fb21..3fcd319fd 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -36,6 +36,7 @@ namespace OpenGL {
36 36
37using Maxwell = Tegra::Engines::Maxwell3D::Regs; 37using Maxwell = Tegra::Engines::Maxwell3D::Regs;
38 38
39using Tegra::Engines::ShaderType;
39using VideoCore::Surface::PixelFormat; 40using VideoCore::Surface::PixelFormat;
40using VideoCore::Surface::SurfaceTarget; 41using VideoCore::Surface::SurfaceTarget;
41using VideoCore::Surface::SurfaceType; 42using VideoCore::Surface::SurfaceType;
@@ -56,8 +57,7 @@ namespace {
56 57
57template <typename Engine, typename Entry> 58template <typename Engine, typename Entry>
58Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry, 59Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry,
59 Tegra::Engines::ShaderType shader_type, 60 ShaderType shader_type, std::size_t index = 0) {
60 std::size_t index = 0) {
61 if (entry.IsBindless()) { 61 if (entry.IsBindless()) {
62 const Tegra::Texture::TextureHandle tex_handle = 62 const Tegra::Texture::TextureHandle tex_handle =
63 engine.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset()); 63 engine.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset());
@@ -910,15 +910,10 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader&
910 const auto& maxwell3d = system.GPU().Maxwell3D(); 910 const auto& maxwell3d = system.GPU().Maxwell3D();
911 u32 binding = device.GetBaseBindings(stage_index).sampler; 911 u32 binding = device.GetBaseBindings(stage_index).sampler;
912 for (const auto& entry : shader->GetShaderEntries().samplers) { 912 for (const auto& entry : shader->GetShaderEntries().samplers) {
913 const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index); 913 const auto shader_type = static_cast<ShaderType>(stage_index);
914 if (!entry.IsIndexed()) { 914 for (std::size_t i = 0; i < entry.Size(); ++i) {
915 const auto texture = GetTextureInfo(maxwell3d, entry, shader_type); 915 const auto texture = GetTextureInfo(maxwell3d, entry, shader_type, i);
916 SetupTexture(binding++, texture, entry); 916 SetupTexture(binding++, texture, entry);
917 } else {
918 for (std::size_t i = 0; i < entry.Size(); ++i) {
919 const auto texture = GetTextureInfo(maxwell3d, entry, shader_type, i);
920 SetupTexture(binding++, texture, entry);
921 }
922 } 917 }
923 } 918 }
924} 919}
@@ -928,16 +923,9 @@ void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) {
928 const auto& compute = system.GPU().KeplerCompute(); 923 const auto& compute = system.GPU().KeplerCompute();
929 u32 binding = 0; 924 u32 binding = 0;
930 for (const auto& entry : kernel->GetShaderEntries().samplers) { 925 for (const auto& entry : kernel->GetShaderEntries().samplers) {
931 if (!entry.IsIndexed()) { 926 for (std::size_t i = 0; i < entry.Size(); ++i) {
932 const auto texture = 927 const auto texture = GetTextureInfo(compute, entry, ShaderType::Compute, i);
933 GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute);
934 SetupTexture(binding++, texture, entry); 928 SetupTexture(binding++, texture, entry);
935 } else {
936 for (std::size_t i = 0; i < entry.Size(); ++i) {
937 const auto texture =
938 GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute, i);
939 SetupTexture(binding++, texture, entry);
940 }
941 } 929 }
942 } 930 }
943} 931}
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index 9d5b8de7a..60f57d83e 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -73,7 +73,7 @@ UniqueDescriptorUpdateTemplate VKComputePipeline::CreateDescriptorUpdateTemplate
73 std::vector<vk::DescriptorUpdateTemplateEntry> template_entries; 73 std::vector<vk::DescriptorUpdateTemplateEntry> template_entries;
74 u32 binding = 0; 74 u32 binding = 0;
75 u32 offset = 0; 75 u32 offset = 0;
76 FillDescriptorUpdateTemplateEntries(device, entries, binding, offset, template_entries); 76 FillDescriptorUpdateTemplateEntries(entries, binding, offset, template_entries);
77 if (template_entries.empty()) { 77 if (template_entries.empty()) {
78 // If the shader doesn't use descriptor sets, skip template creation. 78 // If the shader doesn't use descriptor sets, skip template creation.
79 return UniqueDescriptorUpdateTemplate{}; 79 return UniqueDescriptorUpdateTemplate{};
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index b155dfb49..6a02403c1 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -97,8 +97,7 @@ UniqueDescriptorUpdateTemplate VKGraphicsPipeline::CreateDescriptorUpdateTemplat
97 u32 offset = 0; 97 u32 offset = 0;
98 for (const auto& stage : program) { 98 for (const auto& stage : program) {
99 if (stage) { 99 if (stage) {
100 FillDescriptorUpdateTemplateEntries(device, stage->entries, binding, offset, 100 FillDescriptorUpdateTemplateEntries(stage->entries, binding, offset, template_entries);
101 template_entries);
102 } 101 }
103 } 102 }
104 if (template_entries.empty()) { 103 if (template_entries.empty()) {
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 7ddf7d3ee..696e4b291 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -36,6 +36,13 @@ using Tegra::Engines::ShaderType;
36 36
37namespace { 37namespace {
38 38
39// C++20's using enum
40constexpr auto eUniformBuffer = vk::DescriptorType::eUniformBuffer;
41constexpr auto eStorageBuffer = vk::DescriptorType::eStorageBuffer;
42constexpr auto eUniformTexelBuffer = vk::DescriptorType::eUniformTexelBuffer;
43constexpr auto eCombinedImageSampler = vk::DescriptorType::eCombinedImageSampler;
44constexpr auto eStorageImage = vk::DescriptorType::eStorageImage;
45
39constexpr VideoCommon::Shader::CompilerSettings compiler_settings{ 46constexpr VideoCommon::Shader::CompilerSettings compiler_settings{
40 VideoCommon::Shader::CompileDepth::FullDecompile}; 47 VideoCommon::Shader::CompileDepth::FullDecompile};
41 48
@@ -119,23 +126,32 @@ ShaderType GetShaderType(Maxwell::ShaderProgram program) {
119 } 126 }
120} 127}
121 128
129template <vk::DescriptorType descriptor_type, class Container>
130void AddBindings(std::vector<vk::DescriptorSetLayoutBinding>& bindings, u32& binding,
131 vk::ShaderStageFlags stage_flags, const Container& container) {
132 const u32 num_entries = static_cast<u32>(std::size(container));
133 for (std::size_t i = 0; i < num_entries; ++i) {
134 u32 count = 1;
135 if constexpr (descriptor_type == eCombinedImageSampler) {
136 // Combined image samplers can be arrayed.
137 count = container[i].Size();
138 }
139 bindings.emplace_back(binding++, descriptor_type, count, stage_flags, nullptr);
140 }
141}
142
122u32 FillDescriptorLayout(const ShaderEntries& entries, 143u32 FillDescriptorLayout(const ShaderEntries& entries,
123 std::vector<vk::DescriptorSetLayoutBinding>& bindings, 144 std::vector<vk::DescriptorSetLayoutBinding>& bindings,
124 Maxwell::ShaderProgram program_type, u32 base_binding) { 145 Maxwell::ShaderProgram program_type, u32 base_binding) {
125 const ShaderType stage = GetStageFromProgram(program_type); 146 const ShaderType stage = GetStageFromProgram(program_type);
126 const vk::ShaderStageFlags stage_flags = MaxwellToVK::ShaderStage(stage); 147 const vk::ShaderStageFlags flags = MaxwellToVK::ShaderStage(stage);
127 148
128 u32 binding = base_binding; 149 u32 binding = base_binding;
129 const auto AddBindings = [&](vk::DescriptorType descriptor_type, std::size_t num_entries) { 150 AddBindings<eUniformBuffer>(bindings, binding, flags, entries.const_buffers);
130 for (std::size_t i = 0; i < num_entries; ++i) { 151 AddBindings<eStorageBuffer>(bindings, binding, flags, entries.global_buffers);
131 bindings.emplace_back(binding++, descriptor_type, 1, stage_flags, nullptr); 152 AddBindings<eUniformTexelBuffer>(bindings, binding, flags, entries.texel_buffers);
132 } 153 AddBindings<eCombinedImageSampler>(bindings, binding, flags, entries.samplers);
133 }; 154 AddBindings<eStorageImage>(bindings, binding, flags, entries.images);
134 AddBindings(vk::DescriptorType::eUniformBuffer, entries.const_buffers.size());
135 AddBindings(vk::DescriptorType::eStorageBuffer, entries.global_buffers.size());
136 AddBindings(vk::DescriptorType::eUniformTexelBuffer, entries.texel_buffers.size());
137 AddBindings(vk::DescriptorType::eCombinedImageSampler, entries.samplers.size());
138 AddBindings(vk::DescriptorType::eStorageImage, entries.images.size());
139 return binding; 155 return binding;
140} 156}
141 157
@@ -361,32 +377,45 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
361 return {std::move(program), std::move(bindings)}; 377 return {std::move(program), std::move(bindings)};
362} 378}
363 379
364void FillDescriptorUpdateTemplateEntries( 380template <vk::DescriptorType descriptor_type, class Container>
365 const VKDevice& device, const ShaderEntries& entries, u32& binding, u32& offset, 381void AddEntry(std::vector<vk::DescriptorUpdateTemplateEntry>& template_entries, u32& binding,
366 std::vector<vk::DescriptorUpdateTemplateEntry>& template_entries) { 382 u32& offset, const Container& container) {
367 static constexpr auto entry_size = static_cast<u32>(sizeof(DescriptorUpdateEntry)); 383 static constexpr u32 entry_size = static_cast<u32>(sizeof(DescriptorUpdateEntry));
368 const auto AddEntry = [&](vk::DescriptorType descriptor_type, std::size_t count_) { 384 const u32 count = static_cast<u32>(std::size(container));
369 const u32 count = static_cast<u32>(count_); 385
370 if (descriptor_type == vk::DescriptorType::eUniformTexelBuffer && 386 if constexpr (descriptor_type == eCombinedImageSampler) {
371 device.GetDriverID() == vk::DriverIdKHR::eNvidiaProprietary) { 387 for (u32 i = 0; i < count; ++i) {
372 // Nvidia has a bug where updating multiple uniform texels at once causes the driver to 388 const u32 num_samplers = container[i].Size();
373 // crash. 389 template_entries.emplace_back(binding, 0, num_samplers, descriptor_type, offset,
374 for (u32 i = 0; i < count; ++i) { 390 entry_size);
375 template_entries.emplace_back(binding + i, 0, 1, descriptor_type, 391 ++binding;
376 offset + i * entry_size, entry_size); 392 offset += num_samplers * entry_size;
377 }
378 } else if (count != 0) {
379 template_entries.emplace_back(binding, 0, count, descriptor_type, offset, entry_size);
380 } 393 }
381 offset += count * entry_size; 394 return;
382 binding += count; 395 }
383 };
384 396
385 AddEntry(vk::DescriptorType::eUniformBuffer, entries.const_buffers.size()); 397 if constexpr (descriptor_type == eUniformTexelBuffer) {
386 AddEntry(vk::DescriptorType::eStorageBuffer, entries.global_buffers.size()); 398 // Nvidia has a bug where updating multiple uniform texels at once causes the driver to
387 AddEntry(vk::DescriptorType::eUniformTexelBuffer, entries.texel_buffers.size()); 399 // crash.
388 AddEntry(vk::DescriptorType::eCombinedImageSampler, entries.samplers.size()); 400 for (u32 i = 0; i < count; ++i) {
389 AddEntry(vk::DescriptorType::eStorageImage, entries.images.size()); 401 template_entries.emplace_back(binding + i, 0, 1, descriptor_type,
402 offset + i * entry_size, entry_size);
403 }
404 } else if (count > 0) {
405 template_entries.emplace_back(binding, 0, count, descriptor_type, offset, entry_size);
406 }
407 offset += count * entry_size;
408 binding += count;
409}
410
411void FillDescriptorUpdateTemplateEntries(
412 const ShaderEntries& entries, u32& binding, u32& offset,
413 std::vector<vk::DescriptorUpdateTemplateEntry>& template_entries) {
414 AddEntry<eUniformBuffer>(template_entries, offset, binding, entries.const_buffers);
415 AddEntry<eStorageBuffer>(template_entries, offset, binding, entries.global_buffers);
416 AddEntry<eUniformTexelBuffer>(template_entries, offset, binding, entries.texel_buffers);
417 AddEntry<eCombinedImageSampler>(template_entries, offset, binding, entries.samplers);
418 AddEntry<eStorageImage>(template_entries, offset, binding, entries.images);
390} 419}
391 420
392} // namespace Vulkan 421} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 8678fc9c3..92a670cc7 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -194,7 +194,7 @@ private:
194}; 194};
195 195
196void FillDescriptorUpdateTemplateEntries( 196void FillDescriptorUpdateTemplateEntries(
197 const VKDevice& device, const ShaderEntries& entries, u32& binding, u32& offset, 197 const ShaderEntries& entries, u32& binding, u32& offset,
198 std::vector<vk::DescriptorUpdateTemplateEntry>& template_entries); 198 std::vector<vk::DescriptorUpdateTemplateEntry>& template_entries);
199 199
200} // namespace Vulkan 200} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 3bf86da87..3fe28c204 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -105,17 +105,20 @@ void TransitionImages(const std::vector<ImageView>& views, vk::PipelineStageFlag
105 105
106template <typename Engine, typename Entry> 106template <typename Engine, typename Entry>
107Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry, 107Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry,
108 std::size_t stage) { 108 std::size_t stage, std::size_t index = 0) {
109 const auto stage_type = static_cast<Tegra::Engines::ShaderType>(stage); 109 const auto stage_type = static_cast<Tegra::Engines::ShaderType>(stage);
110 if (entry.IsBindless()) { 110 if (entry.IsBindless()) {
111 const Tegra::Texture::TextureHandle tex_handle = 111 const Tegra::Texture::TextureHandle tex_handle =
112 engine.AccessConstBuffer32(stage_type, entry.GetBuffer(), entry.GetOffset()); 112 engine.AccessConstBuffer32(stage_type, entry.GetBuffer(), entry.GetOffset());
113 return engine.GetTextureInfo(tex_handle); 113 return engine.GetTextureInfo(tex_handle);
114 } 114 }
115 const auto& gpu_profile = engine.AccessGuestDriverProfile();
116 const u32 entry_offset = static_cast<u32>(index * gpu_profile.GetTextureHandlerSize());
117 const u32 offset = entry.GetOffset() + entry_offset;
115 if constexpr (std::is_same_v<Engine, Tegra::Engines::Maxwell3D>) { 118 if constexpr (std::is_same_v<Engine, Tegra::Engines::Maxwell3D>) {
116 return engine.GetStageTexture(stage_type, entry.GetOffset()); 119 return engine.GetStageTexture(stage_type, offset);
117 } else { 120 } else {
118 return engine.GetTexture(entry.GetOffset()); 121 return engine.GetTexture(offset);
119 } 122 }
120} 123}
121 124
@@ -836,8 +839,10 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
836 MICROPROFILE_SCOPE(Vulkan_Textures); 839 MICROPROFILE_SCOPE(Vulkan_Textures);
837 const auto& gpu = system.GPU().Maxwell3D(); 840 const auto& gpu = system.GPU().Maxwell3D();
838 for (const auto& entry : entries.samplers) { 841 for (const auto& entry : entries.samplers) {
839 const auto texture = GetTextureInfo(gpu, entry, stage); 842 for (std::size_t i = 0; i < entry.Size(); ++i) {
840 SetupTexture(texture, entry); 843 const auto texture = GetTextureInfo(gpu, entry, stage, i);
844 SetupTexture(texture, entry);
845 }
841 } 846 }
842} 847}
843 848
@@ -886,8 +891,10 @@ void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
886 MICROPROFILE_SCOPE(Vulkan_Textures); 891 MICROPROFILE_SCOPE(Vulkan_Textures);
887 const auto& gpu = system.GPU().KeplerCompute(); 892 const auto& gpu = system.GPU().KeplerCompute();
888 for (const auto& entry : entries.samplers) { 893 for (const auto& entry : entries.samplers) {
889 const auto texture = GetTextureInfo(gpu, entry, ComputeShaderIndex); 894 for (std::size_t i = 0; i < entry.Size(); ++i) {
890 SetupTexture(texture, entry); 895 const auto texture = GetTextureInfo(gpu, entry, ComputeShaderIndex, i);
896 SetupTexture(texture, entry);
897 }
891 } 898 }
892} 899}
893 900
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index f64354a0c..cfcca5af0 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -69,8 +69,9 @@ struct TexelBuffer {
69 69
70struct SampledImage { 70struct SampledImage {
71 Id image_type{}; 71 Id image_type{};
72 Id sampled_image_type{}; 72 Id sampler_type{};
73 Id sampler{}; 73 Id sampler_pointer_type{};
74 Id variable{};
74}; 75};
75 76
76struct StorageImage { 77struct StorageImage {
@@ -833,16 +834,20 @@ private:
833 constexpr int sampled = 1; 834 constexpr int sampled = 1;
834 constexpr auto format = spv::ImageFormat::Unknown; 835 constexpr auto format = spv::ImageFormat::Unknown;
835 const Id image_type = TypeImage(t_float, dim, depth, arrayed, ms, sampled, format); 836 const Id image_type = TypeImage(t_float, dim, depth, arrayed, ms, sampled, format);
836 const Id sampled_image_type = TypeSampledImage(image_type); 837 const Id sampler_type = TypeSampledImage(image_type);
837 const Id pointer_type = 838 const Id sampler_pointer_type =
838 TypePointer(spv::StorageClass::UniformConstant, sampled_image_type); 839 TypePointer(spv::StorageClass::UniformConstant, sampler_type);
840 const Id type = sampler.IsIndexed()
841 ? TypeArray(sampler_type, Constant(t_uint, sampler.Size()))
842 : sampler_type;
843 const Id pointer_type = TypePointer(spv::StorageClass::UniformConstant, type);
839 const Id id = OpVariable(pointer_type, spv::StorageClass::UniformConstant); 844 const Id id = OpVariable(pointer_type, spv::StorageClass::UniformConstant);
840 AddGlobalVariable(Name(id, fmt::format("sampler_{}", sampler.GetIndex()))); 845 AddGlobalVariable(Name(id, fmt::format("sampler_{}", sampler.GetIndex())));
841 Decorate(id, spv::Decoration::Binding, binding++); 846 Decorate(id, spv::Decoration::Binding, binding++);
842 Decorate(id, spv::Decoration::DescriptorSet, DESCRIPTOR_SET); 847 Decorate(id, spv::Decoration::DescriptorSet, DESCRIPTOR_SET);
843 848
844 sampled_images.emplace(sampler.GetIndex(), 849 sampled_images.emplace(sampler.GetIndex(), SampledImage{image_type, sampler_type,
845 SampledImage{image_type, sampled_image_type, id}); 850 sampler_pointer_type, id});
846 } 851 }
847 return binding; 852 return binding;
848 } 853 }
@@ -1525,7 +1530,12 @@ private:
1525 ASSERT(!meta.sampler.IsBuffer()); 1530 ASSERT(!meta.sampler.IsBuffer());
1526 1531
1527 const auto& entry = sampled_images.at(meta.sampler.GetIndex()); 1532 const auto& entry = sampled_images.at(meta.sampler.GetIndex());
1528 return OpLoad(entry.sampled_image_type, entry.sampler); 1533 Id sampler = entry.variable;
1534 if (meta.sampler.IsIndexed()) {
1535 const Id index = AsInt(Visit(meta.index));
1536 sampler = OpAccessChain(entry.sampler_pointer_type, sampler, index);
1537 }
1538 return OpLoad(entry.sampler_type, sampler);
1529 } 1539 }
1530 1540
1531 Id GetTextureImage(Operation operation) { 1541 Id GetTextureImage(Operation operation) {
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index a0a7b9111..a1828546e 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -299,7 +299,7 @@ private:
299 u32 index{}; ///< Emulated index given for the this sampler. 299 u32 index{}; ///< Emulated index given for the this sampler.
300 u32 offset{}; ///< Offset in the const buffer from where the sampler is being read. 300 u32 offset{}; ///< Offset in the const buffer from where the sampler is being read.
301 u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers). 301 u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers).
302 u32 size{}; ///< Size of the sampler if indexed. 302 u32 size{1}; ///< Size of the sampler.
303 303
304 Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) 304 Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc)
305 bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. 305 bool is_array{}; ///< Whether the texture is being sampled as an array texture or not.