Commit 5beaef93 by Ben Clayton

Pipeline: Store builtins on SpirvRoutine...

... even if they're not directly used by the SPIR-V shader code. This will let the debugger display these values in the locals window. Bug: b/145351270 Change-Id: I1d390e95bf38e89b072ef374e6a35cd8222a45c6 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38912Tested-by: 's avatarBen Clayton <bclayton@google.com> Presubmit-Ready: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 0b4bc585
...@@ -60,12 +60,19 @@ void ComputeProgram::generate() ...@@ -60,12 +60,19 @@ void ComputeProgram::generate()
void ComputeProgram::setWorkgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routine, Int workgroupID[3]) void ComputeProgram::setWorkgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routine, Int workgroupID[3])
{ {
// TODO(b/146486064): Consider only assigning these to the SpirvRoutine iff
// they are ever going to be read.
routine->numWorkgroups = *Pointer<Int4>(data + OFFSET(Data, numWorkgroups));
routine->workgroupID = Insert(Insert(Insert(Int4(0), workgroupID[X], X), workgroupID[Y], Y), workgroupID[Z], Z);
routine->workgroupSize = *Pointer<Int4>(data + OFFSET(Data, workgroupSize));
routine->subgroupsPerWorkgroup = *Pointer<Int>(data + OFFSET(Data, subgroupsPerWorkgroup));
routine->invocationsPerSubgroup = *Pointer<Int>(data + OFFSET(Data, invocationsPerSubgroup));
routine->setInputBuiltin(shader, spv::BuiltInNumWorkgroups, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine->setInputBuiltin(shader, spv::BuiltInNumWorkgroups, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
auto numWorkgroups = *Pointer<Int4>(data + OFFSET(Data, numWorkgroups));
for(uint32_t component = 0; component < builtin.SizeInComponents; component++) for(uint32_t component = 0; component < builtin.SizeInComponents; component++)
{ {
value[builtin.FirstComponent + component] = value[builtin.FirstComponent + component] =
As<SIMD::Float>(SIMD::Int(Extract(numWorkgroups, component))); As<SIMD::Float>(SIMD::Int(Extract(routine->numWorkgroups, component)));
} }
}); });
...@@ -78,24 +85,21 @@ void ComputeProgram::setWorkgroupBuiltins(Pointer<Byte> data, SpirvRoutine *rout ...@@ -78,24 +85,21 @@ void ComputeProgram::setWorkgroupBuiltins(Pointer<Byte> data, SpirvRoutine *rout
}); });
routine->setInputBuiltin(shader, spv::BuiltInWorkgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine->setInputBuiltin(shader, spv::BuiltInWorkgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
auto workgroupSize = *Pointer<Int4>(data + OFFSET(Data, workgroupSize));
for(uint32_t component = 0; component < builtin.SizeInComponents; component++) for(uint32_t component = 0; component < builtin.SizeInComponents; component++)
{ {
value[builtin.FirstComponent + component] = value[builtin.FirstComponent + component] =
As<SIMD::Float>(SIMD::Int(Extract(workgroupSize, component))); As<SIMD::Float>(SIMD::Int(Extract(routine->workgroupSize, component)));
} }
}); });
routine->setInputBuiltin(shader, spv::BuiltInNumSubgroups, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine->setInputBuiltin(shader, spv::BuiltInNumSubgroups, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 1); ASSERT(builtin.SizeInComponents == 1);
auto subgroupsPerWorkgroup = *Pointer<Int>(data + OFFSET(Data, subgroupsPerWorkgroup)); value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine->subgroupsPerWorkgroup));
value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(subgroupsPerWorkgroup));
}); });
routine->setInputBuiltin(shader, spv::BuiltInSubgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine->setInputBuiltin(shader, spv::BuiltInSubgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 1); ASSERT(builtin.SizeInComponents == 1);
auto invocationsPerSubgroup = *Pointer<Int>(data + OFFSET(Data, invocationsPerSubgroup)); value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine->invocationsPerSubgroup));
value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(invocationsPerSubgroup));
}); });
routine->setImmutableInputBuiltins(shader); routine->setImmutableInputBuiltins(shader);
...@@ -120,6 +124,22 @@ void ComputeProgram::setSubgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routi ...@@ -120,6 +124,22 @@ void ComputeProgram::setSubgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routi
localInvocationID[X] = idx; localInvocationID[X] = idx;
} }
Int4 wgID = Insert(Insert(Insert(SIMD::Int(0), workgroupID[X], X), workgroupID[Y], Y), workgroupID[Z], Z);
auto localBase = workgroupSize * wgID;
SIMD::Int globalInvocationID[3];
globalInvocationID[X] = SIMD::Int(Extract(localBase, X)) + localInvocationID[X];
globalInvocationID[Y] = SIMD::Int(Extract(localBase, Y)) + localInvocationID[Y];
globalInvocationID[Z] = SIMD::Int(Extract(localBase, Z)) + localInvocationID[Z];
routine->localInvocationIndex = localInvocationIndex;
routine->subgroupIndex = subgroupIndex;
routine->localInvocationID[X] = localInvocationID[X];
routine->localInvocationID[Y] = localInvocationID[Y];
routine->localInvocationID[Z] = localInvocationID[Z];
routine->globalInvocationID[X] = globalInvocationID[X];
routine->globalInvocationID[Y] = globalInvocationID[Y];
routine->globalInvocationID[Z] = globalInvocationID[Z];
routine->setInputBuiltin(shader, spv::BuiltInLocalInvocationIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine->setInputBuiltin(shader, spv::BuiltInLocalInvocationIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 1); ASSERT(builtin.SizeInComponents == 1);
value[builtin.FirstComponent] = As<SIMD::Float>(localInvocationIndex); value[builtin.FirstComponent] = As<SIMD::Float>(localInvocationIndex);
...@@ -139,15 +159,10 @@ void ComputeProgram::setSubgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routi ...@@ -139,15 +159,10 @@ void ComputeProgram::setSubgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routi
}); });
routine->setInputBuiltin(shader, spv::BuiltInGlobalInvocationId, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine->setInputBuiltin(shader, spv::BuiltInGlobalInvocationId, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
SIMD::Int wgID = 0;
wgID = Insert(wgID, workgroupID[X], X);
wgID = Insert(wgID, workgroupID[Y], Y);
wgID = Insert(wgID, workgroupID[Z], Z);
auto localBase = workgroupSize * wgID;
for(uint32_t component = 0; component < builtin.SizeInComponents; component++) for(uint32_t component = 0; component < builtin.SizeInComponents; component++)
{ {
auto globalInvocationID = SIMD::Int(Extract(localBase, component)) + localInvocationID[component]; value[builtin.FirstComponent + component] =
value[builtin.FirstComponent + component] = As<SIMD::Float>(globalInvocationID); As<SIMD::Float>(globalInvocationID[component]);
} }
}); });
} }
......
...@@ -60,17 +60,33 @@ void PixelProgram::setBuiltins(Int &x, Int &y, Float4 (&z)[4], Float4 &w, Int cM ...@@ -60,17 +60,33 @@ void PixelProgram::setBuiltins(Int &x, Int &y, Float4 (&z)[4], Float4 &w, Int cM
{ {
routine.setImmutableInputBuiltins(spirvShader); routine.setImmutableInputBuiltins(spirvShader);
// TODO(b/146486064): Consider only assigning these to the SpirvRoutine iff
// they are ever going to be read.
routine.fragCoord[0] = SIMD::Float(Float(x)) + SIMD::Float(0.5f, 1.5f, 0.5f, 1.5f);
routine.fragCoord[1] = SIMD::Float(Float(y)) + SIMD::Float(0.5f, 0.5f, 1.5f, 1.5f);
routine.fragCoord[2] = z[0]; // sample 0
routine.fragCoord[3] = w;
routine.pointCoord[0] = SIMD::Float(0.5f) +
SIMD::Float(Float(x) - (*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordX))));
routine.pointCoord[1] = SIMD::Float(0.5f) +
SIMD::Float(Float(y) - (*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordY))));
routine.invocationsPerSubgroup = SIMD::Width;
routine.helperInvocation = ~maskAny(cMask);
routine.windowSpacePosition[0] = x + SIMD::Int(0, 1, 0, 1);
routine.windowSpacePosition[1] = y + SIMD::Int(0, 0, 1, 1);
routine.viewID = *Pointer<Int>(data + OFFSET(DrawData, viewID));
routine.setInputBuiltin(spirvShader, spv::BuiltInViewIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInViewIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
assert(builtin.SizeInComponents == 1); assert(builtin.SizeInComponents == 1);
value[builtin.FirstComponent] = As<Float4>(Int4((*Pointer<Int>(data + OFFSET(DrawData, viewID))))); value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.viewID));
}); });
routine.setInputBuiltin(spirvShader, spv::BuiltInFragCoord, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInFragCoord, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
assert(builtin.SizeInComponents == 4); assert(builtin.SizeInComponents == 4);
value[builtin.FirstComponent + 0] = SIMD::Float(Float(x)) + SIMD::Float(0.5f, 1.5f, 0.5f, 1.5f); value[builtin.FirstComponent + 0] = routine.fragCoord[0];
value[builtin.FirstComponent + 1] = SIMD::Float(Float(y)) + SIMD::Float(0.5f, 0.5f, 1.5f, 1.5f); value[builtin.FirstComponent + 1] = routine.fragCoord[1];
value[builtin.FirstComponent + 2] = z[0]; // sample 0 value[builtin.FirstComponent + 2] = routine.fragCoord[2];
value[builtin.FirstComponent + 3] = w; value[builtin.FirstComponent + 3] = routine.fragCoord[3];
}); });
routine.setInputBuiltin(spirvShader, spv::BuiltInPointCoord, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInPointCoord, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
...@@ -88,12 +104,8 @@ void PixelProgram::setBuiltins(Int &x, Int &y, Float4 (&z)[4], Float4 &w, Int cM ...@@ -88,12 +104,8 @@ void PixelProgram::setBuiltins(Int &x, Int &y, Float4 (&z)[4], Float4 &w, Int cM
routine.setInputBuiltin(spirvShader, spv::BuiltInHelperInvocation, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInHelperInvocation, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
assert(builtin.SizeInComponents == 1); assert(builtin.SizeInComponents == 1);
value[builtin.FirstComponent] = As<SIMD::Float>(~maskAny(cMask)); value[builtin.FirstComponent] = As<SIMD::Float>(routine.helperInvocation);
}); });
routine.windowSpacePosition[0] = x + SIMD::Int(0, 1, 0, 1);
routine.windowSpacePosition[1] = y + SIMD::Int(0, 0, 1, 1);
routine.viewID = *Pointer<Int>(data + OFFSET(DrawData, viewID));
} }
void PixelProgram::applyShader(Int cMask[4], Int sMask[4], Int zMask[4]) void PixelProgram::applyShader(Int cMask[4], Int sMask[4], Int zMask[4])
......
...@@ -1163,8 +1163,28 @@ public: ...@@ -1163,8 +1163,28 @@ public:
Pointer<Byte> pushConstants; Pointer<Byte> pushConstants;
Pointer<Byte> constants; Pointer<Byte> constants;
Int killMask = Int{ 0 }; Int killMask = Int{ 0 };
// Shader invocation state.
// Not all of these variables are used for every type of shader, and some
// are only used when debugging. See b/146486064 for more information.
// Give careful consideration to the runtime performance loss before adding
// more state here.
SIMD::Int windowSpacePosition[2]; SIMD::Int windowSpacePosition[2];
Int viewID; // slice offset into input attachments for multiview, even if the shader doesn't use ViewIndex Int viewID; // slice offset into input attachments for multiview, even if the shader doesn't use ViewIndex
Int instanceID;
SIMD::Int vertexIndex;
std::array<SIMD::Float, 4> fragCoord;
std::array<SIMD::Float, 4> pointCoord;
SIMD::Int helperInvocation;
Int4 numWorkgroups;
Int4 workgroupID;
Int4 workgroupSize;
Int subgroupsPerWorkgroup;
Int invocationsPerSubgroup;
Int subgroupIndex;
SIMD::Int localInvocationIndex;
std::array<SIMD::Int, 3> localInvocationID;
std::array<SIMD::Int, 3> globalInvocationID;
void createVariable(SpirvShader::Object::ID id, uint32_t size) void createVariable(SpirvShader::Object::ID id, uint32_t size)
{ {
......
...@@ -34,15 +34,20 @@ VertexProgram::VertexProgram( ...@@ -34,15 +34,20 @@ VertexProgram::VertexProgram(
{ {
routine.setImmutableInputBuiltins(spirvShader); routine.setImmutableInputBuiltins(spirvShader);
// TODO(b/146486064): Consider only assigning these to the SpirvRoutine iff
// they are ever going to be read.
routine.viewID = *Pointer<Int>(data + OFFSET(DrawData, viewID));
routine.instanceID = *Pointer<Int>(data + OFFSET(DrawData, instanceID));
routine.setInputBuiltin(spirvShader, spv::BuiltInViewIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInViewIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
assert(builtin.SizeInComponents == 1); assert(builtin.SizeInComponents == 1);
value[builtin.FirstComponent] = As<Float4>(Int4((*Pointer<Int>(data + OFFSET(DrawData, viewID))))); value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.viewID));
}); });
routine.setInputBuiltin(spirvShader, spv::BuiltInInstanceIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInInstanceIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
// TODO: we could do better here; we know InstanceIndex is uniform across all lanes // TODO: we could do better here; we know InstanceIndex is uniform across all lanes
assert(builtin.SizeInComponents == 1); assert(builtin.SizeInComponents == 1);
value[builtin.FirstComponent] = As<Float4>(Int4((*Pointer<Int>(data + OFFSET(DrawData, instanceID))))); value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.instanceID));
}); });
routine.setInputBuiltin(spirvShader, spv::BuiltInSubgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) { routine.setInputBuiltin(spirvShader, spv::BuiltInSubgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
...@@ -62,14 +67,15 @@ VertexProgram::~VertexProgram() ...@@ -62,14 +67,15 @@ VertexProgram::~VertexProgram()
void VertexProgram::program(Pointer<UInt> &batch, UInt &vertexCount) void VertexProgram::program(Pointer<UInt> &batch, UInt &vertexCount)
{ {
routine.vertexIndex = *Pointer<SIMD::Int>(As<Pointer<SIMD::Int>>(batch)) +
SIMD::Int(*Pointer<Int>(data + OFFSET(DrawData, baseVertex)));
auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex); auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex);
if(it != spirvShader->inputBuiltins.end()) if(it != spirvShader->inputBuiltins.end())
{ {
assert(it->second.SizeInComponents == 1); assert(it->second.SizeInComponents == 1);
routine.getVariable(it->second.Id)[it->second.FirstComponent] = routine.getVariable(it->second.Id)[it->second.FirstComponent] =
As<Float4>(*Pointer<Int4>(As<Pointer<Int4>>(batch)) + As<SIMD::Float>(routine.vertexIndex);
Int4(*Pointer<Int>(data + OFFSET(DrawData, baseVertex))));
} }
auto activeLaneMask = SIMD::Int(0xFFFFFFFF); auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment