summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-11-06 04:32:43 -0300
committerGravatar ReinUsesLisp2019-11-22 21:28:47 -0300
commit32c1bc6a67820f9df21c8f64f4df078b015aa7da (patch)
tree141df885726a01fbd7d999d6ee314b4d11c8ce56 /src/video_core/shader/decode
parentMerge pull request #3142 from ReinUsesLisp/depbar-log (diff)
downloadyuzu-32c1bc6a67820f9df21c8f64f4df078b015aa7da.tar.gz
yuzu-32c1bc6a67820f9df21c8f64f4df078b015aa7da.tar.xz
yuzu-32c1bc6a67820f9df21c8f64f4df078b015aa7da.zip
shader/texture: Deduce texture buffers from locker
Instead of specializing shaders to separate texture buffers from 1D textures, use the locker to deduce them while they are being decoded.
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/texture.cpp102
1 files changed, 41 insertions, 61 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index bb926a132..695fdbd24 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -128,8 +128,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
128 } 128 }
129 const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); 129 const Node component = Immediate(static_cast<u32>(instr.tld4s.component));
130 130
131 const auto& sampler = 131 const SamplerInfo info{TextureType::Texture2D, false, depth_compare};
132 GetSampler(instr.sampler, {{TextureType::Texture2D, false, depth_compare}}); 132 const auto& sampler = GetSampler(instr.sampler, info);
133 133
134 Node4 values; 134 Node4 values;
135 for (u32 element = 0; element < values.size(); ++element) { 135 for (u32 element = 0; element < values.size(); ++element) {
@@ -149,7 +149,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
149 // Sadly, not all texture instructions specify the type of texture their sampler 149 // Sadly, not all texture instructions specify the type of texture their sampler
150 // uses. This must be fixed at a later instance. 150 // uses. This must be fixed at a later instance.
151 const auto& sampler = 151 const auto& sampler =
152 is_bindless ? GetBindlessSampler(instr.gpr8, {}) : GetSampler(instr.sampler, {}); 152 is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.sampler);
153 153
154 u32 indexer = 0; 154 u32 indexer = 0;
155 switch (instr.txq.query_type) { 155 switch (instr.txq.query_type) {
@@ -185,8 +185,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
185 auto texture_type = instr.tmml.texture_type.Value(); 185 auto texture_type = instr.tmml.texture_type.Value();
186 const bool is_array = instr.tmml.array != 0; 186 const bool is_array = instr.tmml.array != 0;
187 const auto& sampler = 187 const auto& sampler =
188 is_bindless ? GetBindlessSampler(instr.gpr20, {{texture_type, is_array, false}}) 188 is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.sampler);
189 : GetSampler(instr.sampler, {{texture_type, is_array, false}});
190 189
191 std::vector<Node> coords; 190 std::vector<Node> coords;
192 191
@@ -254,67 +253,50 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
254 return pc; 253 return pc;
255} 254}
256 255
257const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, 256ShaderIR::SamplerInfo ShaderIR::GetSamplerInfo(std::optional<SamplerInfo> sampler_info, u32 offset,
258 std::optional<SamplerInfo> sampler_info) { 257 std::optional<u32> buffer) {
259 const auto offset = static_cast<u32>(sampler.index.Value());
260
261 TextureType type;
262 bool is_array;
263 bool is_shadow;
264 if (sampler_info) { 258 if (sampler_info) {
265 type = sampler_info->type; 259 return *sampler_info;
266 is_array = sampler_info->is_array; 260 }
267 is_shadow = sampler_info->is_shadow; 261 const auto sampler =
268 } else if (const auto sampler = locker.ObtainBoundSampler(offset)) { 262 buffer ? locker.ObtainBindlessSampler(*buffer, offset) : locker.ObtainBoundSampler(offset);
269 type = sampler->texture_type.Value(); 263 if (!sampler) {
270 is_array = sampler->is_array.Value() != 0;
271 is_shadow = sampler->is_shadow.Value() != 0;
272 } else {
273 LOG_WARNING(HW_GPU, "Unknown sampler info"); 264 LOG_WARNING(HW_GPU, "Unknown sampler info");
274 type = TextureType::Texture2D; 265 return SamplerInfo{TextureType::Texture2D, false, false, false};
275 is_array = false;
276 is_shadow = false;
277 } 266 }
267 return SamplerInfo{sampler->texture_type, sampler->is_array != 0, sampler->is_shadow != 0,
268 sampler->is_buffer != 0};
269}
270
271const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
272 std::optional<SamplerInfo> sampler_info) {
273 const auto offset = static_cast<u32>(sampler.index.Value());
274 const auto info = GetSamplerInfo(sampler_info, offset);
278 275
279 // If this sampler has already been used, return the existing mapping. 276 // If this sampler has already been used, return the existing mapping.
280 const auto it = 277 const auto it =
281 std::find_if(used_samplers.begin(), used_samplers.end(), 278 std::find_if(used_samplers.begin(), used_samplers.end(),
282 [offset](const Sampler& entry) { return entry.GetOffset() == offset; }); 279 [offset](const Sampler& entry) { return entry.GetOffset() == offset; });
283 if (it != used_samplers.end()) { 280 if (it != used_samplers.end()) {
284 ASSERT(!it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && 281 ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array &&
285 it->IsShadow() == is_shadow); 282 it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer);
286 return *it; 283 return *it;
287 } 284 }
288 285
289 // Otherwise create a new mapping for this sampler 286 // Otherwise create a new mapping for this sampler
290 const auto next_index = static_cast<u32>(used_samplers.size()); 287 const auto next_index = static_cast<u32>(used_samplers.size());
291 return used_samplers.emplace_back(Sampler(next_index, offset, type, is_array, is_shadow)); 288 return used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow,
289 info.is_buffer);
292} 290}
293 291
294const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, 292const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg,
295 std::optional<SamplerInfo> sampler_info) { 293 std::optional<SamplerInfo> sampler_info) {
296 const Node sampler_register = GetRegister(reg); 294 const Node sampler_register = GetRegister(reg);
297 const auto [base_sampler, buffer, offset] = 295 const auto [base_sampler, buffer, offset] =
298 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); 296 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size()));
299 ASSERT(base_sampler != nullptr); 297 ASSERT(base_sampler != nullptr);
300 298
301 TextureType type; 299 const auto info = GetSamplerInfo(sampler_info, offset, buffer);
302 bool is_array;
303 bool is_shadow;
304 if (sampler_info) {
305 type = sampler_info->type;
306 is_array = sampler_info->is_array;
307 is_shadow = sampler_info->is_shadow;
308 } else if (const auto sampler = locker.ObtainBindlessSampler(buffer, offset)) {
309 type = sampler->texture_type.Value();
310 is_array = sampler->is_array.Value() != 0;
311 is_shadow = sampler->is_shadow.Value() != 0;
312 } else {
313 LOG_WARNING(HW_GPU, "Unknown sampler info");
314 type = TextureType::Texture2D;
315 is_array = false;
316 is_shadow = false;
317 }
318 300
319 // If this sampler has already been used, return the existing mapping. 301 // If this sampler has already been used, return the existing mapping.
320 const auto it = 302 const auto it =
@@ -323,15 +305,15 @@ const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg,
323 return entry.GetBuffer() == buffer && entry.GetOffset() == offset; 305 return entry.GetBuffer() == buffer && entry.GetOffset() == offset;
324 }); 306 });
325 if (it != used_samplers.end()) { 307 if (it != used_samplers.end()) {
326 ASSERT(it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && 308 ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array &&
327 it->IsShadow() == is_shadow); 309 it->IsShadow() == info.is_shadow);
328 return *it; 310 return *it;
329 } 311 }
330 312
331 // Otherwise create a new mapping for this sampler 313 // Otherwise create a new mapping for this sampler
332 const auto next_index = static_cast<u32>(used_samplers.size()); 314 const auto next_index = static_cast<u32>(used_samplers.size());
333 return used_samplers.emplace_back( 315 return used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array,
334 Sampler(next_index, offset, buffer, type, is_array, is_shadow)); 316 info.is_shadow, info.is_buffer);
335} 317}
336 318
337void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { 319void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) {
@@ -416,17 +398,16 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
416 (texture_type == TextureType::TextureCube && is_array && is_shadow), 398 (texture_type == TextureType::TextureCube && is_array && is_shadow),
417 "This method is not supported."); 399 "This method is not supported.");
418 400
401 const SamplerInfo info{texture_type, is_array, is_shadow, false};
419 const auto& sampler = 402 const auto& sampler =
420 is_bindless ? GetBindlessSampler(*bindless_reg, {{texture_type, is_array, is_shadow}}) 403 is_bindless ? GetBindlessSampler(*bindless_reg, info) : GetSampler(instr.sampler, info);
421 : GetSampler(instr.sampler, {{texture_type, is_array, is_shadow}});
422 404
423 const bool lod_needed = process_mode == TextureProcessMode::LZ || 405 const bool lod_needed = process_mode == TextureProcessMode::LZ ||
424 process_mode == TextureProcessMode::LL || 406 process_mode == TextureProcessMode::LL ||
425 process_mode == TextureProcessMode::LLA; 407 process_mode == TextureProcessMode::LLA;
426 408
427 // LOD selection (either via bias or explicit textureLod) not 409 // LOD selection (either via bias or explicit textureLod) not supported in GL for
428 // supported in GL for sampler2DArrayShadow and 410 // sampler2DArrayShadow and samplerCubeArrayShadow.
429 // samplerCubeArrayShadow.
430 const bool gl_lod_supported = 411 const bool gl_lod_supported =
431 !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) || 412 !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) ||
432 (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); 413 (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));
@@ -436,8 +417,8 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
436 417
437 UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); 418 UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported);
438 419
439 Node bias = {}; 420 Node bias;
440 Node lod = {}; 421 Node lod;
441 if (process_mode != TextureProcessMode::None && gl_lod_supported) { 422 if (process_mode != TextureProcessMode::None && gl_lod_supported) {
442 switch (process_mode) { 423 switch (process_mode) {
443 case TextureProcessMode::LZ: 424 case TextureProcessMode::LZ:
@@ -573,10 +554,9 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
573 554
574 u64 parameter_register = instr.gpr20.Value(); 555 u64 parameter_register = instr.gpr20.Value();
575 556
576 const auto& sampler = 557 const SamplerInfo info{texture_type, is_array, depth_compare, false};
577 is_bindless 558 const auto& sampler = is_bindless ? GetBindlessSampler(parameter_register++, info)
578 ? GetBindlessSampler(parameter_register++, {{texture_type, is_array, depth_compare}}) 559 : GetSampler(instr.sampler, info);
579 : GetSampler(instr.sampler, {{texture_type, is_array, depth_compare}});
580 560
581 std::vector<Node> aoffi; 561 std::vector<Node> aoffi;
582 if (is_aoffi) { 562 if (is_aoffi) {
@@ -623,7 +603,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
623 // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr}; 603 // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr};
624 // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr}; 604 // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr};
625 605
626 const auto& sampler = GetSampler(instr.sampler, {{texture_type, is_array, false}}); 606 const auto& sampler = GetSampler(instr.sampler);
627 607
628 Node4 values; 608 Node4 values;
629 for (u32 element = 0; element < values.size(); ++element) { 609 for (u32 element = 0; element < values.size(); ++element) {
@@ -659,7 +639,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
659 // When lod is used always is in gpr20 639 // When lod is used always is in gpr20
660 const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); 640 const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0);
661 641
662 const auto& sampler = GetSampler(instr.sampler, {{texture_type, is_array, false}}); 642 const auto& sampler = GetSampler(instr.sampler);
663 643
664 Node4 values; 644 Node4 values;
665 for (u32 element = 0; element < values.size(); ++element) { 645 for (u32 element = 0; element < values.size(); ++element) {