mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 03:54:45 +00:00
shader_recompiler: Add texel buffer multiplier
* Fixes format mismatch assert when vsharp stride is multiple of format stride
This commit is contained in:
parent
7276853b02
commit
22b816227f
5 changed files with 17 additions and 5 deletions
|
@ -326,7 +326,9 @@ Id EmitLoadBufferU32x4(EmitContext& ctx, IR::Inst*, u32 handle, Id address) {
|
|||
Id EmitLoadBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) {
|
||||
const auto& buffer = ctx.texture_buffers[handle];
|
||||
const Id tex_buffer = ctx.OpLoad(buffer.image_type, buffer.id);
|
||||
const Id coord = ctx.OpIAdd(ctx.U32[1], address, buffer.coord_offset);
|
||||
const Id coord =
|
||||
ctx.OpIAdd(ctx.U32[1], ctx.OpShiftLeftLogical(ctx.U32[1], address, buffer.coord_shift),
|
||||
buffer.coord_offset);
|
||||
Id texel = buffer.is_storage ? ctx.OpImageRead(buffer.result_type, tex_buffer, coord)
|
||||
: ctx.OpImageFetch(buffer.result_type, tex_buffer, coord);
|
||||
if (buffer.is_integer) {
|
||||
|
@ -372,7 +374,9 @@ void EmitStoreBufferU32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
|
|||
void EmitStoreBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
const auto& buffer = ctx.texture_buffers[handle];
|
||||
const Id tex_buffer = ctx.OpLoad(buffer.image_type, buffer.id);
|
||||
const Id coord = ctx.OpIAdd(ctx.U32[1], address, buffer.coord_offset);
|
||||
const Id coord =
|
||||
ctx.OpIAdd(ctx.U32[1], ctx.OpShiftLeftLogical(ctx.U32[1], address, buffer.coord_shift),
|
||||
buffer.coord_offset);
|
||||
if (buffer.is_integer) {
|
||||
value = ctx.OpBitcast(buffer.result_type, value);
|
||||
}
|
||||
|
|
|
@ -207,6 +207,8 @@ void EmitContext::DefineBufferOffsets() {
|
|||
push_data_block, ConstU32(half), ConstU32(comp))};
|
||||
const Id value{OpLoad(U32[1], ptr)};
|
||||
tex_buffer.coord_offset = OpBitFieldUExtract(U32[1], value, ConstU32(offset), ConstU32(6U));
|
||||
tex_buffer.coord_shift =
|
||||
OpBitFieldUExtract(U32[1], value, ConstU32(offset + 6U), ConstU32(2U));
|
||||
Name(tex_buffer.coord_offset, fmt::format("texbuf{}_off", binding));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ public:
|
|||
struct TextureBufferDefinition {
|
||||
Id id;
|
||||
Id coord_offset;
|
||||
Id coord_shift;
|
||||
u32 binding;
|
||||
Id image_type;
|
||||
Id result_type;
|
||||
|
|
|
@ -105,6 +105,11 @@ struct PushData {
|
|||
ASSERT(offset < 256 && binding < buf_offsets.size());
|
||||
buf_offsets[binding] = offset;
|
||||
}
|
||||
|
||||
void AddTexelOffset(u32 binding, u32 multiplier, u32 texel_offset) {
|
||||
ASSERT(texel_offset < 64 && multiplier < 16);
|
||||
buf_offsets[binding] = texel_offset | (std::bit_width(multiplier) << 6);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(PushData) <= 128,
|
||||
"PushData size is greater than minimum size guaranteed by Vulkan spec");
|
||||
|
|
|
@ -548,12 +548,12 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
|
|||
const auto [vk_buffer, offset] = buffer_cache.ObtainBuffer(
|
||||
vsharp.base_address, vsharp.GetSize(), desc.is_written, true, buffer_id);
|
||||
const u32 fmt_stride = AmdGpu::NumBits(vsharp.GetDataFmt()) >> 3;
|
||||
ASSERT_MSG(fmt_stride == vsharp.GetStride(),
|
||||
"Texel buffer stride must match format stride");
|
||||
const u32 buf_stride = vsharp.GetStride();
|
||||
ASSERT_MSG(buf_stride % fmt_stride, "Texel buffer stride must match format stride");
|
||||
const u32 offset_aligned = Common::AlignDown(offset, alignment);
|
||||
const u32 adjust = offset - offset_aligned;
|
||||
ASSERT(adjust % fmt_stride == 0);
|
||||
push_data.AddOffset(binding.buffer, adjust / fmt_stride);
|
||||
push_data.AddTexelOffset(binding.buffer, buf_stride / fmt_stride, adjust / fmt_stride);
|
||||
buffer_view =
|
||||
vk_buffer->View(offset_aligned, vsharp.GetSize() + adjust, desc.is_written,
|
||||
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
|
||||
|
|
Loading…
Add table
Reference in a new issue