summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/environment.h2
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp80
-rw-r--r--src/shader_recompiler/shader_info.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp31
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp25
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp32
6 files changed, 127 insertions, 49 deletions
diff --git a/src/shader_recompiler/environment.h b/src/shader_recompiler/environment.h
index 1c50ae51e..090bc1c08 100644
--- a/src/shader_recompiler/environment.h
+++ b/src/shader_recompiler/environment.h
@@ -17,7 +17,7 @@ public:
17 17
18 [[nodiscard]] virtual u32 ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) = 0; 18 [[nodiscard]] virtual u32 ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) = 0;
19 19
20 [[nodiscard]] virtual TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) = 0; 20 [[nodiscard]] virtual TextureType ReadTextureType(u32 raw_handle) = 0;
21 21
22 [[nodiscard]] virtual u32 TextureBoundBuffer() const = 0; 22 [[nodiscard]] virtual u32 TextureBoundBuffer() const = 0;
23 23
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index e1d5a2ce1..5ac485522 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -19,6 +19,9 @@ namespace {
19struct ConstBufferAddr { 19struct ConstBufferAddr {
20 u32 index; 20 u32 index;
21 u32 offset; 21 u32 offset;
22 u32 secondary_index;
23 u32 secondary_offset;
24 bool has_secondary;
22}; 25};
23 26
24struct TextureInst { 27struct TextureInst {
@@ -109,9 +112,38 @@ bool IsTextureInstruction(const IR::Inst& inst) {
109 return IndexedInstruction(inst) != IR::Opcode::Void; 112 return IndexedInstruction(inst) != IR::Opcode::Void;
110} 113}
111 114
115std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst);
116
117std::optional<ConstBufferAddr> Track(const IR::Value& value) {
118 return IR::BreadthFirstSearch(value, TryGetConstBuffer);
119}
120
112std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) { 121std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
113 if (inst->GetOpcode() != IR::Opcode::GetCbufU32) { 122 switch (inst->GetOpcode()) {
123 default:
114 return std::nullopt; 124 return std::nullopt;
125 case IR::Opcode::BitwiseOr32: {
126 std::optional lhs{Track(inst->Arg(0))};
127 std::optional rhs{Track(inst->Arg(1))};
128 if (!lhs || !rhs) {
129 return std::nullopt;
130 }
131 if (lhs->has_secondary || rhs->has_secondary) {
132 return std::nullopt;
133 }
134 if (lhs->index > rhs->index || lhs->offset > rhs->offset) {
135 std::swap(lhs, rhs);
136 }
137 return ConstBufferAddr{
138 .index = lhs->index,
139 .offset = lhs->offset,
140 .secondary_index = rhs->index,
141 .secondary_offset = rhs->offset,
142 .has_secondary = true,
143 };
144 }
145 case IR::Opcode::GetCbufU32:
146 break;
115 } 147 }
116 const IR::Value index{inst->Arg(0)}; 148 const IR::Value index{inst->Arg(0)};
117 const IR::Value offset{inst->Arg(1)}; 149 const IR::Value offset{inst->Arg(1)};
@@ -127,13 +159,12 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
127 return ConstBufferAddr{ 159 return ConstBufferAddr{
128 .index{index.U32()}, 160 .index{index.U32()},
129 .offset{offset.U32()}, 161 .offset{offset.U32()},
162 .secondary_index = 0,
163 .secondary_offset = 0,
164 .has_secondary = false,
130 }; 165 };
131} 166}
132 167
133std::optional<ConstBufferAddr> Track(const IR::Value& value) {
134 return IR::BreadthFirstSearch(value, TryGetConstBuffer);
135}
136
137TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { 168TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
138 ConstBufferAddr addr; 169 ConstBufferAddr addr;
139 if (IsBindless(inst)) { 170 if (IsBindless(inst)) {
@@ -146,6 +177,9 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
146 addr = ConstBufferAddr{ 177 addr = ConstBufferAddr{
147 .index = env.TextureBoundBuffer(), 178 .index = env.TextureBoundBuffer(),
148 .offset = inst.Arg(0).U32(), 179 .offset = inst.Arg(0).U32(),
180 .secondary_index = 0,
181 .secondary_offset = 0,
182 .has_secondary = false,
149 }; 183 };
150 } 184 }
151 return TextureInst{ 185 return TextureInst{
@@ -155,6 +189,14 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
155 }; 189 };
156} 190}
157 191
192TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
193 const u32 secondary_index{cbuf.has_secondary ? cbuf.index : cbuf.secondary_index};
194 const u32 secondary_offset{cbuf.has_secondary ? cbuf.offset : cbuf.secondary_offset};
195 const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset)};
196 const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)};
197 return env.ReadTextureType(lhs_raw | rhs_raw);
198}
199
158class Descriptors { 200class Descriptors {
159public: 201public:
160 explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, 202 explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_,
@@ -167,8 +209,11 @@ public:
167 209
168 u32 Add(const TextureBufferDescriptor& desc) { 210 u32 Add(const TextureBufferDescriptor& desc) {
169 return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) { 211 return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) {
170 return desc.cbuf_index == existing.cbuf_index && 212 return desc.has_secondary == existing.has_secondary &&
171 desc.cbuf_offset == existing.cbuf_offset; 213 desc.cbuf_index == existing.cbuf_index &&
214 desc.cbuf_offset == existing.cbuf_offset &&
215 desc.secondary_cbuf_index == existing.secondary_cbuf_index &&
216 desc.secondary_cbuf_offset == existing.secondary_cbuf_offset;
172 }); 217 });
173 } 218 }
174 219
@@ -181,8 +226,12 @@ public:
181 226
182 u32 Add(const TextureDescriptor& desc) { 227 u32 Add(const TextureDescriptor& desc) {
183 return Add(texture_descriptors, desc, [&desc](const auto& existing) { 228 return Add(texture_descriptors, desc, [&desc](const auto& existing) {
184 return desc.cbuf_index == existing.cbuf_index && 229 return desc.type == existing.type && desc.is_depth == existing.is_depth &&
185 desc.cbuf_offset == existing.cbuf_offset && desc.type == existing.type; 230 desc.has_secondary == existing.has_secondary &&
231 desc.cbuf_index == existing.cbuf_index &&
232 desc.cbuf_offset == existing.cbuf_offset &&
233 desc.secondary_cbuf_index == existing.secondary_cbuf_index &&
234 desc.secondary_cbuf_offset == existing.secondary_cbuf_offset;
186 }); 235 });
187 } 236 }
188 237
@@ -247,14 +296,14 @@ void TexturePass(Environment& env, IR::Program& program) {
247 auto flags{inst->Flags<IR::TextureInstInfo>()}; 296 auto flags{inst->Flags<IR::TextureInstInfo>()};
248 switch (inst->GetOpcode()) { 297 switch (inst->GetOpcode()) {
249 case IR::Opcode::ImageQueryDimensions: 298 case IR::Opcode::ImageQueryDimensions:
250 flags.type.Assign(env.ReadTextureType(cbuf.index, cbuf.offset)); 299 flags.type.Assign(ReadTextureType(env, cbuf));
251 inst->SetFlags(flags); 300 inst->SetFlags(flags);
252 break; 301 break;
253 case IR::Opcode::ImageFetch: 302 case IR::Opcode::ImageFetch:
254 if (flags.type != TextureType::Color1D) { 303 if (flags.type != TextureType::Color1D) {
255 break; 304 break;
256 } 305 }
257 if (env.ReadTextureType(cbuf.index, cbuf.offset) == TextureType::Buffer) { 306 if (ReadTextureType(env, cbuf) == TextureType::Buffer) {
258 // Replace with the bound texture type only when it's a texture buffer 307 // Replace with the bound texture type only when it's a texture buffer
259 // If the instruction is 1D and the bound type is 2D, don't change the code and let 308 // If the instruction is 1D and the bound type is 2D, don't change the code and let
260 // the rasterizer robustness handle it 309 // the rasterizer robustness handle it
@@ -270,6 +319,9 @@ void TexturePass(Environment& env, IR::Program& program) {
270 switch (inst->GetOpcode()) { 319 switch (inst->GetOpcode()) {
271 case IR::Opcode::ImageRead: 320 case IR::Opcode::ImageRead:
272 case IR::Opcode::ImageWrite: { 321 case IR::Opcode::ImageWrite: {
322 if (cbuf.has_secondary) {
323 throw NotImplementedException("Unexpected separate sampler");
324 }
273 const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; 325 const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite};
274 if (flags.type == TextureType::Buffer) { 326 if (flags.type == TextureType::Buffer) {
275 index = descriptors.Add(ImageBufferDescriptor{ 327 index = descriptors.Add(ImageBufferDescriptor{
@@ -294,16 +346,22 @@ void TexturePass(Environment& env, IR::Program& program) {
294 default: 346 default:
295 if (flags.type == TextureType::Buffer) { 347 if (flags.type == TextureType::Buffer) {
296 index = descriptors.Add(TextureBufferDescriptor{ 348 index = descriptors.Add(TextureBufferDescriptor{
349 .has_secondary = cbuf.has_secondary,
297 .cbuf_index = cbuf.index, 350 .cbuf_index = cbuf.index,
298 .cbuf_offset = cbuf.offset, 351 .cbuf_offset = cbuf.offset,
352 .secondary_cbuf_index = cbuf.secondary_index,
353 .secondary_cbuf_offset = cbuf.secondary_offset,
299 .count = 1, 354 .count = 1,
300 }); 355 });
301 } else { 356 } else {
302 index = descriptors.Add(TextureDescriptor{ 357 index = descriptors.Add(TextureDescriptor{
303 .type = flags.type, 358 .type = flags.type,
304 .is_depth = flags.is_depth != 0, 359 .is_depth = flags.is_depth != 0,
360 .has_secondary = cbuf.has_secondary,
305 .cbuf_index = cbuf.index, 361 .cbuf_index = cbuf.index,
306 .cbuf_offset = cbuf.offset, 362 .cbuf_offset = cbuf.offset,
363 .secondary_cbuf_index = cbuf.secondary_index,
364 .secondary_cbuf_offset = cbuf.secondary_offset,
307 .count = 1, 365 .count = 1,
308 }); 366 });
309 } 367 }
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index 50b4d1c05..0f45bdfb6 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -61,8 +61,11 @@ struct StorageBufferDescriptor {
61}; 61};
62 62
63struct TextureBufferDescriptor { 63struct TextureBufferDescriptor {
64 bool has_secondary;
64 u32 cbuf_index; 65 u32 cbuf_index;
65 u32 cbuf_offset; 66 u32 cbuf_offset;
67 u32 secondary_cbuf_index;
68 u32 secondary_cbuf_offset;
66 u32 count; 69 u32 count;
67}; 70};
68using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; 71using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>;
@@ -79,8 +82,11 @@ using ImageBufferDescriptors = boost::container::small_vector<ImageBufferDescrip
79struct TextureDescriptor { 82struct TextureDescriptor {
80 TextureType type; 83 TextureType type;
81 bool is_depth; 84 bool is_depth;
85 bool has_secondary;
82 u32 cbuf_index; 86 u32 cbuf_index;
83 u32 cbuf_offset; 87 u32 cbuf_offset;
88 u32 secondary_cbuf_index;
89 u32 secondary_cbuf_offset;
84 u32 count; 90 u32 count;
85}; 91};
86using TextureDescriptors = boost::container::small_vector<TextureDescriptor, 12>; 92using TextureDescriptors = boost::container::small_vector<TextureDescriptor, 12>;
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index 3c907ec5a..45d837ca4 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -88,23 +88,34 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
88 boost::container::static_vector<u32, max_elements> image_view_indices; 88 boost::container::static_vector<u32, max_elements> image_view_indices;
89 boost::container::static_vector<VkSampler, max_elements> samplers; 89 boost::container::static_vector<VkSampler, max_elements> samplers;
90 90
91 const auto& launch_desc{kepler_compute.launch_description}; 91 const auto& qmd{kepler_compute.launch_description};
92 const auto& cbufs{launch_desc.const_buffer_config}; 92 const auto& cbufs{qmd.const_buffer_config};
93 const bool via_header_index{launch_desc.linked_tsc}; 93 const bool via_header_index{qmd.linked_tsc != 0};
94 const auto read_handle{[&](u32 cbuf_index, u32 cbuf_offset) { 94 const auto read_handle{[&](const auto& desc) {
95 ASSERT(((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) != 0); 95 ASSERT(((qmd.const_buffer_enable_mask >> desc.cbuf_index) & 1) != 0);
96 const GPUVAddr addr{cbufs[cbuf_index].Address() + cbuf_offset}; 96 const GPUVAddr addr{cbufs[desc.cbuf_index].Address() + desc.cbuf_offset};
97 const u32 raw_handle{gpu_memory.Read<u32>(addr)}; 97 if constexpr (std::is_same_v<decltype(desc), const Shader::TextureDescriptor&> ||
98 return TextureHandle(raw_handle, via_header_index); 98 std::is_same_v<decltype(desc), const Shader::TextureBufferDescriptor&>) {
99 if (desc.has_secondary) {
100 ASSERT(((qmd.const_buffer_enable_mask >> desc.secondary_cbuf_index) & 1) != 0);
101 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
102 desc.secondary_cbuf_offset};
103 const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
104 const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
105 const u32 raw{lhs_raw | rhs_raw};
106 return TextureHandle{raw, via_header_index};
107 }
108 }
109 return TextureHandle{gpu_memory.Read<u32>(addr), via_header_index};
99 }}; 110 }};
100 const auto add_image{[&](const auto& desc) { 111 const auto add_image{[&](const auto& desc) {
101 const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; 112 const TextureHandle handle{read_handle(desc)};
102 image_view_indices.push_back(handle.image); 113 image_view_indices.push_back(handle.image);
103 }}; 114 }};
104 std::ranges::for_each(info.texture_buffer_descriptors, add_image); 115 std::ranges::for_each(info.texture_buffer_descriptors, add_image);
105 std::ranges::for_each(info.image_buffer_descriptors, add_image); 116 std::ranges::for_each(info.image_buffer_descriptors, add_image);
106 for (const auto& desc : info.texture_descriptors) { 117 for (const auto& desc : info.texture_descriptors) {
107 const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; 118 const TextureHandle handle{read_handle(desc)};
108 image_view_indices.push_back(handle.image); 119 image_view_indices.push_back(handle.image);
109 120
110 Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); 121 Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler);
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index d5e9dae0f..08f00b9ce 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -169,20 +169,31 @@ void GraphicsPipeline::Configure(bool is_indexed) {
169 ++index; 169 ++index;
170 } 170 }
171 const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; 171 const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers};
172 const auto read_handle{[&](u32 cbuf_index, u32 cbuf_offset) { 172 const auto read_handle{[&](const auto& desc) {
173 ASSERT(cbufs[cbuf_index].enabled); 173 ASSERT(cbufs[desc.cbuf_index].enabled);
174 const GPUVAddr addr{cbufs[cbuf_index].address + cbuf_offset}; 174 const GPUVAddr addr{cbufs[desc.cbuf_index].address + desc.cbuf_offset};
175 const u32 raw_handle{gpu_memory.Read<u32>(addr)}; 175 if constexpr (std::is_same_v<decltype(desc), const Shader::TextureDescriptor&> ||
176 return TextureHandle(raw_handle, via_header_index); 176 std::is_same_v<decltype(desc), const Shader::TextureBufferDescriptor&>) {
177 if (desc.has_secondary) {
178 ASSERT(cbufs[desc.secondary_cbuf_index].enabled);
179 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
180 desc.secondary_cbuf_offset};
181 const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
182 const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
183 const u32 raw{lhs_raw | rhs_raw};
184 return TextureHandle{raw, via_header_index};
185 }
186 }
187 return TextureHandle{gpu_memory.Read<u32>(addr), via_header_index};
177 }}; 188 }};
178 const auto add_image{[&](const auto& desc) { 189 const auto add_image{[&](const auto& desc) {
179 const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; 190 const TextureHandle handle{read_handle(desc)};
180 image_view_indices.push_back(handle.image); 191 image_view_indices.push_back(handle.image);
181 }}; 192 }};
182 std::ranges::for_each(info.texture_buffer_descriptors, add_image); 193 std::ranges::for_each(info.texture_buffer_descriptors, add_image);
183 std::ranges::for_each(info.image_buffer_descriptors, add_image); 194 std::ranges::for_each(info.image_buffer_descriptors, add_image);
184 for (const auto& desc : info.texture_descriptors) { 195 for (const auto& desc : info.texture_descriptors) {
185 const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; 196 const TextureHandle handle{read_handle(desc)};
186 image_view_indices.push_back(handle.image); 197 image_view_indices.push_back(handle.image);
187 198
188 Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; 199 Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)};
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index e9b93336b..4317b2ac7 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -188,9 +188,7 @@ protected:
188 } 188 }
189 189
190 Shader::TextureType ReadTextureTypeImpl(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index, 190 Shader::TextureType ReadTextureTypeImpl(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index,
191 GPUVAddr cbuf_addr, u32 cbuf_size, u32 cbuf_index, 191 u32 raw) {
192 u32 cbuf_offset) {
193 const u32 raw{cbuf_offset < cbuf_size ? gpu_memory->Read<u32>(cbuf_addr + cbuf_offset) : 0};
194 const TextureHandle handle{raw, via_header_index}; 192 const TextureHandle handle{raw, via_header_index};
195 const GPUVAddr descriptor_addr{tic_addr + handle.image * sizeof(Tegra::Texture::TICEntry)}; 193 const GPUVAddr descriptor_addr{tic_addr + handle.image * sizeof(Tegra::Texture::TICEntry)};
196 Tegra::Texture::TICEntry entry; 194 Tegra::Texture::TICEntry entry;
@@ -219,7 +217,7 @@ protected:
219 throw Shader::NotImplementedException("Unknown texture type"); 217 throw Shader::NotImplementedException("Unknown texture type");
220 } 218 }
221 }()}; 219 }()};
222 texture_types.emplace(MakeCbufKey(cbuf_index, cbuf_offset), result); 220 texture_types.emplace(raw, result);
223 return result; 221 return result;
224 } 222 }
225 223
@@ -227,7 +225,7 @@ protected:
227 GPUVAddr program_base{}; 225 GPUVAddr program_base{};
228 226
229 std::vector<u64> code; 227 std::vector<u64> code;
230 std::unordered_map<u64, Shader::TextureType> texture_types; 228 std::unordered_map<u32, Shader::TextureType> texture_types;
231 std::unordered_map<u64, u32> cbuf_values; 229 std::unordered_map<u64, u32> cbuf_values;
232 230
233 u32 local_memory_size{}; 231 u32 local_memory_size{};
@@ -250,7 +248,7 @@ using Shader::Maxwell::TranslateProgram;
250 248
251// TODO: Move this to a separate file 249// TODO: Move this to a separate file
252constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'}; 250constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'};
253constexpr u32 CACHE_VERSION{1}; 251constexpr u32 CACHE_VERSION{2};
254 252
255class GraphicsEnvironment final : public GenericEnvironment { 253class GraphicsEnvironment final : public GenericEnvironment {
256public: 254public:
@@ -308,13 +306,10 @@ public:
308 return value; 306 return value;
309 } 307 }
310 308
311 Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { 309 Shader::TextureType ReadTextureType(u32 handle) override {
312 const auto& regs{maxwell3d->regs}; 310 const auto& regs{maxwell3d->regs};
313 const auto& cbuf{maxwell3d->state.shader_stages[stage_index].const_buffers[cbuf_index]};
314 ASSERT(cbuf.enabled);
315 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; 311 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
316 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, 312 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, handle);
317 cbuf.address, cbuf.size, cbuf_index, cbuf_offset);
318 } 313 }
319 314
320private: 315private:
@@ -352,13 +347,10 @@ public:
352 return value; 347 return value;
353 } 348 }
354 349
355 Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { 350 Shader::TextureType ReadTextureType(u32 handle) override {
356 const auto& regs{kepler_compute->regs}; 351 const auto& regs{kepler_compute->regs};
357 const auto& qmd{kepler_compute->launch_description}; 352 const auto& qmd{kepler_compute->launch_description};
358 ASSERT(((qmd.const_buffer_enable_mask.Value() >> cbuf_index) & 1) != 0); 353 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle);
359 const auto& cbuf{qmd.const_buffer_config[cbuf_index]};
360 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0,
361 cbuf.Address(), cbuf.size, cbuf_index, cbuf_offset);
362 } 354 }
363 355
364private: 356private:
@@ -421,7 +413,7 @@ public:
421 code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); 413 code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64)));
422 file.read(reinterpret_cast<char*>(code.get()), code_size); 414 file.read(reinterpret_cast<char*>(code.get()), code_size);
423 for (size_t i = 0; i < num_texture_types; ++i) { 415 for (size_t i = 0; i < num_texture_types; ++i) {
424 u64 key; 416 u32 key;
425 Shader::TextureType type; 417 Shader::TextureType type;
426 file.read(reinterpret_cast<char*>(&key), sizeof(key)) 418 file.read(reinterpret_cast<char*>(&key), sizeof(key))
427 .read(reinterpret_cast<char*>(&type), sizeof(type)); 419 .read(reinterpret_cast<char*>(&type), sizeof(type));
@@ -457,8 +449,8 @@ public:
457 return it->second; 449 return it->second;
458 } 450 }
459 451
460 Shader::TextureType ReadTextureType(u32 cbuf_index, u32 cbuf_offset) override { 452 Shader::TextureType ReadTextureType(u32 handle) override {
461 const auto it{texture_types.find(MakeCbufKey(cbuf_index, cbuf_offset))}; 453 const auto it{texture_types.find(handle)};
462 if (it == texture_types.end()) { 454 if (it == texture_types.end()) {
463 throw Shader::LogicError("Uncached read texture type"); 455 throw Shader::LogicError("Uncached read texture type");
464 } 456 }
@@ -483,7 +475,7 @@ public:
483 475
484private: 476private:
485 std::unique_ptr<u64[]> code; 477 std::unique_ptr<u64[]> code;
486 std::unordered_map<u64, Shader::TextureType> texture_types; 478 std::unordered_map<u32, Shader::TextureType> texture_types;
487 std::unordered_map<u64, u32> cbuf_values; 479 std::unordered_map<u64, u32> cbuf_values;
488 std::array<u32, 3> workgroup_size{}; 480 std::array<u32, 3> workgroup_size{};
489 u32 local_memory_size{}; 481 u32 local_memory_size{};