summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-01-07 17:45:12 -0400
committerGravatar FernandoS272020-01-24 16:44:47 -0400
commit7c530e06661d760eb6366724d109468423363072 (patch)
tree529a0bdfb0aa41773468be8966d9f5c8738e6e3d /src
parentShader_IR: Implement Injectable Custom Variables to the IR. (diff)
downloadyuzu-7c530e06661d760eb6366724d109468423363072.tar.gz
yuzu-7c530e06661d760eb6366724d109468423363072.tar.xz
yuzu-7c530e06661d760eb6366724d109468423363072.zip
Shader_IR: Propagate bindless index into the GL compiler.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp2
-rw-r--r--src/video_core/shader/decode/texture.cpp40
-rw-r--r--src/video_core/shader/node.h2
-rw-r--r--src/video_core/shader/shader_ir.h5
-rw-r--r--src/video_core/shader/track.cpp29
5 files changed, 54 insertions, 24 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 8b413ae9a..df681bdcb 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1123,7 +1123,7 @@ private:
1123 if (!meta->sampler.IsIndexed()) { 1123 if (!meta->sampler.IsIndexed()) {
1124 expr += '(' + GetSampler(meta->sampler) + ", "; 1124 expr += '(' + GetSampler(meta->sampler) + ", ";
1125 } else { 1125 } else {
1126 expr += '(' + GetSampler(meta->sampler) + "[0], "; 1126 expr += '(' + GetSampler(meta->sampler) + '[' + Visit(meta->index).AsUint() + "], ";
1127 } 1127 }
1128 expr += coord_constructors.at(count + (has_array ? 1 : 0) + 1128 expr += coord_constructors.at(count + (has_array ? 1 : 0) +
1129 (has_shadow && !separate_dc ? 1 : 0) - 1); 1129 (has_shadow && !separate_dc ? 1 : 0) - 1);
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index e7c38f5d6..31b09b18c 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -144,7 +144,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
144 Node4 values; 144 Node4 values;
145 for (u32 element = 0; element < values.size(); ++element) { 145 for (u32 element = 0; element < values.size(); ++element) {
146 auto coords_copy = coords; 146 auto coords_copy = coords;
147 MetaTexture meta{sampler, {}, depth_compare, aoffi, {}, {}, {}, {}, component, element}; 147 MetaTexture meta{sampler, {}, depth_compare, aoffi, {}, {},
148 {}, {}, component, element, {}};
148 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 149 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
149 } 150 }
150 151
@@ -167,9 +168,9 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
167 const auto derivate_reg = instr.gpr20.Value(); 168 const auto derivate_reg = instr.gpr20.Value();
168 const auto texture_type = instr.txd.texture_type.Value(); 169 const auto texture_type = instr.txd.texture_type.Value();
169 const auto coord_count = GetCoordCount(texture_type); 170 const auto coord_count = GetCoordCount(texture_type);
170 171 Node index_var{};
171 const Sampler* sampler = 172 const Sampler* sampler =
172 is_bindless ? GetBindlessSampler(base_reg, {{texture_type, is_array, false}}) 173 is_bindless ? GetBindlessSampler(base_reg, index_var, {{texture_type, is_array, false}})
173 : GetSampler(instr.sampler, {{texture_type, is_array, false}}); 174 : GetSampler(instr.sampler, {{texture_type, is_array, false}});
174 Node4 values; 175 Node4 values;
175 if (sampler == nullptr) { 176 if (sampler == nullptr) {
@@ -200,7 +201,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
200 } 201 }
201 202
202 for (u32 element = 0; element < values.size(); ++element) { 203 for (u32 element = 0; element < values.size(); ++element) {
203 MetaTexture meta{*sampler, array_node, {}, {}, {}, derivates, {}, {}, {}, element}; 204 MetaTexture meta{*sampler, array_node, {}, {}, {}, derivates, {}, {}, {}, element, index_var};
204 values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords); 205 values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords);
205 } 206 }
206 207
@@ -215,8 +216,9 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
215 // TODO: The new commits on the texture refactor, change the way samplers work. 216 // TODO: The new commits on the texture refactor, change the way samplers work.
216 // Sadly, not all texture instructions specify the type of texture their sampler 217 // Sadly, not all texture instructions specify the type of texture their sampler
217 // uses. This must be fixed at a later instance. 218 // uses. This must be fixed at a later instance.
219 Node index_var{};
218 const Sampler* sampler = 220 const Sampler* sampler =
219 is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.sampler); 221 is_bindless ? GetBindlessSampler(instr.gpr8, index_var) : GetSampler(instr.sampler);
220 222
221 if (sampler == nullptr) { 223 if (sampler == nullptr) {
222 u32 indexer = 0; 224 u32 indexer = 0;
@@ -240,7 +242,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
240 if (!instr.txq.IsComponentEnabled(element)) { 242 if (!instr.txq.IsComponentEnabled(element)) {
241 continue; 243 continue;
242 } 244 }
243 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element}; 245 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element, index_var};
244 const Node value = 246 const Node value =
245 Operation(OperationCode::TextureQueryDimensions, meta, 247 Operation(OperationCode::TextureQueryDimensions, meta,
246 GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); 248 GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
@@ -266,8 +268,9 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
266 268
267 auto texture_type = instr.tmml.texture_type.Value(); 269 auto texture_type = instr.tmml.texture_type.Value();
268 const bool is_array = instr.tmml.array != 0; 270 const bool is_array = instr.tmml.array != 0;
271 Node index_var{};
269 const Sampler* sampler = 272 const Sampler* sampler =
270 is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.sampler); 273 is_bindless ? GetBindlessSampler(instr.gpr20, index_var) : GetSampler(instr.sampler);
271 274
272 if (sampler == nullptr) { 275 if (sampler == nullptr) {
273 u32 indexer = 0; 276 u32 indexer = 0;
@@ -309,7 +312,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
309 continue; 312 continue;
310 } 313 }
311 auto params = coords; 314 auto params = coords;
312 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element}; 315 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element, index_var};
313 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); 316 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
314 SetTemporary(bb, indexer++, value); 317 SetTemporary(bb, indexer++, value);
315 } 318 }
@@ -386,7 +389,7 @@ const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
386 info.is_buffer, false); 389 info.is_buffer, false);
387} 390}
388 391
389const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, 392const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, Node& index_var,
390 std::optional<SamplerInfo> sampler_info) { 393 std::optional<SamplerInfo> sampler_info) {
391 const Node sampler_register = GetRegister(reg); 394 const Node sampler_register = GetRegister(reg);
392 const auto [base_node, tracked_sampler_info] = 395 const auto [base_node, tracked_sampler_info] =
@@ -421,6 +424,7 @@ const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg,
421 } else if (const auto array_sampler_info = 424 } else if (const auto array_sampler_info =
422 std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) { 425 std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) {
423 const u32 base_offset = array_sampler_info->GetBaseOffset() / 4; 426 const u32 base_offset = array_sampler_info->GetBaseOffset() / 4;
427 index_var = GetCustomVariable(array_sampler_info->GetIndexVar());
424 const auto info = GetSamplerInfo(sampler_info, base_offset); 428 const auto info = GetSamplerInfo(sampler_info, base_offset);
425 429
426 // If this sampler has already been used, return the existing mapping. 430 // If this sampler has already been used, return the existing mapping.
@@ -526,8 +530,9 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
526 "This method is not supported."); 530 "This method is not supported.");
527 531
528 const SamplerInfo info{texture_type, is_array, is_shadow, false}; 532 const SamplerInfo info{texture_type, is_array, is_shadow, false};
529 const Sampler* sampler = 533 Node index_var{};
530 is_bindless ? GetBindlessSampler(*bindless_reg, info) : GetSampler(instr.sampler, info); 534 const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, index_var, info)
535 : GetSampler(instr.sampler, info);
531 Node4 values; 536 Node4 values;
532 if (sampler == nullptr) { 537 if (sampler == nullptr) {
533 for (u32 element = 0; element < values.size(); ++element) { 538 for (u32 element = 0; element < values.size(); ++element) {
@@ -575,7 +580,8 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
575 580
576 for (u32 element = 0; element < values.size(); ++element) { 581 for (u32 element = 0; element < values.size(); ++element) {
577 auto copy_coords = coords; 582 auto copy_coords = coords;
578 MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias, lod, {}, element}; 583 MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias,
584 lod, {}, element, index_var};
579 values[element] = Operation(read_method, meta, std::move(copy_coords)); 585 values[element] = Operation(read_method, meta, std::move(copy_coords));
580 } 586 }
581 587
@@ -690,7 +696,8 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
690 u64 parameter_register = instr.gpr20.Value(); 696 u64 parameter_register = instr.gpr20.Value();
691 697
692 const SamplerInfo info{texture_type, is_array, depth_compare, false}; 698 const SamplerInfo info{texture_type, is_array, depth_compare, false};
693 const Sampler* sampler = is_bindless ? GetBindlessSampler(parameter_register++, info) 699 Node index_var{};
700 const Sampler* sampler = is_bindless ? GetBindlessSampler(parameter_register++, index_var, info)
694 : GetSampler(instr.sampler, info); 701 : GetSampler(instr.sampler, info);
695 Node4 values; 702 Node4 values;
696 if (sampler == nullptr) { 703 if (sampler == nullptr) {
@@ -719,7 +726,8 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
719 for (u32 element = 0; element < values.size(); ++element) { 726 for (u32 element = 0; element < values.size(); ++element) {
720 auto coords_copy = coords; 727 auto coords_copy = coords;
721 MetaTexture meta{ 728 MetaTexture meta{
722 *sampler, GetRegister(array_register), dc, aoffi, ptp, {}, {}, {}, component, element}; 729 *sampler, GetRegister(array_register), dc, aoffi, ptp, {}, {}, {}, component, element,
730 index_var};
723 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 731 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
724 } 732 }
725 733
@@ -752,7 +760,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
752 Node4 values; 760 Node4 values;
753 for (u32 element = 0; element < values.size(); ++element) { 761 for (u32 element = 0; element < values.size(); ++element) {
754 auto coords_copy = coords; 762 auto coords_copy = coords;
755 MetaTexture meta{sampler, array_register, {}, {}, {}, {}, {}, lod, {}, element}; 763 MetaTexture meta{sampler, array_register, {}, {}, {}, {}, {}, lod, {}, element, {}};
756 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); 764 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
757 } 765 }
758 766
@@ -802,7 +810,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
802 Node4 values; 810 Node4 values;
803 for (u32 element = 0; element < values.size(); ++element) { 811 for (u32 element = 0; element < values.size(); ++element) {
804 auto coords_copy = coords; 812 auto coords_copy = coords;
805 MetaTexture meta{sampler, array, {}, {}, {}, {}, {}, lod, {}, element}; 813 MetaTexture meta{sampler, array, {}, {}, {}, {}, {}, lod, {}, element, {}};
806 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); 814 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
807 } 815 }
808 return values; 816 return values;
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index db06767f6..d75453458 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -445,6 +445,7 @@ struct MetaTexture {
445 Node lod; 445 Node lod;
446 Node component{}; 446 Node component{};
447 u32 element{}; 447 u32 element{};
448 Node index{};
448}; 449};
449 450
450struct MetaImage { 451struct MetaImage {
@@ -564,7 +565,6 @@ private:
564 u32 index{}; 565 u32 index{};
565}; 566};
566 567
567
568/// A 32-bits value that represents an immediate value 568/// A 32-bits value that represents an immediate value
569class ImmediateNode final { 569class ImmediateNode final {
570public: 570public:
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 2fe14e815..0421dac0c 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -328,7 +328,7 @@ private:
328 std::optional<SamplerInfo> sampler_info = std::nullopt); 328 std::optional<SamplerInfo> sampler_info = std::nullopt);
329 329
330 /// Accesses a texture sampler for a bindless texture. 330 /// Accesses a texture sampler for a bindless texture.
331 const Sampler* GetBindlessSampler(Tegra::Shader::Register reg, 331 const Sampler* GetBindlessSampler(Tegra::Shader::Register reg, Node& index_var,
332 std::optional<SamplerInfo> sampler_info = std::nullopt); 332 std::optional<SamplerInfo> sampler_info = std::nullopt);
333 333
334 /// Accesses an image. 334 /// Accesses an image.
@@ -394,8 +394,7 @@ private:
394 394
395 std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const; 395 std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;
396 396
397 std::tuple<Node, TrackSampler> TrackSampler(Node tracked, const NodeBlock& code, 397 std::tuple<Node, TrackSampler> TrackSampler(Node tracked, const NodeBlock& code, s64 cursor);
398 s64 cursor) const;
399 398
400 std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const; 399 std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const;
401 400
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp
index 69a677394..d449b625e 100644
--- a/src/video_core/shader/track.cpp
+++ b/src/video_core/shader/track.cpp
@@ -61,8 +61,19 @@ std::optional<std::pair<Node, Node>> DecoupleIndirectRead(const OperationNode& o
61 return std::nullopt; 61 return std::nullopt;
62} 62}
63 63
64bool AmendNodeCv(std::size_t amend_index, Node node) {
65 if (const auto operation = std::get_if<OperationNode>(&*node)) {
66 operation->SetAmendIndex(amend_index);
67 return true;
68 } else if (const auto conditional = std::get_if<ConditionalNode>(&*node)) {
69 conditional->SetAmendIndex(amend_index);
70 return true;
71 }
72 return false;
73}
74
64std::tuple<Node, TrackSampler> ShaderIR::TrackSampler(Node tracked, const NodeBlock& code, 75std::tuple<Node, TrackSampler> ShaderIR::TrackSampler(Node tracked, const NodeBlock& code,
65 s64 cursor) const { 76 s64 cursor) {
66 if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { 77 if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) {
67 // Constant buffer found, test if it's an immediate 78 // Constant buffer found, test if it's an immediate
68 const auto offset = cbuf->GetOffset(); 79 const auto offset = cbuf->GetOffset();
@@ -84,9 +95,21 @@ std::tuple<Node, TrackSampler> ShaderIR::TrackSampler(Node tracked, const NodeBl
84 } 95 }
85 auto [gpr, base_offset] = *pair; 96 auto [gpr, base_offset] = *pair;
86 const auto offset_inm = std::get_if<ImmediateNode>(&*base_offset); 97 const auto offset_inm = std::get_if<ImmediateNode>(&*base_offset);
98 auto gpu_driver = locker.AccessGuestDriverProfile();
99 if (gpu_driver == nullptr) {
100 return {};
101 }
102 const u32 bindless_cv = NewCustomVariable();
103 const Node op = Operation(OperationCode::UDiv, NO_PRECISE, gpr,
104 Immediate(gpu_driver->GetTextureHandlerSize()));
105
106 const Node cv_node = GetCustomVariable(bindless_cv);
107 Node amend_op = Operation(OperationCode::Assign, cv_node, std::move(op));
108 const std::size_t amend_index = DeclareAmend(amend_op);
109 AmendNodeCv(amend_index, code[cursor]);
87 // TODO Implement Bindless Index custom variable 110 // TODO Implement Bindless Index custom variable
88 auto track = 111 auto track = MakeTrackSampler<ArraySamplerNode>(cbuf->GetIndex(),
89 MakeTrackSampler<ArraySamplerNode>(cbuf->GetIndex(), offset_inm->GetValue(), 0); 112 offset_inm->GetValue(), bindless_cv);
90 return {tracked, track}; 113 return {tracked, track};
91 } 114 }
92 return {}; 115 return {};