Skip to content

Commit

Permalink
Hoist resource variables using a global initializer function correctly
Browse files Browse the repository at this point in the history
Fixes: shader-slang#4874
Hoist resource variables using a global initializer function in such a way that the initializer function is passed into every entry-point opposed to emitting a local-variable asignment in global scope.
  • Loading branch information
ArielG-NV committed Aug 21, 2024
1 parent d286ff5 commit 38c84bb
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 10 deletions.
30 changes: 25 additions & 5 deletions source/slang/slang-ir-legalize-types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,20 @@ struct LegalCallBuilder
// result type of the function, so we know that
// the legalization funciton/call will use a `void`
// result type.
//
_emitCall(m_context->builder->getVoidType());

// If our call is in global scope (initializer) we should
// hoist the call into the start of every entry-point
if (!m_context->builder->getInsertLoc().getInst()->getParent()
|| m_context->builder->getInsertLoc().getInst()->getParent()->getOp() == kIROp_Module)
{
for (auto i : m_context->getEntryPoints())
{
m_context->builder->setInsertBefore(i->getFirstOrdinaryInst());
_emitCall(m_context->builder->getVoidType());
}
}
else
_emitCall(m_context->builder->getVoidType());
return resultVal;
}
break;
Expand All @@ -370,11 +382,19 @@ struct LegalCallBuilder
auto simpleType = resultType.getSimple();
auto builder = m_context->builder;

// Recall that a local variable in our IR represents a *pointer*
// Recall that a variable in our IR represents a *pointer*
// to storage of the appropriate type.
//
auto varPtr = builder->emitVar(simpleType);

IRInst* varPtr = nullptr;
if (m_call->parent->getOp() == kIROp_Module)
{
// If we were going to emit an IRVar in global scope, emit a GlobalVar instead
varPtr = builder->createGlobalVar(simpleType);
}
else
{
varPtr = builder->emitVar(simpleType);
}
// We need to pass that pointer as an argument to our new
// `call` instruction, so that it can receive the value
// written by the callee.
Expand Down
15 changes: 15 additions & 0 deletions source/slang/slang-legalize-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,21 @@ struct IRTypeLegalizationContext
TargetProgram* targetProgram;
IRBuilder builderStorage;

List<IRFunc*> entryPoints;
List<IRFunc*>& getEntryPoints()
{
if (entryPoints.getCount() == 0)
{
for (auto i : module->getGlobalInsts())
{
if (auto func = as<IRFunc>(i))
if (i->findDecoration<IREntryPointDecoration>())
entryPoints.add(func);
}
}
return entryPoints;
}

IRTypeLegalizationContext(
TargetProgram* target,
IRModule* inModule);
Expand Down
48 changes: 48 additions & 0 deletions tests/compute/type-legalize-global-with-init-function.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// type-legalize-global-with-init.slang
//
// Confirm that type legalization can handle a global constant
// with a resource type or a type that recursively contains
// resources.
//
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUF): -shaderobj
//
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<uint> outputBuffer;

//TEST_INPUT:ubuffer(data=[1 2 3 4 5 6 7 8], stride=4):name=inputBuffer
RWStructuredBuffer<uint> inputBuffer;

static const RWStructuredBuffer<uint> gBuffer = inputBuffer;

struct Stuff
{
__init(RWStructuredBuffer<uint> inA, RWStructuredBuffer<uint> inB)
{
a = inA;
b = inB;
}
RWStructuredBuffer<uint> a;
RWStructuredBuffer<uint> b;
}

static const Stuff gStuff = Stuff( inputBuffer, inputBuffer );

uint test(uint x)
{
return gBuffer[x]
+ gStuff.a[x + 1] * 16
+ gStuff.b[x + 2] * 256;
}

[numthreads(4, 1, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{
let tid = dispatchThreadID.x;
let inVal = tid;
let outVal = test(inVal);
outputBuffer[tid] = outVal;
}
//BUF: 321
//BUF: 432
//BUF: 543
//BUF: 654
7 changes: 6 additions & 1 deletion tests/compute/type-legalize-global-with-init.slang
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// with a resource type or a type that recursively contains
// resources.
//
//TEST(compute):COMPARE_COMPUTE: -shaderobj
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUF): -shaderobj
//
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<uint> outputBuffer;
Expand Down Expand Up @@ -37,3 +37,8 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
let outVal = test(inVal);
outputBuffer[tid] = outVal;
}
//BUF: 321
//BUF: 432
//BUF: 543
//BUF: 654

This file was deleted.

0 comments on commit 38c84bb

Please sign in to comment.