summaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp9
-rw-r--r--src/video_core/shader/decode/texture.cpp22
-rw-r--r--src/video_core/shader/shader_ir.h36
4 files changed, 48 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index 4e04ab2f8..9f7b7272e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.h
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h
@@ -58,6 +58,7 @@ private:
58struct ShaderEntries { 58struct ShaderEntries {
59 std::vector<ConstBufferEntry> const_buffers; 59 std::vector<ConstBufferEntry> const_buffers;
60 std::vector<SamplerEntry> samplers; 60 std::vector<SamplerEntry> samplers;
61 std::vector<SamplerEntry> bindless_samplers;
61 std::vector<GlobalMemoryEntry> global_memory_entries; 62 std::vector<GlobalMemoryEntry> global_memory_entries;
62 std::array<bool, Maxwell::NumClipDistances> clip_distances{}; 63 std::array<bool, Maxwell::NumClipDistances> clip_distances{};
63 std::size_t shader_length{}; 64 std::size_t shader_length{};
@@ -68,4 +69,4 @@ std::string GetCommonDeclarations();
68ProgramResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage, 69ProgramResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage,
69 const std::string& suffix); 70 const std::string& suffix);
70 71
71} // namespace OpenGL::GLShader \ No newline at end of file 72} // namespace OpenGL::GLShader
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index 6a95af6f6..e27740383 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -319,16 +319,18 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
319 u32 type{}; 319 u32 type{};
320 u8 is_array{}; 320 u8 is_array{};
321 u8 is_shadow{}; 321 u8 is_shadow{};
322 u8 is_bindless{};
322 if (file.ReadBytes(&offset, sizeof(u64)) != sizeof(u64) || 323 if (file.ReadBytes(&offset, sizeof(u64)) != sizeof(u64) ||
323 file.ReadBytes(&index, sizeof(u64)) != sizeof(u64) || 324 file.ReadBytes(&index, sizeof(u64)) != sizeof(u64) ||
324 file.ReadBytes(&type, sizeof(u32)) != sizeof(u32) || 325 file.ReadBytes(&type, sizeof(u32)) != sizeof(u32) ||
325 file.ReadBytes(&is_array, sizeof(u8)) != sizeof(u8) || 326 file.ReadBytes(&is_array, sizeof(u8)) != sizeof(u8) ||
326 file.ReadBytes(&is_shadow, sizeof(u8)) != sizeof(u8)) { 327 file.ReadBytes(&is_shadow, sizeof(u8)) != sizeof(u8) ||
328 file.ReadBytes(&is_bindless, sizeof(u8)) != sizeof(u8)) {
327 return {}; 329 return {};
328 } 330 }
329 entry.entries.samplers.emplace_back( 331 entry.entries.samplers.emplace_back(
330 static_cast<std::size_t>(offset), static_cast<std::size_t>(index), 332 static_cast<std::size_t>(offset), static_cast<std::size_t>(index),
331 static_cast<Tegra::Shader::TextureType>(type), is_array != 0, is_shadow != 0, false); 333 static_cast<Tegra::Shader::TextureType>(type), is_array != 0, is_shadow != 0, is_bindless != 0);
332 } 334 }
333 335
334 u32 global_memory_count{}; 336 u32 global_memory_count{};
@@ -388,7 +390,8 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(FileUtil::IOFile& file, u64 uniqu
388 file.WriteObject(static_cast<u64>(sampler.GetIndex())) != 1 || 390 file.WriteObject(static_cast<u64>(sampler.GetIndex())) != 1 ||
389 file.WriteObject(static_cast<u32>(sampler.GetType())) != 1 || 391 file.WriteObject(static_cast<u32>(sampler.GetType())) != 1 ||
390 file.WriteObject(static_cast<u8>(sampler.IsArray() ? 1 : 0)) != 1 || 392 file.WriteObject(static_cast<u8>(sampler.IsArray() ? 1 : 0)) != 1 ||
391 file.WriteObject(static_cast<u8>(sampler.IsShadow() ? 1 : 0)) != 1) { 393 file.WriteObject(static_cast<u8>(sampler.IsShadow() ? 1 : 0)) != 1 ||
394 file.WriteObject(static_cast<u8>(sampler.IsBindless() ? 1 : 0)) != 1) {
392 return false; 395 return false;
393 } 396 }
394 } 397 }
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