summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar Rodrigo Locatti2019-11-06 04:54:11 +0000
committerGravatar GitHub2019-11-06 04:54:11 +0000
commit654b77d2ec372bd986d472da7491d0156d0af52e (patch)
tree163ac38e64ed94bdcf3a4ee3c50816c6882cc138 /src/video_core/shader/decode
parentMerge pull request #3073 from DarkLordZach/azure-rename-partial (diff)
parentshader/node: Unpack bindless texture encoding (diff)
downloadyuzu-654b77d2ec372bd986d472da7491d0156d0af52e.tar.gz
yuzu-654b77d2ec372bd986d472da7491d0156d0af52e.tar.xz
yuzu-654b77d2ec372bd986d472da7491d0156d0af52e.zip
Merge pull request #3039 from ReinUsesLisp/cleanup-samplers
shader/node: Unpack bindless texture encoding
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/image.cpp50
-rw-r--r--src/video_core/shader/decode/texture.cpp59
2 files changed, 55 insertions, 54 deletions
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index b02d2cb95..d2fe4ec5d 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -143,39 +143,37 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
143} 143}
144 144
145Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { 145Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) {
146 const auto offset{static_cast<std::size_t>(image.index.Value())}; 146 const auto offset = static_cast<u32>(image.index.Value());
147 if (const auto existing_image = TryUseExistingImage(offset, type)) { 147
148 return *existing_image; 148 const auto it =
149 std::find_if(std::begin(used_images), std::end(used_images),
150 [offset](const Image& entry) { return entry.GetOffset() == offset; });
151 if (it != std::end(used_images)) {
152 ASSERT(!it->IsBindless() && it->GetType() == it->GetType());
153 return *it;
149 } 154 }
150 155
151 const std::size_t next_index{used_images.size()}; 156 const auto next_index = static_cast<u32>(used_images.size());
152 return used_images.emplace(offset, Image{offset, next_index, type}).first->second; 157 return used_images.emplace_back(next_index, offset, type);
153} 158}
154 159
155Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { 160Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) {
156 const Node image_register{GetRegister(reg)}; 161 const Node image_register = GetRegister(reg);
157 const auto [base_image, cbuf_index, cbuf_offset]{ 162 const auto [base_image, buffer, offset] =
158 TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))}; 163 TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()));
159 const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)}; 164
160 165 const auto it =
161 if (const auto image = TryUseExistingImage(cbuf_key, type)) { 166 std::find_if(std::begin(used_images), std::end(used_images),
162 return *image; 167 [buffer = buffer, offset = offset](const Image& entry) {
163 } 168 return entry.GetBuffer() == buffer && entry.GetOffset() == offset;
164 169 });
165 const std::size_t next_index{used_images.size()}; 170 if (it != std::end(used_images)) {
166 return used_images.emplace(cbuf_key, Image{cbuf_index, cbuf_offset, next_index, type}) 171 ASSERT(it->IsBindless() && it->GetType() == it->GetType());
167 .first->second; 172 return *it;
168}
169
170Image* ShaderIR::TryUseExistingImage(u64 offset, Tegra::Shader::ImageType type) {
171 auto it = used_images.find(offset);
172 if (it == used_images.end()) {
173 return nullptr;
174 } 173 }
175 auto& image = it->second;
176 ASSERT(image.GetType() == type);
177 174
178 return &image; 175 const auto next_index = static_cast<u32>(used_images.size());
176 return used_images.emplace_back(next_index, offset, buffer, type);
179} 177}
180 178
181} // namespace VideoCommon::Shader 179} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 4c838c8bb..ca690b58b 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -262,7 +262,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
262 break; 262 break;
263 } 263 }
264 case OpCode::Id::TLDS: { 264 case OpCode::Id::TLDS: {
265 const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()}; 265 const TextureType texture_type{instr.tlds.GetTextureType()};
266 const bool is_array{instr.tlds.IsArrayTexture()}; 266 const bool is_array{instr.tlds.IsArrayTexture()};
267 267
268 UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI), 268 UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI),
@@ -293,77 +293,80 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
293 std::optional<SamplerInfo> sampler_info) { 293 std::optional<SamplerInfo> sampler_info) {
294 const auto offset = static_cast<u32>(sampler.index.Value()); 294 const auto offset = static_cast<u32>(sampler.index.Value());
295 295
296 Tegra::Shader::TextureType type; 296 TextureType type;
297 bool is_array; 297 bool is_array;
298 bool is_shadow; 298 bool is_shadow;
299 if (sampler_info) { 299 if (sampler_info) {
300 type = sampler_info->type; 300 type = sampler_info->type;
301 is_array = sampler_info->is_array; 301 is_array = sampler_info->is_array;
302 is_shadow = sampler_info->is_shadow; 302 is_shadow = sampler_info->is_shadow;
303 } else if (auto sampler = locker.ObtainBoundSampler(offset); sampler) { 303 } else if (const auto sampler = locker.ObtainBoundSampler(offset)) {
304 type = sampler->texture_type.Value(); 304 type = sampler->texture_type.Value();
305 is_array = sampler->is_array.Value() != 0; 305 is_array = sampler->is_array.Value() != 0;
306 is_shadow = sampler->is_shadow.Value() != 0; 306 is_shadow = sampler->is_shadow.Value() != 0;
307 } else { 307 } else {
308 type = Tegra::Shader::TextureType::Texture2D; 308 LOG_WARNING(HW_GPU, "Unknown sampler info");
309 type = TextureType::Texture2D;
309 is_array = false; 310 is_array = false;
310 is_shadow = false; 311 is_shadow = false;
311 } 312 }
312 313
313 // If this sampler has already been used, return the existing mapping. 314 // If this sampler has already been used, return the existing mapping.
314 const auto itr = 315 const auto it =
315 std::find_if(used_samplers.begin(), used_samplers.end(), 316 std::find_if(used_samplers.begin(), used_samplers.end(),
316 [&](const Sampler& entry) { return entry.GetOffset() == offset; }); 317 [offset](const Sampler& entry) { return entry.GetOffset() == offset; });
317 if (itr != used_samplers.end()) { 318 if (it != used_samplers.end()) {
318 ASSERT(itr->GetType() == type && itr->IsArray() == is_array && 319 ASSERT(!it->IsBindless() && it->GetType() == type && it->IsArray() == is_array &&
319 itr->IsShadow() == is_shadow); 320 it->IsShadow() == is_shadow);
320 return *itr; 321 return *it;
321 } 322 }
322 323
323 // Otherwise create a new mapping for this sampler 324 // Otherwise create a new mapping for this sampler
324 const std::size_t next_index = used_samplers.size(); 325 const auto next_index = static_cast<u32>(used_samplers.size());
325 const Sampler entry{offset, next_index, type, is_array, is_shadow}; 326 return used_samplers.emplace_back(Sampler(next_index, offset, type, is_array, is_shadow));
326 return *used_samplers.emplace(entry).first; 327}
327} // namespace VideoCommon::Shader
328 328
329const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, 329const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg,
330 std::optional<SamplerInfo> sampler_info) { 330 std::optional<SamplerInfo> sampler_info) {
331 const Node sampler_register = GetRegister(reg); 331 const Node sampler_register = GetRegister(reg);
332 const auto [base_sampler, cbuf_index, cbuf_offset] = 332 const auto [base_sampler, buffer, offset] =
333 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); 333 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size()));
334 ASSERT(base_sampler != nullptr); 334 ASSERT(base_sampler != nullptr);
335 const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset); 335
336 Tegra::Shader::TextureType type; 336 TextureType type;
337 bool is_array; 337 bool is_array;
338 bool is_shadow; 338 bool is_shadow;
339 if (sampler_info) { 339 if (sampler_info) {
340 type = sampler_info->type; 340 type = sampler_info->type;
341 is_array = sampler_info->is_array; 341 is_array = sampler_info->is_array;
342 is_shadow = sampler_info->is_shadow; 342 is_shadow = sampler_info->is_shadow;
343 } else if (auto sampler = locker.ObtainBindlessSampler(cbuf_index, cbuf_offset); sampler) { 343 } else if (const auto sampler = locker.ObtainBindlessSampler(buffer, offset)) {
344 type = sampler->texture_type.Value(); 344 type = sampler->texture_type.Value();
345 is_array = sampler->is_array.Value() != 0; 345 is_array = sampler->is_array.Value() != 0;
346 is_shadow = sampler->is_shadow.Value() != 0; 346 is_shadow = sampler->is_shadow.Value() != 0;
347 } else { 347 } else {
348 type = Tegra::Shader::TextureType::Texture2D; 348 LOG_WARNING(HW_GPU, "Unknown sampler info");
349 type = TextureType::Texture2D;
349 is_array = false; 350 is_array = false;
350 is_shadow = false; 351 is_shadow = false;
351 } 352 }
352 353
353 // If this sampler has already been used, return the existing mapping. 354 // If this sampler has already been used, return the existing mapping.
354 const auto itr = 355 const auto it =
355 std::find_if(used_samplers.begin(), used_samplers.end(), 356 std::find_if(used_samplers.begin(), used_samplers.end(),
356 [&](const Sampler& entry) { return entry.GetOffset() == cbuf_key; }); 357 [buffer = buffer, offset = offset](const Sampler& entry) {
357 if (itr != used_samplers.end()) { 358 return entry.GetBuffer() == buffer && entry.GetOffset() == offset;
358 ASSERT(itr->GetType() == type && itr->IsArray() == is_array && 359 });
359 itr->IsShadow() == is_shadow); 360 if (it != used_samplers.end()) {
360 return *itr; 361 ASSERT(it->IsBindless() && it->GetType() == type && it->IsArray() == is_array &&
362 it->IsShadow() == is_shadow);
363 return *it;
361 } 364 }
362 365
363 // Otherwise create a new mapping for this sampler 366 // Otherwise create a new mapping for this sampler
364 const std::size_t next_index = used_samplers.size(); 367 const auto next_index = static_cast<u32>(used_samplers.size());
365 const Sampler entry{cbuf_index, cbuf_offset, next_index, type, is_array, is_shadow}; 368 return used_samplers.emplace_back(
366 return *used_samplers.emplace(entry).first; 369 Sampler(next_index, offset, buffer, type, is_array, is_shadow));
367} 370}
368 371
369void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { 372void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) {