mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 19:36:55 +02:00
shader: align address-memory buffer bindings
This commit is contained in:
@@ -123,8 +123,10 @@ static BufferView NativeStorageBuffer(RenderContext& context, CommandBuffer& com
|
||||
static BufferView
|
||||
NativeAddressBuffer(RenderContext& context, CommandBuffer& command_buffer,
|
||||
const ShaderRecompiler::IR::AddressResource& resource,
|
||||
const ShaderRecompiler::IR::ResourceSnapshot::Address& address) {
|
||||
const ShaderRecompiler::IR::ResourceSnapshot::Address& address,
|
||||
uint32_t& address_offset) {
|
||||
BufferView result;
|
||||
address_offset = 0;
|
||||
if (address.binding_base == 0) {
|
||||
BindNullStorageBuffer(context, result);
|
||||
return result;
|
||||
@@ -145,17 +147,17 @@ NativeAddressBuffer(RenderContext& context, CommandBuffer& command_buffer,
|
||||
}
|
||||
const auto& graphics = context.GetGraphics();
|
||||
const auto alignment = graphics.StorageMinAlignment();
|
||||
if (alignment == 0 ||
|
||||
size > graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange ||
|
||||
BufferCache::GetBufferOffset(address.binding_base) % alignment != 0) {
|
||||
EXIT("address resource range or alignment is unsupported\n");
|
||||
}
|
||||
auto binding =
|
||||
context.GetBufferCache().ObtainBuffer(command_buffer, address.binding_base, size);
|
||||
const auto aligned_offset = binding.offset - binding.offset % alignment;
|
||||
const auto adjustment = binding.offset - aligned_offset;
|
||||
const auto max_range = graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange;
|
||||
const auto visible_size = std::min(size, static_cast<uint64_t>(max_range - adjustment));
|
||||
address_offset = static_cast<uint32_t>(adjustment);
|
||||
result.owner = std::move(binding.owner);
|
||||
result.buffer = binding.buffer;
|
||||
result.offset = binding.offset;
|
||||
result.range = static_cast<vk::DeviceSize>(size);
|
||||
result.offset = aligned_offset;
|
||||
result.range = static_cast<vk::DeviceSize>(visible_size + adjustment);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -897,22 +899,28 @@ void RenderExecutor::RebindBuffers(CommandBuffer& buffer,
|
||||
resources.buffers.clear();
|
||||
resources.buffers.reserve(program.info.buffers.size());
|
||||
EXIT_IF(prepared.user_data.size() != layout.ShaderDataDwords());
|
||||
std::fill(prepared.user_data.begin() + layout.buffer_offset_dword, prepared.user_data.end(), 0);
|
||||
std::fill(prepared.user_data.begin() + layout.memory_offset_dword, prepared.user_data.end(), 0);
|
||||
auto pack_memory_offset = [&](uint32_t index, uint32_t offset) {
|
||||
const auto dword = layout.memory_offset_dword + index / 4u;
|
||||
const auto shift = (index % 4u) * 8u;
|
||||
prepared.user_data[dword] |= offset << shift;
|
||||
};
|
||||
for (uint32_t i = 0; i < program.info.buffers.size(); i++) {
|
||||
ShaderBufferResource descriptor;
|
||||
CopyNativeDescriptor(snapshot.buffers[i], descriptor.fields);
|
||||
uint32_t buffer_offset = 0;
|
||||
resources.buffers.push_back(NativeStorageBuffer(m_context, buffer, descriptor,
|
||||
program.info.buffers[i], buffer_offset));
|
||||
const auto dword = layout.buffer_offset_dword + i / 4u;
|
||||
const auto shift = (i % 4u) * 8u;
|
||||
prepared.user_data[dword] |= buffer_offset << shift;
|
||||
pack_memory_offset(i, buffer_offset);
|
||||
}
|
||||
resources.addresses.clear();
|
||||
resources.addresses.reserve(program.info.addresses.size());
|
||||
for (uint32_t i = 0; i < program.info.addresses.size(); i++) {
|
||||
uint32_t address_offset = 0;
|
||||
resources.addresses.push_back(NativeAddressBuffer(
|
||||
m_context, buffer, program.info.addresses[i], snapshot.addresses[i]));
|
||||
m_context, buffer, program.info.addresses[i], snapshot.addresses[i], address_offset));
|
||||
pack_memory_offset(static_cast<uint32_t>(program.info.buffers.size()) + i,
|
||||
address_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +109,9 @@ bool ValidateNativeProgram(const IR::Program& program, std::string* error) {
|
||||
}
|
||||
}
|
||||
const auto has_user_storage = present[static_cast<size_t>(Kind::UserData)];
|
||||
if (program.bindings.buffer_offset_dword != program.bindings.user_data_registers.size() ||
|
||||
program.bindings.buffer_offset_count != program.info.buffers.size() ||
|
||||
if (program.bindings.memory_offset_dword != program.bindings.user_data_registers.size() ||
|
||||
program.bindings.memory_offset_count !=
|
||||
program.info.buffers.size() + program.info.addresses.size() ||
|
||||
(!has_user_storage &&
|
||||
program.bindings.push_constant_size != program.bindings.ShaderDataDwords() * 4u) ||
|
||||
(has_user_storage && program.bindings.push_constant_size != 0) ||
|
||||
|
||||
@@ -333,7 +333,8 @@ struct EmitterState {
|
||||
uint32_t wave_size = 64;
|
||||
bool per_invocation_masks = false;
|
||||
uint32_t storage_buffer_variable = 0;
|
||||
std::array<uint32_t, IR::ShaderInfo::MaxBuffers> storage_buffer_offsets {};
|
||||
std::array<uint32_t, IR::ShaderInfo::MaxBuffers + IR::ShaderInfo::MaxAddresses>
|
||||
memory_byte_offsets {};
|
||||
uint32_t address_memory_variable = 0;
|
||||
uint32_t gds_variable = 0;
|
||||
uint32_t gds_length = 0;
|
||||
@@ -713,7 +714,7 @@ uint32_t StorageBufferPackedStride(const EmitterState& state, const IR::MemoryIn
|
||||
|
||||
Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem);
|
||||
|
||||
void EmitStorageBufferOffsets(EmitterState& state);
|
||||
void EmitMemoryOffsets(EmitterState& state);
|
||||
|
||||
uint32_t LdsDwordCount(const EmitterState& state);
|
||||
|
||||
|
||||
@@ -135,6 +135,22 @@ uint32_t AddressByteAddress(ValueEmitContext& ctx, const IR::Inst& inst, const I
|
||||
return Select(state, TypeU32(state), valid, relative, ConstantU32(state, UINT32_MAX));
|
||||
}
|
||||
|
||||
uint32_t AddAddressMemoryOffset(ValueEmitContext& ctx, const IR::MemoryInfo& mem,
|
||||
uint32_t address) {
|
||||
auto& state = ctx.state;
|
||||
const auto binding =
|
||||
ResourceForDescriptor(state, IR::DescriptorBindingKind::AddressMemory, mem.resource);
|
||||
const auto offset =
|
||||
state.memory_byte_offsets[state.program.info.buffers.size() + binding.array_index];
|
||||
const auto corrected = Binary(state, OpIAdd, TypeU32(state), address, offset);
|
||||
const auto not_invalid =
|
||||
Binary(state, OpINotEqual, TypeBool(state), address, ConstantU32(state, UINT32_MAX));
|
||||
const auto no_overflow =
|
||||
Binary(state, OpUGreaterThanEqual, TypeBool(state), corrected, address);
|
||||
return Select(state, TypeU32(state), AndCondition(state, not_invalid, no_overflow), corrected,
|
||||
ConstantU32(state, UINT32_MAX));
|
||||
}
|
||||
|
||||
uint32_t ByteAddress(ValueEmitContext& ctx, const IR::Inst& inst, const IR::MemoryInfo& mem) {
|
||||
if (mem.kind == IR::ResourceKind::Buffer) {
|
||||
return BufferByteAddress(ctx, inst, mem, ctx.Arg(inst, 1), ctx.Arg(inst, 2),
|
||||
@@ -147,7 +163,11 @@ uint32_t ByteAddress(ValueEmitContext& ctx, const IR::Inst& inst, const IR::Memo
|
||||
return Binary(ctx.state, OpIAdd, TypeU32(ctx.state), ctx.Arg(inst, 0),
|
||||
ConstantU32(ctx.state, mem.offset));
|
||||
}
|
||||
return AddressByteAddress(ctx, inst, mem, ctx.Arg(inst, 1), ctx.Arg(inst, 2));
|
||||
const auto address = AddressByteAddress(ctx, inst, mem, ctx.Arg(inst, 1), ctx.Arg(inst, 2));
|
||||
if (mem.kind == IR::ResourceKind::Scratch) {
|
||||
return address;
|
||||
}
|
||||
return AddAddressMemoryOffset(ctx, mem, address);
|
||||
}
|
||||
|
||||
uint32_t DwordIndex(ValueEmitContext& ctx, const IR::Inst& inst, const IR::MemoryInfo& mem) {
|
||||
|
||||
@@ -52,14 +52,14 @@ Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::
|
||||
return state.program.info.buffers[mem.resource].descriptor_format;
|
||||
}
|
||||
|
||||
void EmitStorageBufferOffsets(EmitterState& state) {
|
||||
for (uint32_t i = 0; i < state.program.bindings.buffer_offset_count; i++) {
|
||||
void EmitMemoryOffsets(EmitterState& state) {
|
||||
for (uint32_t i = 0; i < state.program.bindings.memory_offset_count; i++) {
|
||||
const auto word =
|
||||
EmitShaderDataDwordLoad(state, state.program.bindings.buffer_offset_dword + i / 4u);
|
||||
const auto shift = ConstantU32(state, (i % 4u) * 8u + 2u);
|
||||
state.storage_buffer_offsets[i] = EmitBinaryU32(
|
||||
EmitShaderDataDwordLoad(state, state.program.bindings.memory_offset_dword + i / 4u);
|
||||
const auto shift = ConstantU32(state, (i % 4u) * 8u);
|
||||
state.memory_byte_offsets[i] = EmitBinaryU32(
|
||||
state, OpBitwiseAnd, EmitBinaryU32(state, OpShiftRightLogical, word, shift),
|
||||
ConstantU32(state, 0x3fu));
|
||||
ConstantU32(state, 0xffu));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,9 @@ MemoryResourceAccess PrepareMemoryResourceAccess(EmitterState& state, const IR::
|
||||
state.builder.AddFunction({OpAccessChain, TypeStorageBufferPointer(state),
|
||||
access.object_pointer, state.storage_buffer_variable,
|
||||
ConstantU32(state, binding.array_index)});
|
||||
access.index_offset = state.storage_buffer_offsets[binding.array_index];
|
||||
access.index_offset = EmitBinaryU32(state, OpShiftRightLogical,
|
||||
state.memory_byte_offsets[binding.array_index],
|
||||
ConstantU32(state, 2u));
|
||||
access.add_index_offset = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -620,7 +620,7 @@ bool EmitValueProgram(EmitterState& state, const IR::ValueProgram& program, std:
|
||||
state.builder.AddFunction(
|
||||
{OpStore, state.pixel_valid_mask_variable, ConstantU32(state, 1)});
|
||||
}
|
||||
EmitStorageBufferOffsets(state);
|
||||
EmitMemoryOffsets(state);
|
||||
if (program.blocks.empty()) {
|
||||
EmitReturn(ctx);
|
||||
} else if (state.program.dispatcher_fallback) {
|
||||
|
||||
@@ -423,13 +423,13 @@ struct BindingLayout {
|
||||
uint32_t descriptor_set = 0;
|
||||
uint32_t push_constant_offset = 0;
|
||||
uint32_t push_constant_size = 0;
|
||||
uint32_t buffer_offset_dword = 0;
|
||||
uint32_t buffer_offset_count = 0;
|
||||
uint32_t memory_offset_dword = 0;
|
||||
uint32_t memory_offset_count = 0;
|
||||
std::vector<uint32_t> user_data_registers;
|
||||
std::vector<DescriptorBinding> descriptors;
|
||||
|
||||
[[nodiscard]] uint32_t ShaderDataDwords() const {
|
||||
return buffer_offset_dword + (buffer_offset_count + 3u) / 4u;
|
||||
return memory_offset_dword + (memory_offset_count + 3u) / 4u;
|
||||
}
|
||||
|
||||
bool operator==(const BindingLayout& other) const = default;
|
||||
|
||||
@@ -130,8 +130,9 @@ bool AllocateBindings(Program& program, const BindingLayoutOptions& options, std
|
||||
}
|
||||
return false;
|
||||
}
|
||||
next.buffer_offset_dword = static_cast<uint32_t>(next.user_data_registers.size());
|
||||
next.buffer_offset_count = static_cast<uint32_t>(program.info.buffers.size());
|
||||
next.memory_offset_dword = static_cast<uint32_t>(next.user_data_registers.size());
|
||||
next.memory_offset_count =
|
||||
static_cast<uint32_t>(program.info.buffers.size() + program.info.addresses.size());
|
||||
|
||||
if (!program.info.buffers.empty()) {
|
||||
std::vector<uint32_t> resources(program.info.buffers.size());
|
||||
|
||||
@@ -1059,8 +1059,8 @@ static void ShaderAppendNativeSpecialization(std::vector<uint32_t>&
|
||||
ids.push_back(program.bindings.descriptor_set);
|
||||
ids.push_back(program.bindings.push_constant_offset);
|
||||
ids.push_back(program.bindings.push_constant_size);
|
||||
ids.push_back(program.bindings.buffer_offset_dword);
|
||||
ids.push_back(program.bindings.buffer_offset_count);
|
||||
ids.push_back(program.bindings.memory_offset_dword);
|
||||
ids.push_back(program.bindings.memory_offset_count);
|
||||
ids.push_back(static_cast<uint32_t>(program.bindings.user_data_registers.size()));
|
||||
ids.insert(ids.end(), program.bindings.user_data_registers.begin(),
|
||||
program.bindings.user_data_registers.end());
|
||||
|
||||
@@ -939,6 +939,12 @@ void TestDynamicSrtReadRemainsExplicit() {
|
||||
FindBinding(fixture.program.bindings,
|
||||
DescriptorBindingKind::AddressMemory) != nullptr,
|
||||
"dynamic scalar read received the wrong resource bindings");
|
||||
Check(fixture.program.bindings.memory_offset_dword ==
|
||||
fixture.program.bindings.user_data_registers.size() &&
|
||||
fixture.program.bindings.memory_offset_count == 2u &&
|
||||
fixture.program.bindings.ShaderDataDwords() ==
|
||||
fixture.program.bindings.memory_offset_dword + 1u,
|
||||
"unified memory-offset layout is inconsistent");
|
||||
}
|
||||
|
||||
void TestPhiValidation() {
|
||||
|
||||
@@ -863,6 +863,7 @@ struct TestCase {
|
||||
bool compile_only = false;
|
||||
size_t storage_buffer_range_dwords = 0;
|
||||
std::vector<u32> storage_buffer_offsets;
|
||||
std::vector<u32> address_memory_offsets;
|
||||
bool force_shader_data_storage = false;
|
||||
bool expected_force_point_sampler = false;
|
||||
std::optional<uint64_t> flat_memory_base;
|
||||
@@ -1177,15 +1178,28 @@ CompiledShader CompileCase(const TestCase &test) {
|
||||
result.resources.user_data[reg - result.program.user_data_base]);
|
||||
}
|
||||
packed_user_data.resize(result.program.bindings.ShaderDataDwords());
|
||||
for (u32 i = 0; i < result.program.bindings.buffer_offset_count; i++) {
|
||||
const auto offset = i < test.storage_buffer_offsets.size()
|
||||
? test.storage_buffer_offsets[i]
|
||||
: 0u;
|
||||
const auto buffer_count = static_cast<u32>(result.program.info.buffers.size());
|
||||
for (u32 i = 0; i < buffer_count; i++) {
|
||||
u32 offset = 0;
|
||||
if (i < test.storage_buffer_offsets.size()) {
|
||||
offset = test.storage_buffer_offsets[i];
|
||||
}
|
||||
Require(test.name, "shader data", offset % sizeof(u32) == 0 && offset < 256,
|
||||
"storage buffer offset is not representable");
|
||||
packed_user_data[result.program.bindings.buffer_offset_dword + i / 4u] |=
|
||||
packed_user_data[result.program.bindings.memory_offset_dword + i / 4u] |=
|
||||
offset << ((i % 4u) * 8u);
|
||||
}
|
||||
for (u32 i = 0; i < result.program.info.addresses.size(); i++) {
|
||||
u32 offset = 0;
|
||||
if (i < test.address_memory_offsets.size()) {
|
||||
offset = test.address_memory_offsets[i];
|
||||
}
|
||||
Require(test.name, "shader data", offset < 256,
|
||||
"address-memory offset is not representable");
|
||||
const auto index = buffer_count + i;
|
||||
packed_user_data[result.program.bindings.memory_offset_dword + index / 4u] |=
|
||||
offset << ((index % 4u) * 8u);
|
||||
}
|
||||
return {std::move(result.spirv), std::move(result.program),
|
||||
std::move(result.resources.flattened_srt),
|
||||
std::move(packed_user_data)};
|
||||
@@ -16575,10 +16589,18 @@ TestCase FlatLoadVariants() {
|
||||
}
|
||||
AppendEnd(&code);
|
||||
|
||||
const std::vector<u32> guest_memory{0x80ff7f01u, 0x00008001u, 0x11223344u,
|
||||
0x55667788u, 0x99aabbccu, 0xddeeff00u};
|
||||
constexpr size_t byte_offset = 8;
|
||||
std::vector<u32> host_memory(
|
||||
(byte_offset + guest_memory.size() * sizeof(u32) + sizeof(u32) - 1u) /
|
||||
sizeof(u32));
|
||||
std::memcpy(reinterpret_cast<uint8_t *>(host_memory.data()) + byte_offset,
|
||||
guest_memory.data(), guest_memory.size() * sizeof(u32));
|
||||
|
||||
TestCase test{"FlatLoadVariants",
|
||||
code,
|
||||
{0x80ff7f01u, 0x00008001u, 0x11223344u, 0x55667788u,
|
||||
0x99aabbccu, 0xddeeff00u},
|
||||
std::move(host_memory),
|
||||
{0x01u, 0xffffffffu, 0x7f01u, 0xffff80ffu, 0x11223344u,
|
||||
0x55667788u, 0x11223344u, 0x55667788u, 0x99aabbccu,
|
||||
0x11223344u, 0x55667788u, 0x99aabbccu, 0xddeeff00u,
|
||||
@@ -16588,6 +16610,40 @@ TestCase FlatLoadVariants() {
|
||||
O::FLAT_LOAD_DWORDX2, O::FLAT_LOAD_DWORDX3,
|
||||
O::FLAT_LOAD_DWORDX4, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
test.flat_memory_base = 0;
|
||||
test.address_memory_offsets = {static_cast<u32>(byte_offset)};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase FlatSubdwordLoadsApplyByteOffset() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendVMovU32(&code, 20, 0);
|
||||
AppendVMovU32(&code, 21, 0);
|
||||
code.push_back(EncodeFlat0(0x08, 0, 0));
|
||||
code.push_back(EncodeFlat1(0, 0x7d, 0, 20));
|
||||
code.push_back(EncodeFlat0(0x0a, 0, 1));
|
||||
code.push_back(EncodeFlat1(1, 0x7d, 0, 20));
|
||||
AppendStoreVgpr(&code, 0, 0);
|
||||
AppendStoreVgpr(&code, 1, 1);
|
||||
AppendEnd(&code);
|
||||
|
||||
constexpr size_t byte_offset = 3;
|
||||
constexpr u32 guest_word = 0x80ff7f01u;
|
||||
std::vector<u32> host_memory(
|
||||
(byte_offset + sizeof(guest_word) + sizeof(u32) - 1u) / sizeof(u32));
|
||||
std::memcpy(reinterpret_cast<uint8_t *>(host_memory.data()) + byte_offset,
|
||||
&guest_word, sizeof(guest_word));
|
||||
|
||||
TestCase test;
|
||||
test.name = "FlatSubdwordLoadsApplyByteOffset";
|
||||
test.code = std::move(code);
|
||||
test.initial = std::move(host_memory);
|
||||
test.expected = {0x01u, 0x0000ff7fu};
|
||||
test.flat_memory_base = 0;
|
||||
test.address_memory_offsets = {static_cast<u32>(byte_offset)};
|
||||
test.opcodes = {O::V_MOV_B32, O::FLAT_LOAD_UBYTE, O::FLAT_LOAD_USHORT,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
return test;
|
||||
}
|
||||
|
||||
@@ -16667,9 +16723,10 @@ TestCase FlatVirtualAddressRebasesGuestAllocation() {
|
||||
TestCase test;
|
||||
test.name = "FlatVirtualAddressRebasesGuestAllocation";
|
||||
test.code = std::move(code);
|
||||
test.initial = {0, 0x12345678u};
|
||||
test.initial = {0xfeedfaceu, 0xcafebabeu, 0, 0x12345678u};
|
||||
test.expected = {0x12345678u, 0x12345678u, 0};
|
||||
test.flat_memory_base = GuestBase;
|
||||
test.address_memory_offsets = {8, 8, 8};
|
||||
test.opcodes = {O::V_MOV_B32, O::FLAT_LOAD_DWORD, O::BUFFER_STORE_DWORD,
|
||||
O::S_ENDPGM};
|
||||
return test;
|
||||
@@ -16688,12 +16745,16 @@ TestCase GlobalSignedImmediateRebasesBeforeSaddr() {
|
||||
AppendStoreVgpr(&code, 0, 0);
|
||||
AppendEnd(&code);
|
||||
|
||||
return {"GlobalSignedImmediateRebasesBeforeSaddr",
|
||||
code,
|
||||
{0x11111111u, 0x22222222u, 0x12345678u},
|
||||
{0x12345678u},
|
||||
{O::S_MOV_B32, O::V_MOV_B32, O::FLAT_LOAD_DWORD,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
TestCase test;
|
||||
test.name = "GlobalSignedImmediateRebasesBeforeSaddr";
|
||||
test.code = std::move(code);
|
||||
test.initial = {0xfeedfaceu, 0xcafebabeu, 0x11111111u, 0x22222222u,
|
||||
0x12345678u};
|
||||
test.expected = {0x12345678u};
|
||||
test.address_memory_offsets = {8};
|
||||
test.opcodes = {O::S_MOV_B32, O::V_MOV_B32, O::FLAT_LOAD_DWORD,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase FlatSegmentIgnoresSaddrAndMasksOffsetMsb() {
|
||||
@@ -19373,6 +19434,7 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(TBufferLoadFormatXy88IntegerComponents);
|
||||
AddCase(TBufferStoreVariants);
|
||||
AddCase(FlatLoadVariants);
|
||||
AddCase(FlatSubdwordLoadsApplyByteOffset);
|
||||
AddCase(FlatVirtualAddressRebasesGuestAllocation);
|
||||
AddCase(GlobalSignedImmediateRebasesBeforeSaddr);
|
||||
AddCase(FlatSegmentIgnoresSaddrAndMasksOffsetMsb);
|
||||
|
||||
@@ -4231,7 +4231,7 @@ void TestNewShaderRecompilerScalarMemoryBindingDomains() {
|
||||
raw.program.bindings,
|
||||
ShaderRecompiler::IR::DescriptorBindingKind::FlattenedSrt) ==
|
||||
nullptr &&
|
||||
raw.program.bindings.buffer_offset_count == 0u,
|
||||
raw.program.bindings.memory_offset_count == 1u,
|
||||
"raw scalar load did not use only the address-memory domain");
|
||||
Check(count_live_memory_ops(
|
||||
raw.program, ShaderRecompiler::IR::ValueOpcode::LoadAddressU32,
|
||||
@@ -4284,7 +4284,7 @@ void TestNewShaderRecompilerScalarMemoryBindingDomains() {
|
||||
buffer.program.bindings,
|
||||
ShaderRecompiler::IR::DescriptorBindingKind::FlattenedSrt) ==
|
||||
nullptr &&
|
||||
buffer.program.bindings.buffer_offset_count == 1u,
|
||||
buffer.program.bindings.memory_offset_count == 1u,
|
||||
"descriptor scalar load did not use only the buffer domain");
|
||||
Check(count_live_memory_ops(
|
||||
buffer.program, ShaderRecompiler::IR::ValueOpcode::ReadConstBuffer,
|
||||
@@ -11442,8 +11442,8 @@ void TestNewShaderRecompilerSpirvSizeBaselines() {
|
||||
EncodeSopp(0x01),
|
||||
};
|
||||
const auto wide_result = compile("wide-buffer", wide_buffer,
|
||||
{.words = 797,
|
||||
.instructions = 209,
|
||||
{.words = 807,
|
||||
.instructions = 211,
|
||||
.runtime_arrays = 1,
|
||||
.variables = 2,
|
||||
.loads = 9,
|
||||
|
||||
Reference in New Issue
Block a user