summaryrefslogtreecommitdiff
path: root/src/video_core/shader
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-03-26 17:56:16 -0400
committerGravatar FernandoS272019-04-08 11:23:45 -0400
commitfe392fff2425c10c9683a4058c779d352b9855ec (patch)
tree3227202eb53093f9a22d9e704928ade70cda08c4 /src/video_core/shader
parentImplement Bindless Samplers and TEX_B in the IR. (diff)
downloadyuzu-fe392fff2425c10c9683a4058c779d352b9855ec.tar.gz
yuzu-fe392fff2425c10c9683a4058c779d352b9855ec.tar.xz
yuzu-fe392fff2425c10c9683a4058c779d352b9855ec.zip
Unify both sampler types.
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode/texture.cpp22
-rw-r--r--src/video_core/shader/shader_ir.h36
2 files changed, 40 insertions, 18 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 23f2ad999..3ac04f6b7 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -267,7 +267,7 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, Textu
267 267
268 // Otherwise create a new mapping for this sampler 268 // Otherwise create a new mapping for this sampler
269 const std::size_t next_index = used_samplers.size(); 269 const std::size_t next_index = used_samplers.size();
270 const Sampler entry{offset, next_index, type, is_array, is_shadow, false}; 270 const Sampler entry{offset, next_index, type, is_array, is_shadow};
271 return *used_samplers.emplace(entry).first; 271 return *used_samplers.emplace(entry).first;
272} 272}
273 273
@@ -281,20 +281,22 @@ const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg,
281 ASSERT(cbuf_offset_imm != nullptr); 281 ASSERT(cbuf_offset_imm != nullptr);
282 const auto cbuf_offset = cbuf_offset_imm->GetValue(); 282 const auto cbuf_offset = cbuf_offset_imm->GetValue();
283 const auto cbuf_index = cbuf->GetIndex(); 283 const auto cbuf_index = cbuf->GetIndex();
284 const std::pair<u32, u32> cbuf_pair = {cbuf_index, cbuf_offset}; 284 const u64 cbuf_key = (cbuf_index << 32) | cbuf_offset;
285 285
286 // If this sampler has already been used, return the existing mapping. 286 // If this sampler has already been used, return the existing mapping.
287 if (used_bindless_samplers.count(cbuf_pair) > 0) { 287 const auto itr =
288 const auto& sampler = used_bindless_samplers[cbuf_pair]; 288 std::find_if(used_samplers.begin(), used_samplers.end(),
289 ASSERT(sampler.GetType() == type && sampler.IsArray() == is_array && 289 [&](const Sampler& entry) { return entry.GetOffset() == cbuf_key; });
290 sampler.IsShadow() == is_shadow); 290 if (itr != used_samplers.end()) {
291 return sampler; 291 ASSERT(itr->GetType() == type && itr->IsArray() == is_array &&
292 itr->IsShadow() == is_shadow);
293 return *itr;
292 } 294 }
293 295
294 // Otherwise create a new mapping for this sampler 296 // Otherwise create a new mapping for this sampler
295 const std::size_t next_index = used_bindless_samplers.size(); 297 const std::size_t next_index = used_samplers.size();
296 const Sampler entry{0, next_index, type, is_array, is_shadow, true}; 298 const Sampler entry{cbuf_index, cbuf_offset, next_index, type, is_array, is_shadow};
297 return (*used_bindless_samplers.emplace(std::make_pair(cbuf_pair, entry)).first).second; 299 return *used_samplers.emplace(entry).first;
298} 300}
299 301
300void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { 302void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) {
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 712dc3ddb..773c71fa5 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -196,12 +196,24 @@ enum class ExitMethod {
196 196
197class Sampler { 197class Sampler {
198public: 198public:
199 Sampler() = default; 199 // Use this constructor for binded Samplers
200 explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type,
201 bool is_array, bool is_shadow)
202 : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow},
203 is_bindless{false} {}
204
205 // Use this constructor for bindless Samplers
206 explicit Sampler(u32 cbuf_index, u32 cbuf_offset, std::size_t index,
207 Tegra::Shader::TextureType type, bool is_array, bool is_shadow)
208 : offset{(static_cast<u64>(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type}, is_array{is_array},
209 is_shadow{is_shadow}, is_bindless{true} {}
210
211 // Use this only for serialization/deserialization
200 explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type, 212 explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type,
201 bool is_array, bool is_shadow, bool is_bindless) 213 bool is_array, bool is_shadow, bool is_bindless)
202 : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow}, is_bindless{is_bindless} {} 214 : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow},
215 is_bindless{is_bindless} {}
203 216
204 ~Sampler() = default;
205 217
206 std::size_t GetOffset() const { 218 std::size_t GetOffset() const {
207 return offset; 219 return offset;
@@ -223,6 +235,14 @@ public:
223 return is_shadow; 235 return is_shadow;
224 } 236 }
225 237
238 bool IsBindless() const {
239 return is_bindless;
240 }
241
242 std::pair<u32, u32> GetBindlessCBuf() {
243 return {offset >> 32, offset & 0x00000000FFFFFFFFULL};
244 }
245
226 bool operator<(const Sampler& rhs) const { 246 bool operator<(const Sampler& rhs) const {
227 return std::tie(offset, index, type, is_array, is_shadow) < 247 return std::tie(offset, index, type, is_array, is_shadow) <
228 std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_array, rhs.is_shadow); 248 std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_array, rhs.is_shadow);
@@ -234,8 +254,8 @@ private:
234 std::size_t offset{}; 254 std::size_t offset{};
235 std::size_t index{}; ///< Value used to index into the generated GLSL sampler array. 255 std::size_t index{}; ///< Value used to index into the generated GLSL sampler array.
236 Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) 256 Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc)
237 bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. 257 bool is_array{}; ///< Whether the texture is being sampled as an array texture or not.
238 bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. 258 bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not.
239 bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not. 259 bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not.
240}; 260};
241 261
@@ -735,8 +755,9 @@ private:
735 Tegra::Shader::TextureType type, bool is_array, bool is_shadow); 755 Tegra::Shader::TextureType type, bool is_array, bool is_shadow);
736 756
737 // Accesses a texture sampler for a bindless texture. 757 // Accesses a texture sampler for a bindless texture.
738 const Sampler& GetBindlessSampler(const Tegra::Shader::Register& reg, Tegra::Shader::TextureType type, 758 const Sampler& GetBindlessSampler(const Tegra::Shader::Register& reg,
739 bool is_array, bool is_shadow); 759 Tegra::Shader::TextureType type, bool is_array,
760 bool is_shadow);
740 761
741 /// Extracts a sequence of bits from a node 762 /// Extracts a sequence of bits from a node
742 Node BitfieldExtract(Node value, u32 offset, u32 bits); 763 Node BitfieldExtract(Node value, u32 offset, u32 bits);
@@ -845,7 +866,6 @@ private:
845 std::set<Tegra::Shader::Attribute::Index> used_output_attributes; 866 std::set<Tegra::Shader::Attribute::Index> used_output_attributes;
846 std::map<u32, ConstBuffer> used_cbufs; 867 std::map<u32, ConstBuffer> used_cbufs;
847 std::set<Sampler> used_samplers; 868 std::set<Sampler> used_samplers;
848 std::map<std::pair<u32, u32>, Sampler> used_bindless_samplers;
849 std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{}; 869 std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{};
850 std::set<GlobalMemoryBase> used_global_memory_bases; 870 std::set<GlobalMemoryBase> used_global_memory_bases;
851 871