mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
Patch ImageQueryDimensions
This commit is contained in:
parent
ad9507dbfd
commit
f501d13c21
@ -87,6 +87,14 @@ struct SamplerResource {
|
|||||||
};
|
};
|
||||||
using SamplerResourceList = boost::container::small_vector<SamplerResource, 16>;
|
using SamplerResourceList = boost::container::small_vector<SamplerResource, 16>;
|
||||||
|
|
||||||
|
struct FMaskResource {
|
||||||
|
u32 sgpr_base;
|
||||||
|
u32 dword_offset;
|
||||||
|
|
||||||
|
constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
|
||||||
|
};
|
||||||
|
using FMaskResourceList = boost::container::small_vector<FMaskResource, 16>;
|
||||||
|
|
||||||
struct PushData {
|
struct PushData {
|
||||||
static constexpr u32 BufOffsetIndex = 2;
|
static constexpr u32 BufOffsetIndex = 2;
|
||||||
static constexpr u32 UdRegsIndex = 4;
|
static constexpr u32 UdRegsIndex = 4;
|
||||||
@ -179,6 +187,7 @@ struct Info {
|
|||||||
TextureBufferResourceList texture_buffers;
|
TextureBufferResourceList texture_buffers;
|
||||||
ImageResourceList images;
|
ImageResourceList images;
|
||||||
SamplerResourceList samplers;
|
SamplerResourceList samplers;
|
||||||
|
FMaskResourceList fmasks;
|
||||||
|
|
||||||
std::span<const u32> user_data;
|
std::span<const u32> user_data;
|
||||||
Stage stage;
|
Stage stage;
|
||||||
@ -263,6 +272,10 @@ constexpr AmdGpu::Sampler SamplerResource::GetSharp(const Info& info) const noex
|
|||||||
return inline_sampler ? inline_sampler : info.ReadUd<AmdGpu::Sampler>(sgpr_base, dword_offset);
|
return inline_sampler ? inline_sampler : info.ReadUd<AmdGpu::Sampler>(sgpr_base, dword_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr AmdGpu::Image FMaskResource::GetSharp(const Info& info) const noexcept {
|
||||||
|
return info.ReadUd<AmdGpu::Image>(sgpr_base, dword_offset);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Shader
|
} // namespace Shader
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -147,7 +147,7 @@ public:
|
|||||||
explicit Descriptors(Info& info_)
|
explicit Descriptors(Info& info_)
|
||||||
: info{info_}, buffer_resources{info_.buffers},
|
: info{info_}, buffer_resources{info_.buffers},
|
||||||
texture_buffer_resources{info_.texture_buffers}, image_resources{info_.images},
|
texture_buffer_resources{info_.texture_buffers}, image_resources{info_.images},
|
||||||
sampler_resources{info_.samplers} {}
|
sampler_resources{info_.samplers}, fmask_resources(info_.fmasks) {}
|
||||||
|
|
||||||
u32 Add(const BufferResource& desc) {
|
u32 Add(const BufferResource& desc) {
|
||||||
const u32 index{Add(buffer_resources, desc, [&desc](const auto& existing) {
|
const u32 index{Add(buffer_resources, desc, [&desc](const auto& existing) {
|
||||||
@ -193,6 +193,14 @@ public:
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 Add(const FMaskResource& desc) {
|
||||||
|
u32 index = Add(fmask_resources, desc, [&desc](const auto& existing) {
|
||||||
|
return desc.sgpr_base == existing.sgpr_base &&
|
||||||
|
desc.dword_offset == existing.dword_offset;
|
||||||
|
});
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Descriptors, typename Descriptor, typename Func>
|
template <typename Descriptors, typename Descriptor, typename Func>
|
||||||
static u32 Add(Descriptors& descriptors, const Descriptor& desc, Func&& pred) {
|
static u32 Add(Descriptors& descriptors, const Descriptor& desc, Func&& pred) {
|
||||||
@ -209,6 +217,7 @@ private:
|
|||||||
TextureBufferResourceList& texture_buffer_resources;
|
TextureBufferResourceList& texture_buffer_resources;
|
||||||
ImageResourceList& image_resources;
|
ImageResourceList& image_resources;
|
||||||
SamplerResourceList& sampler_resources;
|
SamplerResourceList& sampler_resources;
|
||||||
|
FMaskResourceList& fmask_resources;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
@ -673,6 +682,19 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||||||
case IR::Opcode::ImageQueryLod:
|
case IR::Opcode::ImageQueryLod:
|
||||||
inst.ReplaceUsesWith(ir.Imm32(1));
|
inst.ReplaceUsesWith(ir.Imm32(1));
|
||||||
return;
|
return;
|
||||||
|
case IR::Opcode::ImageQueryDimensions: {
|
||||||
|
IR::Value dims = ir.CompositeConstruct(ir.Imm32(static_cast<u32>(image.width)), // x
|
||||||
|
ir.Imm32(static_cast<u32>(image.width)), // y
|
||||||
|
ir.Imm32(1), ir.Imm32(1)); // depth, mip
|
||||||
|
inst.ReplaceUsesWith(dims);
|
||||||
|
|
||||||
|
// Track FMask resource to do specialization.
|
||||||
|
descriptors.Add(FMaskResource{
|
||||||
|
.sgpr_base = tsharp.sgpr_base,
|
||||||
|
.dword_offset = tsharp.dword_offset,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Can't patch fmask instruction {}", inst.GetOpcode());
|
UNREACHABLE_MSG("Can't patch fmask instruction {}", inst.GetOpcode());
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,13 @@ struct ImageSpecialization {
|
|||||||
auto operator<=>(const ImageSpecialization&) const = default;
|
auto operator<=>(const ImageSpecialization&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FMaskSpecialization {
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
|
||||||
|
auto operator<=>(const FMaskSpecialization&) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alongside runtime information, this structure also checks bound resources
|
* Alongside runtime information, this structure also checks bound resources
|
||||||
* for compatibility. Can be used as a key for storing shader permutations.
|
* for compatibility. Can be used as a key for storing shader permutations.
|
||||||
@ -46,6 +53,7 @@ struct StageSpecialization {
|
|||||||
boost::container::small_vector<BufferSpecialization, 16> buffers;
|
boost::container::small_vector<BufferSpecialization, 16> buffers;
|
||||||
boost::container::small_vector<TextureBufferSpecialization, 8> tex_buffers;
|
boost::container::small_vector<TextureBufferSpecialization, 8> tex_buffers;
|
||||||
boost::container::small_vector<ImageSpecialization, 16> images;
|
boost::container::small_vector<ImageSpecialization, 16> images;
|
||||||
|
boost::container::small_vector<FMaskSpecialization, 8> fmasks;
|
||||||
Backend::Bindings start{};
|
Backend::Bindings start{};
|
||||||
|
|
||||||
explicit StageSpecialization(const Shader::Info& info_, RuntimeInfo runtime_info_,
|
explicit StageSpecialization(const Shader::Info& info_, RuntimeInfo runtime_info_,
|
||||||
@ -67,6 +75,11 @@ struct StageSpecialization {
|
|||||||
: sharp.GetType();
|
: sharp.GetType();
|
||||||
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
|
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
|
||||||
});
|
});
|
||||||
|
ForEachSharp(binding, fmasks, info->fmasks,
|
||||||
|
[](auto& spec, const auto& desc, AmdGpu::Image sharp) {
|
||||||
|
spec.width = sharp.width;
|
||||||
|
spec.height = sharp.height;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForEachSharp(u32& binding, auto& spec_list, auto& desc_list, auto&& func) {
|
void ForEachSharp(u32& binding, auto& spec_list, auto& desc_list, auto&& func) {
|
||||||
@ -105,6 +118,11 @@ struct StageSpecialization {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (u32 i = 0; i < fmasks.size(); i++) {
|
||||||
|
if (other.bitset[binding++] && fmasks[i] != other.fmasks[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user