graphics: size compute LDS from shader state

This commit is contained in:
nmzik
2026-08-16 13:48:10 +02:00
parent 1375d650a7
commit 4e343408dc
8 changed files with 172 additions and 19 deletions
@@ -972,6 +972,10 @@ uint32_t EmitStorageBufferElementPointer(EmitterState& state, const IR::MemoryIn
uint32_t EmitLdsElementPointer(EmitterState& state, uint32_t index);
uint32_t LdsDwordCount(const EmitterState& state);
uint32_t EmitLdsElementInBounds(EmitterState& state, uint32_t index);
uint32_t EmitGdsElementInBounds(EmitterState& state, uint32_t index);
uint32_t EmitGdsElementPointer(EmitterState& state, uint32_t index);
@@ -495,11 +495,14 @@ uint32_t EmitLdsElementPointer(EmitterState& state, uint32_t index) {
return pointer;
}
uint32_t LdsDwordCount(const EmitterState& state) {
return state.needs_function_lds ? 8192u : state.compute_input_info->lds_size_dwords;
}
uint32_t EmitLdsElementInBounds(EmitterState& state, uint32_t index) {
const auto in_bounds = state.builder.AllocateId();
const auto dwords = state.needs_function_lds ? 8192u : 1024u;
state.builder.AddFunction(
{OpULessThan, state.bool_type, in_bounds, index, ConstantU32(state, dwords)});
{OpULessThan, state.bool_type, in_bounds, index, ConstantU32(state, LdsDwordCount(state))});
return in_bounds;
}
@@ -1,5 +1,7 @@
#include "graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h"
#include <algorithm>
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
const IR::DescriptorBinding* DescriptorBinding(const EmitterState& state,
@@ -736,7 +738,8 @@ void EmitHeaderAndTypes(EmitterState& state) {
if (state.stage == ShaderType::Compute || state.needs_function_lds) {
const auto storage_class =
state.needs_function_lds ? StorageClassFunction : StorageClassWorkgroup;
const auto lds_size = ConstantU32(state, state.needs_function_lds ? 8192u : 1024u);
const auto lds_dwords = std::max(LdsDwordCount(state), 1u);
const auto lds_size = ConstantU32(state, lds_dwords);
state.builder.AddType({OpTypeArray, state.lds_array_type, state.uint_type, lds_size});
state.builder.AddType(
{OpTypePointer, state.ptr_workgroup_array, storage_class, state.lds_array_type});
@@ -158,7 +158,7 @@ uint32_t DwordIndex(ValueEmitContext& ctx, const IR::Inst& inst, const IR::Memor
uint32_t InBounds(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint32_t index, uint32_t pc) {
if (mem.kind == IR::ResourceKind::Lds) {
return 0;
return EmitLdsElementInBounds(ctx.state, index);
}
if (mem.kind == IR::ResourceKind::Gds) {
return EmitGdsElementInBounds(ctx.state, index);
@@ -546,7 +546,8 @@ uint32_t AppendConsume(ValueEmitContext& ctx, const IR::Inst& inst, bool gds, bo
ConstantU32(state, ScopeSubgroup), ballot});
const auto is_first =
Binary(state, OpIEqual, state.bool_type, EmitSubgroupLocalInvocationId(state), first);
const auto storage_bounds = gds ? EmitGdsElementInBounds(state, index) : 0u;
const auto storage_bounds =
gds ? EmitGdsElementInBounds(state, index) : EmitLdsElementInBounds(state, index);
const auto m0_bounds =
gds ? Binary(state, OpINotEqual, state.bool_type, size, ConstantU32(state, 0))
: Binary(state, OpULessThan, state.bool_type,