summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-12-11 13:07:30 -0400
committerGravatar FernandoS272019-12-11 19:53:16 -0400
commit271a3264f33766524224462537685b6e5c691f9d (patch)
treed97f52424561ab3abfac243f408e2b7e31d335de /src
parentMerge pull request #3218 from FernandoS27/tess-gl (diff)
downloadyuzu-271a3264f33766524224462537685b6e5c691f9d.tar.gz
yuzu-271a3264f33766524224462537685b6e5c691f9d.tar.xz
yuzu-271a3264f33766524224462537685b6e5c691f9d.zip
Shader_Ir: default failed tracks on bindless samplers to null values.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/texture.cpp97
-rw-r--r--src/video_core/shader/shader_ir.h4
2 files changed, 77 insertions, 24 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index da8e886df..67926afcb 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -129,7 +129,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
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 SamplerInfo info{TextureType::Texture2D, false, depth_compare}; 131 const SamplerInfo info{TextureType::Texture2D, false, depth_compare};
132 const auto& sampler = GetSampler(instr.sampler, info); 132 const Sampler& 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) {
@@ -154,9 +154,17 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
154 const auto texture_type = instr.txd.texture_type.Value(); 154 const auto texture_type = instr.txd.texture_type.Value();
155 const auto coord_count = GetCoordCount(texture_type); 155 const auto coord_count = GetCoordCount(texture_type);
156 156
157 const auto& sampler = is_bindless 157 const Sampler* sampler = is_bindless
158 ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) 158 ? GetBindlessSampler(base_reg, {{texture_type, false, false}})
159 : GetSampler(instr.sampler, {{texture_type, false, false}}); 159 : GetSampler(instr.sampler, {{texture_type, false, false}});
160 Node4 values;
161 if (sampler == nullptr) {
162 for (u32 element = 0; element < values.size(); ++element) {
163 values[element] = Immediate(0);
164 }
165 WriteTexInstructionFloat(bb, instr, values);
166 break;
167 }
160 if (is_bindless) { 168 if (is_bindless) {
161 base_reg++; 169 base_reg++;
162 } 170 }
@@ -170,9 +178,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
170 derivates.push_back(GetRegister(derivate_reg + derivate + 1)); 178 derivates.push_back(GetRegister(derivate_reg + derivate + 1));
171 } 179 }
172 180
173 Node4 values;
174 for (u32 element = 0; element < values.size(); ++element) { 181 for (u32 element = 0; element < values.size(); ++element) {
175 MetaTexture meta{sampler, {}, {}, {}, derivates, {}, {}, {}, element}; 182 MetaTexture meta{*sampler, {}, {}, {}, derivates, {}, {}, {}, element};
176 values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords); 183 values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords);
177 } 184 }
178 185
@@ -187,9 +194,24 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
187 // TODO: The new commits on the texture refactor, change the way samplers work. 194 // TODO: The new commits on the texture refactor, change the way samplers work.
188 // Sadly, not all texture instructions specify the type of texture their sampler 195 // Sadly, not all texture instructions specify the type of texture their sampler
189 // uses. This must be fixed at a later instance. 196 // uses. This must be fixed at a later instance.
190 const auto& sampler = 197 const Sampler* sampler =
191 is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.sampler); 198 is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.sampler);
192 199
200 if (sampler == nullptr) {
201 u32 indexer = 0;
202 for (u32 element = 0; element < 4; ++element) {
203 if (!instr.txq.IsComponentEnabled(element)) {
204 continue;
205 }
206 const Node value = Immediate(0);
207 SetTemporary(bb, indexer++, value);
208 }
209 for (u32 i = 0; i < indexer; ++i) {
210 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
211 }
212 break;
213 }
214
193 u32 indexer = 0; 215 u32 indexer = 0;
194 switch (instr.txq.query_type) { 216 switch (instr.txq.query_type) {
195 case Tegra::Shader::TextureQueryType::Dimension: { 217 case Tegra::Shader::TextureQueryType::Dimension: {
@@ -197,7 +219,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
197 if (!instr.txq.IsComponentEnabled(element)) { 219 if (!instr.txq.IsComponentEnabled(element)) {
198 continue; 220 continue;
199 } 221 }
200 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; 222 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element};
201 const Node value = 223 const Node value =
202 Operation(OperationCode::TextureQueryDimensions, meta, 224 Operation(OperationCode::TextureQueryDimensions, meta,
203 GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); 225 GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
@@ -223,9 +245,24 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
223 245
224 auto texture_type = instr.tmml.texture_type.Value(); 246 auto texture_type = instr.tmml.texture_type.Value();
225 const bool is_array = instr.tmml.array != 0; 247 const bool is_array = instr.tmml.array != 0;
226 const auto& sampler = 248 const Sampler* sampler =
227 is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.sampler); 249 is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.sampler);
228 250
251 if (sampler == nullptr) {
252 u32 indexer = 0;
253 for (u32 element = 0; element < 2; ++element) {
254 if (!instr.tmml.IsComponentEnabled(element)) {
255 continue;
256 }
257 const Node value = Immediate(0);
258 SetTemporary(bb, indexer++, value);
259 }
260 for (u32 i = 0; i < indexer; ++i) {
261 SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
262 }
263 break;
264 }
265
229 std::vector<Node> coords; 266 std::vector<Node> coords;
230 267
231 // TODO: Add coordinates for different samplers once other texture types are implemented. 268 // TODO: Add coordinates for different samplers once other texture types are implemented.
@@ -251,7 +288,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
251 continue; 288 continue;
252 } 289 }
253 auto params = coords; 290 auto params = coords;
254 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; 291 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element};
255 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); 292 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
256 SetTemporary(bb, indexer++, value); 293 SetTemporary(bb, indexer++, value);
257 } 294 }
@@ -307,7 +344,7 @@ ShaderIR::SamplerInfo ShaderIR::GetSamplerInfo(std::optional<SamplerInfo> sample
307 sampler->is_buffer != 0}; 344 sampler->is_buffer != 0};
308} 345}
309 346
310const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, 347const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
311 std::optional<SamplerInfo> sampler_info) { 348 std::optional<SamplerInfo> sampler_info) {
312 const auto offset = static_cast<u32>(sampler.index.Value()); 349 const auto offset = static_cast<u32>(sampler.index.Value());
313 const auto info = GetSamplerInfo(sampler_info, offset); 350 const auto info = GetSamplerInfo(sampler_info, offset);
@@ -319,21 +356,24 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
319 if (it != used_samplers.end()) { 356 if (it != used_samplers.end()) {
320 ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && 357 ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array &&
321 it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer); 358 it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer);
322 return *it; 359 return &(*it);
323 } 360 }
324 361
325 // Otherwise create a new mapping for this sampler 362 // Otherwise create a new mapping for this sampler
326 const auto next_index = static_cast<u32>(used_samplers.size()); 363 const auto next_index = static_cast<u32>(used_samplers.size());
327 return used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, 364 return &used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow,
328 info.is_buffer); 365 info.is_buffer);
329} 366}
330 367
331const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, 368const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg,
332 std::optional<SamplerInfo> sampler_info) { 369 std::optional<SamplerInfo> sampler_info) {
333 const Node sampler_register = GetRegister(reg); 370 const Node sampler_register = GetRegister(reg);
334 const auto [base_sampler, buffer, offset] = 371 const auto [base_sampler, buffer, offset] =
335 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); 372 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size()));
336 ASSERT(base_sampler != nullptr); 373 ASSERT(base_sampler != nullptr);
374 if (base_sampler == nullptr) {
375 return nullptr;
376 }
337 377
338 const auto info = GetSamplerInfo(sampler_info, offset, buffer); 378 const auto info = GetSamplerInfo(sampler_info, offset, buffer);
339 379
@@ -346,12 +386,12 @@ const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg,
346 if (it != used_samplers.end()) { 386 if (it != used_samplers.end()) {
347 ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && 387 ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array &&
348 it->IsShadow() == info.is_shadow); 388 it->IsShadow() == info.is_shadow);
349 return *it; 389 return &(*it);
350 } 390 }
351 391
352 // Otherwise create a new mapping for this sampler 392 // Otherwise create a new mapping for this sampler
353 const auto next_index = static_cast<u32>(used_samplers.size()); 393 const auto next_index = static_cast<u32>(used_samplers.size());
354 return used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, 394 return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array,
355 info.is_shadow, info.is_buffer); 395 info.is_shadow, info.is_buffer);
356} 396}
357 397
@@ -438,8 +478,15 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
438 "This method is not supported."); 478 "This method is not supported.");
439 479
440 const SamplerInfo info{texture_type, is_array, is_shadow, false}; 480 const SamplerInfo info{texture_type, is_array, is_shadow, false};
441 const auto& sampler = 481 const Sampler* sampler =
442 is_bindless ? GetBindlessSampler(*bindless_reg, info) : GetSampler(instr.sampler, info); 482 is_bindless ? GetBindlessSampler(*bindless_reg, info) : GetSampler(instr.sampler, info);
483 Node4 values;
484 if (sampler == nullptr) {
485 for (u32 element = 0; element < values.size(); ++element) {
486 values[element] = Immediate(0);
487 }
488 return values;
489 }
443 490
444 const bool lod_needed = process_mode == TextureProcessMode::LZ || 491 const bool lod_needed = process_mode == TextureProcessMode::LZ ||
445 process_mode == TextureProcessMode::LL || 492 process_mode == TextureProcessMode::LL ||
@@ -478,10 +525,10 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
478 } 525 }
479 } 526 }
480 527
481 Node4 values; 528
482 for (u32 element = 0; element < values.size(); ++element) { 529 for (u32 element = 0; element < values.size(); ++element) {
483 auto copy_coords = coords; 530 auto copy_coords = coords;
484 MetaTexture meta{sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element}; 531 MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element};
485 values[element] = Operation(read_method, meta, std::move(copy_coords)); 532 values[element] = Operation(read_method, meta, std::move(copy_coords));
486 } 533 }
487 534
@@ -594,8 +641,15 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
594 u64 parameter_register = instr.gpr20.Value(); 641 u64 parameter_register = instr.gpr20.Value();
595 642
596 const SamplerInfo info{texture_type, is_array, depth_compare, false}; 643 const SamplerInfo info{texture_type, is_array, depth_compare, false};
597 const auto& sampler = is_bindless ? GetBindlessSampler(parameter_register++, info) 644 const Sampler* sampler = is_bindless ? GetBindlessSampler(parameter_register++, info)
598 : GetSampler(instr.sampler, info); 645 : GetSampler(instr.sampler, info);
646 Node4 values;
647 if (sampler == nullptr) {
648 for (u32 element = 0; element < values.size(); ++element) {
649 values[element] = Immediate(0);
650 }
651 return values;
652 }
599 653
600 std::vector<Node> aoffi; 654 std::vector<Node> aoffi;
601 if (is_aoffi) { 655 if (is_aoffi) {
@@ -610,10 +664,9 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
610 const Node component = is_bindless ? Immediate(static_cast<u32>(instr.tld4_b.component)) 664 const Node component = is_bindless ? Immediate(static_cast<u32>(instr.tld4_b.component))
611 : Immediate(static_cast<u32>(instr.tld4.component)); 665 : Immediate(static_cast<u32>(instr.tld4.component));
612 666
613 Node4 values;
614 for (u32 element = 0; element < values.size(); ++element) { 667 for (u32 element = 0; element < values.size(); ++element) {
615 auto coords_copy = coords; 668 auto coords_copy = coords;
616 MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component, 669 MetaTexture meta{*sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component,
617 element}; 670 element};
618 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 671 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
619 } 672 }
@@ -642,7 +695,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
642 // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr}; 695 // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr};
643 // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr}; 696 // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr};
644 697
645 const auto& sampler = GetSampler(instr.sampler); 698 const auto& sampler = *GetSampler(instr.sampler);
646 699
647 Node4 values; 700 Node4 values;
648 for (u32 element = 0; element < values.size(); ++element) { 701 for (u32 element = 0; element < values.size(); ++element) {
@@ -655,7 +708,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
655} 708}
656 709
657Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) { 710Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) {
658 const auto& sampler = GetSampler(instr.sampler); 711 const Sampler& sampler = *GetSampler(instr.sampler);
659 712
660 const std::size_t type_coord_count = GetCoordCount(texture_type); 713 const std::size_t type_coord_count = GetCoordCount(texture_type);
661 const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; 714 const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL;
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 580f84fcb..8324432ae 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -313,11 +313,11 @@ private:
313 std::optional<u32> buffer = std::nullopt); 313 std::optional<u32> buffer = std::nullopt);
314 314
315 /// Accesses a texture sampler 315 /// Accesses a texture sampler
316 const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, 316 const Sampler* GetSampler(const Tegra::Shader::Sampler& sampler,
317 std::optional<SamplerInfo> sampler_info = std::nullopt); 317 std::optional<SamplerInfo> sampler_info = std::nullopt);
318 318
319 /// Accesses a texture sampler for a bindless texture. 319 /// Accesses a texture sampler for a bindless texture.
320 const Sampler& GetBindlessSampler(Tegra::Shader::Register reg, 320 const Sampler* GetBindlessSampler(Tegra::Shader::Register reg,
321 std::optional<SamplerInfo> sampler_info = std::nullopt); 321 std::optional<SamplerInfo> sampler_info = std::nullopt);
322 322
323 /// Accesses an image. 323 /// Accesses an image.