aboutsummaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/texture_pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/ir_opt/texture_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp34
1 files changed, 29 insertions, 5 deletions
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index 514cd9b2b6..db8f1ac716 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -345,7 +345,8 @@ static inline u32 GetTextureHandleCached(Environment& env, const ConstBufferAddr
// Cached variants of existing helpers
// A handle computed per draw has no descriptor to read at translation time: assume an ordinary
-// floating-point 2D texture, the instruction's own type deciding the rest.
+// floating-point 2D texture, the instruction's own type deciding the rest (see the TexturePass
+// ImageQueryDimensions case, which has none).
static inline TextureType ReadTextureTypeCached(Environment& env, const ConstBufferAddr& cbuf) {
if (cbuf.handle_program != ~0U) return TextureType::Color2D;
return env.ReadTextureType(GetTextureHandleCached(env, cbuf));
@@ -1010,7 +1011,8 @@ public:
desc.secondary_cbuf_offset == existing.secondary_cbuf_offset &&
desc.secondary_shift_left == existing.secondary_shift_left &&
desc.count == existing.count && desc.size_shift == existing.size_shift &&
- desc.has_secondary == existing.has_secondary;
+ desc.has_secondary == existing.has_secondary &&
+ desc.handle_program == existing.handle_program;
});
}
@@ -1018,7 +1020,8 @@ public:
const u32 index{Add(image_buffer_descriptors, desc, [&desc](const auto& existing) {
return desc.format == existing.format && desc.cbuf_index == existing.cbuf_index &&
desc.cbuf_offset == existing.cbuf_offset && desc.count == existing.count &&
- desc.size_shift == existing.size_shift;
+ desc.size_shift == existing.size_shift &&
+ desc.handle_program == existing.handle_program;
})};
image_buffer_descriptors[index].is_written |= desc.is_written;
image_buffer_descriptors[index].is_read |= desc.is_read;
@@ -1050,7 +1053,8 @@ public:
return desc.type == existing.type && desc.format == existing.format &&
desc.cbuf_index == existing.cbuf_index &&
desc.cbuf_offset == existing.cbuf_offset && desc.count == existing.count &&
- desc.size_shift == existing.size_shift;
+ desc.size_shift == existing.size_shift &&
+ desc.handle_program == existing.handle_program;
})};
image_descriptors[index].is_written |= desc.is_written;
image_descriptors[index].is_read |= desc.is_read;
@@ -1186,6 +1190,18 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
has_last_is_integer = true;
return last_is_integer;
}};
+ // A handle program has no descriptor to read a type from, and ImageQueryDimensions carries
+ // none: it takes the type of another instruction using the same handle.
+ std::unordered_map<u32, TextureType> handle_program_types;
+ for (const TextureInst& texture_inst : to_replace) {
+ const IR::Opcode opcode{IndexedInstruction(*texture_inst.inst)};
+ if (texture_inst.cbuf.handle_program != ~0U && opcode != IR::Opcode::ImageQueryDimensions &&
+ !IsStorageImageOpcode(opcode)) {
+ handle_program_types.try_emplace(
+ texture_inst.cbuf.handle_program,
+ texture_inst.inst->Flags<IR::TextureInstInfo>().type.Value());
+ }
+ }
for (TextureInst& texture_inst : to_replace) {
// TODO: Handle arrays
IR::Inst* const inst{texture_inst.inst};
@@ -1196,7 +1212,12 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
bool is_multisample{false};
switch (inst->GetOpcode()) {
case IR::Opcode::ImageQueryDimensions:
- flags.type.Assign(ReadTextureTypeCached(env, cbuf));
+ if (const auto it{handle_program_types.find(cbuf.handle_program)};
+ it != handle_program_types.end()) {
+ flags.type.Assign(it->second);
+ } else {
+ flags.type.Assign(ReadTextureTypeCached(env, cbuf));
+ }
inst->SetFlags(flags);
break;
case IR::Opcode::ImageSampleImplicitLod:
@@ -1261,6 +1282,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.cbuf_offset = cbuf.offset,
.count = count,
.size_shift = size_shift,
+ .handle_program = cbuf.handle_program,
});
} else {
index = descriptors.Add(ImageDescriptor{
@@ -1273,6 +1295,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.cbuf_offset = cbuf.offset,
.count = count,
.size_shift = size_shift,
+ .handle_program = cbuf.handle_program,
});
}
break;
@@ -1289,6 +1312,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.secondary_shift_left = cbuf.secondary_shift_left,
.count = count,
.size_shift = size_shift,
+ .handle_program = cbuf.handle_program,
});
} else {
count = std::min(count, sampled_dynamic_cap);