mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Add helpers for building SPIR-V ops incrementally
This commit is contained in:
@@ -179,6 +179,7 @@ public:
|
||||
return (uint32_t(op) & rdcspv::OpCodeMask) | (uint16_t(WordCount) << rdcspv::WordCountShift);
|
||||
}
|
||||
|
||||
ConstIter AsIter() const { return iter; }
|
||||
private:
|
||||
// everything is based around this iterator, which may point into our local storage or to external
|
||||
// storage.
|
||||
|
||||
@@ -54,6 +54,12 @@ Scalar::Scalar(Iter it)
|
||||
}
|
||||
}
|
||||
|
||||
Id OperationList::add(const rdcspv::Operation &op)
|
||||
{
|
||||
push_back(op);
|
||||
return OpDecoder(op.AsIter()).result;
|
||||
}
|
||||
|
||||
Editor::Editor(rdcarray<uint32_t> &spirvWords) : m_ExternalSPIRV(spirvWords)
|
||||
{
|
||||
}
|
||||
@@ -307,12 +313,12 @@ Id Editor::AddConstant(const Operation &op)
|
||||
return id;
|
||||
}
|
||||
|
||||
void Editor::AddFunction(const Operation *ops, size_t count)
|
||||
void Editor::AddFunction(const OperationList &ops)
|
||||
{
|
||||
size_t offset = m_SPIRV.size();
|
||||
|
||||
for(size_t i = 0; i < count; i++)
|
||||
ops[i].appendTo(m_SPIRV);
|
||||
for(const Operation &op : ops)
|
||||
op.appendTo(m_SPIRV);
|
||||
|
||||
RegisterOp(Iter(m_SPIRV, offset));
|
||||
}
|
||||
@@ -351,16 +357,18 @@ Id Editor::DeclareStructType(const rdcarray<Id> &members)
|
||||
return typeId;
|
||||
}
|
||||
|
||||
void Editor::AddOperation(Iter iter, const Operation &op)
|
||||
Id Editor::AddOperation(Iter iter, const Operation &op)
|
||||
{
|
||||
if(!iter)
|
||||
return;
|
||||
return Id();
|
||||
|
||||
// add op
|
||||
op.insertInto(m_SPIRV, iter.offs());
|
||||
|
||||
// update offsets
|
||||
addWords(iter.offs(), op.size());
|
||||
|
||||
return OpDecoder(iter).result;
|
||||
}
|
||||
|
||||
void Editor::RegisterOp(Iter it)
|
||||
|
||||
@@ -34,6 +34,12 @@ namespace rdcspv
|
||||
{
|
||||
class Editor;
|
||||
|
||||
struct OperationList : public rdcarray<Operation>
|
||||
{
|
||||
// add an operation and return its result id
|
||||
Id add(const rdcspv::Operation &op);
|
||||
};
|
||||
|
||||
struct Binding
|
||||
{
|
||||
Binding() = default;
|
||||
@@ -68,7 +74,7 @@ public:
|
||||
|
||||
Id MakeId();
|
||||
|
||||
void AddOperation(Iter iter, const Operation &op);
|
||||
Id AddOperation(Iter iter, const Operation &op);
|
||||
|
||||
// callbacks to allow us to update our internal structures over changes
|
||||
|
||||
@@ -96,7 +102,7 @@ public:
|
||||
Id AddType(const Operation &op);
|
||||
Id AddVariable(const Operation &op);
|
||||
Id AddConstant(const Operation &op);
|
||||
void AddFunction(const Operation *ops, size_t count);
|
||||
void AddFunction(const OperationList &ops);
|
||||
|
||||
Iter GetID(Id id);
|
||||
// the entry point has 'two' opcodes, the entrypoint declaration and the function.
|
||||
|
||||
@@ -439,12 +439,9 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
{
|
||||
indexTypeData.signedness = false;
|
||||
|
||||
rdcspv::Id unsignedIndex = editor.MakeId();
|
||||
editor.AddOperation(
|
||||
it, rdcspv::OpBitcast(editor.DeclareType(indexTypeData), unsignedIndex, index));
|
||||
index = editor.AddOperation(
|
||||
it, rdcspv::OpBitcast(editor.DeclareType(indexTypeData), editor.MakeId(), index));
|
||||
it++;
|
||||
|
||||
index = unsignedIndex;
|
||||
}
|
||||
|
||||
// if it's not wide enough, uconvert expand it
|
||||
@@ -452,11 +449,9 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
{
|
||||
rdcspv::Id extendedtype =
|
||||
editor.DeclareType(rdcspv::Scalar(rdcspv::Op::TypeInt, targetIndexWidth, false));
|
||||
rdcspv::Id extendedindex = editor.MakeId();
|
||||
editor.AddOperation(it, rdcspv::OpUConvert(extendedtype, extendedindex, index));
|
||||
index =
|
||||
editor.AddOperation(it, rdcspv::OpUConvert(extendedtype, editor.MakeId(), index));
|
||||
it++;
|
||||
|
||||
index = extendedindex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,18 +462,14 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
|
||||
rdcspv::Id clampedtype =
|
||||
editor.DeclareType(rdcspv::Scalar(rdcspv::Op::TypeInt, targetIndexWidth, false));
|
||||
rdcspv::Id clampedindex = editor.MakeId();
|
||||
|
||||
editor.AddOperation(
|
||||
index = editor.AddOperation(
|
||||
it, rdcspv::Operation(
|
||||
rdcspv::Op::ExtInst,
|
||||
{
|
||||
clampedtype.value(), clampedindex.value(), glsl450.value(),
|
||||
clampedtype.value(), editor.MakeId().value(), glsl450.value(),
|
||||
(uint32_t)rdcspv::GLSLstd450::UMin, index.value(), maxSlotID.value(),
|
||||
}));
|
||||
it++;
|
||||
|
||||
index = clampedindex;
|
||||
}
|
||||
|
||||
rdcspv::Id bufptr;
|
||||
@@ -489,28 +480,26 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
|
||||
// get our output slot address by adding an offset to the base pointer
|
||||
// baseaddr = bufferAddressConst + bindingOffset
|
||||
rdcspv::Id baseaddr = editor.MakeId();
|
||||
editor.AddOperation(
|
||||
it, rdcspv::OpIAdd(uint64ID, baseaddr, bufferAddressConst, varIt->second));
|
||||
rdcspv::Id baseaddr = editor.AddOperation(
|
||||
it, rdcspv::OpIAdd(uint64ID, editor.MakeId(), bufferAddressConst, varIt->second));
|
||||
it++;
|
||||
|
||||
// shift the index since this is a byte offset
|
||||
// shiftedindex = index << uint32shift
|
||||
rdcspv::Id shiftedindex = editor.MakeId();
|
||||
editor.AddOperation(
|
||||
it, rdcspv::OpShiftLeftLogical(uint64ID, shiftedindex, index, uint32shift));
|
||||
rdcspv::Id shiftedindex = editor.AddOperation(
|
||||
it, rdcspv::OpShiftLeftLogical(uint64ID, editor.MakeId(), index, uint32shift));
|
||||
it++;
|
||||
|
||||
// add the index on top of that
|
||||
// offsetaddr = baseaddr + shiftedindex
|
||||
rdcspv::Id offsetaddr = editor.MakeId();
|
||||
editor.AddOperation(it, rdcspv::OpIAdd(uint64ID, offsetaddr, baseaddr, shiftedindex));
|
||||
rdcspv::Id offsetaddr = editor.AddOperation(
|
||||
it, rdcspv::OpIAdd(uint64ID, editor.MakeId(), baseaddr, shiftedindex));
|
||||
it++;
|
||||
|
||||
// make a pointer out of it
|
||||
// uint32_t *bufptr = (uint32_t *)offsetaddr
|
||||
bufptr = editor.MakeId();
|
||||
editor.AddOperation(it, rdcspv::OpConvertUToPtr(uint32ptrtype, bufptr, offsetaddr));
|
||||
bufptr = editor.AddOperation(
|
||||
it, rdcspv::OpConvertUToPtr(uint32ptrtype, editor.MakeId(), offsetaddr));
|
||||
it++;
|
||||
}
|
||||
else
|
||||
@@ -519,16 +508,16 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
|
||||
// add the index to this binding's base index
|
||||
// ssboindex = bindingOffset + index
|
||||
rdcspv::Id ssboindex = editor.MakeId();
|
||||
editor.AddOperation(it, rdcspv::OpIAdd(uint32ID, ssboindex, index, varIt->second));
|
||||
rdcspv::Id ssboindex = editor.AddOperation(
|
||||
it, rdcspv::OpIAdd(uint32ID, editor.MakeId(), index, varIt->second));
|
||||
it++;
|
||||
|
||||
// accesschain to get the pointer we'll atomic into.
|
||||
// accesschain is 0 to access rtarray (first member) then ssboindex for array index
|
||||
// uint32_t *bufptr = (uint32_t *)&buf.rtarray[ssboindex];
|
||||
bufptr = editor.MakeId();
|
||||
editor.AddOperation(it, rdcspv::OpAccessChain(uint32ptrtype, bufptr, ssboVar,
|
||||
{rtarrayOffset, ssboindex}));
|
||||
bufptr =
|
||||
editor.AddOperation(it, rdcspv::OpAccessChain(uint32ptrtype, editor.MakeId(),
|
||||
ssboVar, {rtarrayOffset, ssboindex}));
|
||||
it++;
|
||||
}
|
||||
|
||||
|
||||
@@ -567,8 +567,8 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
tbuffers[tb].imageSampledTypeID =
|
||||
editor.DeclareType(rdcspv::SampledImage(tbuffers[tb].imageTypeID));
|
||||
|
||||
rdcspv::Id arrayType = editor.MakeId();
|
||||
editor.AddType(rdcspv::OpTypeArray(arrayType, tbuffers[tb].imageSampledTypeID, arraySize));
|
||||
rdcspv::Id arrayType = editor.AddType(
|
||||
rdcspv::OpTypeArray(editor.MakeId(), tbuffers[tb].imageSampledTypeID, arraySize));
|
||||
|
||||
rdcspv::Id arrayPtrType =
|
||||
editor.DeclareType(rdcspv::Pointer(arrayType, rdcspv::StorageClass::UniformConstant));
|
||||
@@ -576,9 +576,8 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
tbuffers[tb].pointerTypeID = editor.DeclareType(
|
||||
rdcspv::Pointer(tbuffers[tb].imageSampledTypeID, rdcspv::StorageClass::UniformConstant));
|
||||
|
||||
tbuffers[tb].variableID = editor.MakeId();
|
||||
editor.AddVariable(rdcspv::OpVariable(arrayPtrType, tbuffers[tb].variableID,
|
||||
rdcspv::StorageClass::UniformConstant));
|
||||
tbuffers[tb].variableID = editor.AddVariable(
|
||||
rdcspv::OpVariable(arrayPtrType, editor.MakeId(), rdcspv::StorageClass::UniformConstant));
|
||||
|
||||
editor.SetName(tbuffers[tb].variableID, name);
|
||||
|
||||
@@ -604,9 +603,8 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
rdcspv::Id idxImagePtrType =
|
||||
editor.DeclareType(rdcspv::Pointer(idxSampledTypeID, rdcspv::StorageClass::UniformConstant));
|
||||
|
||||
idxImagePtr = editor.MakeId();
|
||||
editor.AddVariable(
|
||||
rdcspv::OpVariable(idxImagePtrType, idxImagePtr, rdcspv::StorageClass::UniformConstant));
|
||||
idxImagePtr = editor.AddVariable(rdcspv::OpVariable(idxImagePtrType, editor.MakeId(),
|
||||
rdcspv::StorageClass::UniformConstant));
|
||||
|
||||
editor.SetName(idxImagePtr, "ibuffer");
|
||||
|
||||
@@ -792,22 +790,22 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
|
||||
// add the wrapper function
|
||||
{
|
||||
rdcarray<rdcspv::Operation> ops;
|
||||
rdcspv::OperationList ops;
|
||||
|
||||
rdcspv::Id voidType = editor.DeclareType(rdcspv::scalar<void>());
|
||||
rdcspv::Id funcType = editor.DeclareType(rdcspv::FunctionType(voidType, {}));
|
||||
|
||||
ops.push_back(rdcspv::OpFunction(voidType, wrapperEntry, rdcspv::FunctionControl::None, funcType));
|
||||
ops.add(rdcspv::OpFunction(voidType, wrapperEntry, rdcspv::FunctionControl::None, funcType));
|
||||
|
||||
ops.push_back(rdcspv::OpLabel(editor.MakeId()));
|
||||
ops.add(rdcspv::OpLabel(editor.MakeId()));
|
||||
{
|
||||
// uint3 invocationVec = gl_GlobalInvocationID;
|
||||
rdcspv::Id invocationVector = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpLoad(uint32Vec3ID, invocationVector, invocationId));
|
||||
rdcspv::Id invocationVector =
|
||||
ops.add(rdcspv::OpLoad(uint32Vec3ID, editor.MakeId(), invocationId));
|
||||
|
||||
// uint invocation = invocationVec.x
|
||||
rdcspv::Id uintInvocationID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpCompositeExtract(uint32ID, uintInvocationID, invocationVector, {0U}));
|
||||
rdcspv::Id uintInvocationID =
|
||||
ops.add(rdcspv::OpCompositeExtract(uint32ID, editor.MakeId(), invocationVector, {0U}));
|
||||
|
||||
// arraySlotID = uintInvocationID;
|
||||
rdcspv::Id arraySlotID = uintInvocationID;
|
||||
@@ -815,39 +813,37 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
editor.SetName(uintInvocationID, "arraySlot");
|
||||
|
||||
// uint viewinst = uintInvocationID / numVerts
|
||||
rdcspv::Id viewinstID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpUDiv(uint32ID, viewinstID, uintInvocationID, numVertsConstID));
|
||||
rdcspv::Id viewinstID =
|
||||
ops.add(rdcspv::OpUDiv(uint32ID, editor.MakeId(), uintInvocationID, numVertsConstID));
|
||||
|
||||
editor.SetName(viewinstID, "viewInstance");
|
||||
|
||||
rdcspv::Id instID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpUMod(uint32ID, instID, viewinstID, numInstConstID));
|
||||
rdcspv::Id instID =
|
||||
ops.add(rdcspv::OpUMod(uint32ID, editor.MakeId(), viewinstID, numInstConstID));
|
||||
|
||||
editor.SetName(instID, "instanceID");
|
||||
|
||||
rdcspv::Id viewID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpUDiv(uint32ID, viewID, viewinstID, numInstConstID));
|
||||
rdcspv::Id viewID =
|
||||
ops.add(rdcspv::OpUDiv(uint32ID, editor.MakeId(), viewinstID, numInstConstID));
|
||||
|
||||
editor.SetName(viewID, "viewID");
|
||||
|
||||
// bool inBounds = viewID < numViews;
|
||||
rdcspv::Id inBounds = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpULessThan(editor.DeclareType(rdcspv::scalar<bool>()), inBounds,
|
||||
viewID, numViewsConstID));
|
||||
rdcspv::Id inBounds = ops.add(rdcspv::OpULessThan(editor.DeclareType(rdcspv::scalar<bool>()),
|
||||
editor.MakeId(), viewID, numViewsConstID));
|
||||
|
||||
// if(inBounds) goto continueLabel; else goto killLabel;
|
||||
rdcspv::Id killLabel = editor.MakeId();
|
||||
rdcspv::Id continueLabel = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpSelectionMerge(killLabel, rdcspv::SelectionControl::None));
|
||||
ops.push_back(rdcspv::OpBranchConditional(inBounds, continueLabel, killLabel));
|
||||
ops.add(rdcspv::OpSelectionMerge(killLabel, rdcspv::SelectionControl::None));
|
||||
ops.add(rdcspv::OpBranchConditional(inBounds, continueLabel, killLabel));
|
||||
|
||||
// continueLabel:
|
||||
ops.push_back(rdcspv::OpLabel(continueLabel));
|
||||
ops.add(rdcspv::OpLabel(continueLabel));
|
||||
|
||||
// uint vtx = uintInvocationID % numVerts
|
||||
rdcspv::Id vtxID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpUMod(uint32ID, vtxID, uintInvocationID, numVertsConstID));
|
||||
|
||||
rdcspv::Id vtxID =
|
||||
ops.add(rdcspv::OpUMod(uint32ID, editor.MakeId(), uintInvocationID, numVertsConstID));
|
||||
editor.SetName(vtxID, "vertexID");
|
||||
|
||||
rdcspv::Id vertexIndexID = vtxID;
|
||||
@@ -857,20 +853,17 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
if(draw->flags & DrawFlags::Indexed)
|
||||
{
|
||||
// sampledimage idximg = *idximgPtr;
|
||||
rdcspv::Id loaded = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpLoad(idxSampledTypeID, loaded, idxImagePtr));
|
||||
rdcspv::Id loaded = ops.add(rdcspv::OpLoad(idxSampledTypeID, editor.MakeId(), idxImagePtr));
|
||||
|
||||
// image rawimg = imageFromSampled(idximg);
|
||||
rdcspv::Id rawimg = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpImage(idxImageTypeID, rawimg, loaded));
|
||||
rdcspv::Id rawimg = ops.add(rdcspv::OpImage(idxImageTypeID, editor.MakeId(), loaded));
|
||||
|
||||
// uvec4 result = texelFetch(rawimg, vtxID);
|
||||
rdcspv::Id result = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpImageFetch(uint32Vec4ID, result, rawimg, vertexIndexID));
|
||||
rdcspv::Id result =
|
||||
ops.add(rdcspv::OpImageFetch(uint32Vec4ID, editor.MakeId(), rawimg, vertexIndexID));
|
||||
|
||||
// vertexIndex = result.x;
|
||||
vertexIndexID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpCompositeExtract(uint32ID, vertexIndexID, result, {0}));
|
||||
vertexIndexID = ops.add(rdcspv::OpCompositeExtract(uint32ID, editor.MakeId(), result, {0}));
|
||||
}
|
||||
|
||||
// we use the current value of vertexIndex and use instID, to lookup per-vertex and
|
||||
@@ -884,16 +877,16 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
{
|
||||
// for non-indexed draws, we manually apply the vertex offset, but here after we used the
|
||||
// 0-based one to calculate the array slot
|
||||
vertexIndexID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpIAdd(uint32ID, vertexIndexID, vtxID,
|
||||
editor.AddConstantImmediate<uint32_t>(draw->vertexOffset)));
|
||||
vertexIndexID =
|
||||
ops.add(rdcspv::OpIAdd(uint32ID, editor.MakeId(), vtxID,
|
||||
editor.AddConstantImmediate<uint32_t>(draw->vertexOffset)));
|
||||
}
|
||||
editor.SetName(vertexIndexID, "vertexIndex");
|
||||
|
||||
// instIndex = inst + instOffset
|
||||
rdcspv::Id instIndexID = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpIAdd(uint32ID, instIndexID, instID,
|
||||
editor.AddConstantImmediate<uint32_t>(draw->instanceOffset)));
|
||||
rdcspv::Id instIndexID =
|
||||
ops.add(rdcspv::OpIAdd(uint32ID, editor.MakeId(), instID,
|
||||
editor.AddConstantImmediate<uint32_t>(draw->instanceOffset)));
|
||||
editor.SetName(instIndexID, "instanceIndex");
|
||||
|
||||
rdcspv::Id idxs[64] = {};
|
||||
@@ -953,14 +946,14 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
{
|
||||
if(refl.inputSignature[i].compType == compType)
|
||||
{
|
||||
ops.push_back(rdcspv::OpStore(ins[i].variableID, valueID));
|
||||
ops.add(rdcspv::OpStore(ins[i].variableID, valueID));
|
||||
}
|
||||
else
|
||||
{
|
||||
rdcspv::Id castedValue = editor.MakeId();
|
||||
// assume we can just bitcast
|
||||
ops.push_back(rdcspv::OpBitcast(ins[i].basetypeID, castedValue, valueID));
|
||||
ops.push_back(rdcspv::OpStore(ins[i].variableID, castedValue));
|
||||
rdcspv::Id castedValue =
|
||||
ops.add(rdcspv::OpBitcast(ins[i].basetypeID, editor.MakeId(), valueID));
|
||||
ops.add(rdcspv::OpStore(ins[i].variableID, castedValue));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -981,18 +974,16 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
|
||||
uint32_t location = refl.inputSignature[i].regIndex;
|
||||
|
||||
rdcspv::Id ptrId = editor.MakeId();
|
||||
// sampledimage *imgPtr = xxx_tbuffers[i];
|
||||
ops.push_back(rdcspv::OpAccessChain(tb.pointerTypeID, ptrId, tb.variableID,
|
||||
{idxs[refl.inputSignature[i].regIndex]}));
|
||||
rdcspv::Id ptrId =
|
||||
ops.add(rdcspv::OpAccessChain(tb.pointerTypeID, editor.MakeId(), tb.variableID,
|
||||
{idxs[refl.inputSignature[i].regIndex]}));
|
||||
|
||||
// sampledimage img = *imgPtr;
|
||||
rdcspv::Id loaded = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpLoad(tb.imageSampledTypeID, loaded, ptrId));
|
||||
rdcspv::Id loaded = ops.add(rdcspv::OpLoad(tb.imageSampledTypeID, editor.MakeId(), ptrId));
|
||||
|
||||
// image rawimg = imageFromSampled(img);
|
||||
rdcspv::Id rawimg = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpImage(tb.imageTypeID, rawimg, loaded));
|
||||
rdcspv::Id rawimg = ops.add(rdcspv::OpImage(tb.imageTypeID, editor.MakeId(), loaded));
|
||||
|
||||
// vec4 result = texelFetch(rawimg, vtxID or instID);
|
||||
rdcspv::Id idx = vertexLookupID;
|
||||
@@ -1019,23 +1010,20 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
else
|
||||
{
|
||||
// otherwise we divide by the divisor
|
||||
idx = editor.MakeId();
|
||||
rdcspv::Id divisorId = editor.AddConstantImmediate<uint32_t>(divisor);
|
||||
ops.push_back(rdcspv::OpUDiv(uint32ID, idx, instanceLookupID, divisorId));
|
||||
idx = ops.add(rdcspv::OpUDiv(uint32ID, editor.MakeId(), instanceLookupID, divisorId));
|
||||
}
|
||||
}
|
||||
|
||||
if(refl.inputSignature[i].compType == CompType::Double)
|
||||
{
|
||||
// since doubles are packed into two uints, we need to multiply the index by two
|
||||
rdcspv::Id doubled = editor.MakeId();
|
||||
ops.push_back(
|
||||
rdcspv::OpIMul(uint32ID, doubled, idx, editor.AddConstantImmediate<uint32_t>(2)));
|
||||
idx = doubled;
|
||||
idx = ops.add(rdcspv::OpIMul(uint32ID, editor.MakeId(), idx,
|
||||
editor.AddConstantImmediate<uint32_t>(2)));
|
||||
}
|
||||
|
||||
rdcspv::Id result = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpImageFetch(ins[i].vec4ID, result, rawimg, idx));
|
||||
rdcspv::Id result =
|
||||
ops.add(rdcspv::OpImageFetch(ins[i].vec4ID, editor.MakeId(), rawimg, idx));
|
||||
|
||||
if(refl.inputSignature[i].compType == CompType::Double)
|
||||
{
|
||||
@@ -1043,12 +1031,11 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
// packing. We can fetch the data unconditionally since it's harmless to read out of the
|
||||
// bounds of the buffer
|
||||
|
||||
rdcspv::Id nextidx = editor.MakeId();
|
||||
ops.push_back(
|
||||
rdcspv::OpIAdd(uint32ID, nextidx, idx, editor.AddConstantImmediate<uint32_t>(1)));
|
||||
rdcspv::Id nextidx = ops.add(rdcspv::OpIAdd(uint32ID, editor.MakeId(), idx,
|
||||
editor.AddConstantImmediate<uint32_t>(1)));
|
||||
|
||||
rdcspv::Id result2 = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpImageFetch(ins[i].vec4ID, result2, rawimg, nextidx));
|
||||
rdcspv::Id result2 =
|
||||
ops.add(rdcspv::OpImageFetch(ins[i].vec4ID, editor.MakeId(), rawimg, nextidx));
|
||||
|
||||
rdcspv::Id glsl450 = editor.ImportExtInst("GLSL.std.450");
|
||||
|
||||
@@ -1058,22 +1045,20 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
for(uint32_t c = 0; c < refl.inputSignature[i].compCount; c++)
|
||||
{
|
||||
// first extract the uvec2 we want
|
||||
rdcspv::Id packed = editor.MakeId();
|
||||
|
||||
// uvec2 packed = result.[xy/zw] / result2.[xy/zw];
|
||||
ops.push_back(rdcspv::OpVectorShuffle(uvec2Type, packed, result, result2,
|
||||
{c * 2 + 0, c * 2 + 1}));
|
||||
rdcspv::Id packed = ops.add(rdcspv::OpVectorShuffle(
|
||||
uvec2Type, editor.MakeId(), result, result2, {c * 2 + 0, c * 2 + 1}));
|
||||
|
||||
char swizzle[] = "xyzw";
|
||||
|
||||
editor.SetName(packed, StringFormat::Fmt("packed_%c", swizzle[c]));
|
||||
|
||||
// double comp = PackDouble2x32(packed);
|
||||
comps[c] = editor.MakeId();
|
||||
ops.push_back(rdcspv::Operation(
|
||||
comps[c] = ops.add(rdcspv::Operation(
|
||||
rdcspv::Op::ExtInst,
|
||||
{
|
||||
editor.DeclareType(rdcspv::scalar<double>()).value(), comps[c].value(),
|
||||
editor.DeclareType(rdcspv::scalar<double>()).value(), editor.MakeId().value(),
|
||||
glsl450.value(), (uint32_t)rdcspv::GLSLstd450::PackDouble2x32, packed.value(),
|
||||
}));
|
||||
}
|
||||
@@ -1085,32 +1070,26 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
}
|
||||
else
|
||||
{
|
||||
result = editor.MakeId();
|
||||
|
||||
rdcarray<rdcspv::Id> ids;
|
||||
|
||||
for(uint32_t c = 0; c < refl.inputSignature[i].compCount; c++)
|
||||
ids.push_back(comps[c]);
|
||||
|
||||
// baseTypeN value = result.xyz;
|
||||
ops.push_back(rdcspv::OpCompositeConstruct(ins[i].basetypeID, result, ids));
|
||||
result = ops.add(rdcspv::OpCompositeConstruct(ins[i].basetypeID, editor.MakeId(), ids));
|
||||
}
|
||||
}
|
||||
else if(refl.inputSignature[i].compCount == 1)
|
||||
{
|
||||
// for one component, extract x
|
||||
|
||||
rdcspv::Id swizzleIn = result;
|
||||
result = editor.MakeId();
|
||||
|
||||
// baseType value = result.x;
|
||||
ops.push_back(rdcspv::OpCompositeExtract(ins[i].basetypeID, result, swizzleIn, {0}));
|
||||
result =
|
||||
ops.add(rdcspv::OpCompositeExtract(ins[i].basetypeID, editor.MakeId(), result, {0}));
|
||||
}
|
||||
else if(refl.inputSignature[i].compCount != 4)
|
||||
{
|
||||
// for less than 4 components, extract the sub-vector
|
||||
rdcspv::Id swizzleIn = result;
|
||||
result = editor.MakeId();
|
||||
|
||||
rdcarray<uint32_t> swizzle;
|
||||
|
||||
@@ -1118,8 +1097,8 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
swizzle.push_back(c);
|
||||
|
||||
// baseTypeN value = result.xyz;
|
||||
ops.push_back(
|
||||
rdcspv::OpVectorShuffle(ins[i].basetypeID, result, swizzleIn, swizzleIn, swizzle));
|
||||
result = ops.add(rdcspv::OpVectorShuffle(ins[i].basetypeID, editor.MakeId(), result,
|
||||
result, swizzle));
|
||||
}
|
||||
|
||||
// copy the 4 component result directly
|
||||
@@ -1128,12 +1107,11 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
if(patchData.inputs[i].accessChain.empty())
|
||||
{
|
||||
// *global = value
|
||||
ops.push_back(rdcspv::OpStore(ins[i].variableID, result));
|
||||
ops.add(rdcspv::OpStore(ins[i].variableID, result));
|
||||
}
|
||||
else
|
||||
{
|
||||
// for composite types we need to access chain first
|
||||
rdcspv::Id subElement = editor.MakeId();
|
||||
rdcarray<rdcspv::Id> chain;
|
||||
|
||||
for(uint32_t accessIdx : patchData.inputs[i].accessChain)
|
||||
@@ -1144,16 +1122,16 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
chain.push_back(idxs[accessIdx]);
|
||||
}
|
||||
|
||||
ops.push_back(rdcspv::OpAccessChain(ins[i].privatePtrID, subElement,
|
||||
patchData.inputs[i].ID, chain));
|
||||
rdcspv::Id subElement = ops.add(rdcspv::OpAccessChain(
|
||||
ins[i].privatePtrID, editor.MakeId(), patchData.inputs[i].ID, chain));
|
||||
|
||||
ops.push_back(rdcspv::OpStore(subElement, result));
|
||||
ops.add(rdcspv::OpStore(subElement, result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// real_main();
|
||||
ops.push_back(rdcspv::OpFunctionCall(voidType, editor.MakeId(), entryID));
|
||||
ops.add(rdcspv::OpFunctionCall(voidType, editor.MakeId(), entryID));
|
||||
|
||||
rdcspv::Id zero = editor.AddConstantImmediate<uint32_t>(0);
|
||||
|
||||
@@ -1164,15 +1142,12 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
// not a structure member or array child, can load directly
|
||||
if(patchData.outputs[o].accessChain.empty())
|
||||
{
|
||||
loaded = editor.MakeId();
|
||||
// type loaded = *globalvar;
|
||||
ops.push_back(rdcspv::OpLoad(outs[o].basetypeID, loaded, patchData.outputs[o].ID));
|
||||
loaded =
|
||||
ops.add(rdcspv::OpLoad(outs[o].basetypeID, editor.MakeId(), patchData.outputs[o].ID));
|
||||
}
|
||||
else
|
||||
{
|
||||
rdcspv::Id readPtr = editor.MakeId();
|
||||
loaded = editor.MakeId();
|
||||
|
||||
// structure member, need to access chain first
|
||||
rdcarray<rdcspv::Id> chain;
|
||||
|
||||
@@ -1185,33 +1160,33 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
}
|
||||
|
||||
// type *readPtr = globalvar.globalsub...;
|
||||
ops.push_back(
|
||||
rdcspv::OpAccessChain(outs[o].privatePtrID, readPtr, patchData.outputs[o].ID, chain));
|
||||
rdcspv::Id readPtr = ops.add(rdcspv::OpAccessChain(outs[o].privatePtrID, editor.MakeId(),
|
||||
patchData.outputs[o].ID, chain));
|
||||
// type loaded = *readPtr;
|
||||
ops.push_back(rdcspv::OpLoad(outs[o].basetypeID, loaded, readPtr));
|
||||
loaded = ops.add(rdcspv::OpLoad(outs[o].basetypeID, editor.MakeId(), readPtr));
|
||||
}
|
||||
|
||||
// access chain the destination
|
||||
// type *writePtr = outBuffer.verts[arraySlot].outputN
|
||||
rdcspv::Id writePtr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(outs[o].ssboPtrID, writePtr, outBufferVarID,
|
||||
{zero, arraySlotID, outs[o].constID}));
|
||||
rdcspv::Id writePtr =
|
||||
ops.add(rdcspv::OpAccessChain(outs[o].ssboPtrID, editor.MakeId(), outBufferVarID,
|
||||
{zero, arraySlotID, outs[o].constID}));
|
||||
|
||||
// *writePtr = loaded;
|
||||
ops.push_back(rdcspv::OpStore(writePtr, loaded));
|
||||
ops.add(rdcspv::OpStore(writePtr, loaded));
|
||||
}
|
||||
|
||||
// goto killLabel;
|
||||
ops.push_back(rdcspv::OpBranch(killLabel));
|
||||
ops.add(rdcspv::OpBranch(killLabel));
|
||||
|
||||
// killLabel:
|
||||
ops.push_back(rdcspv::OpLabel(killLabel));
|
||||
ops.add(rdcspv::OpLabel(killLabel));
|
||||
}
|
||||
ops.push_back(rdcspv::OpReturn());
|
||||
ops.add(rdcspv::OpReturn());
|
||||
|
||||
ops.push_back(rdcspv::OpFunctionEnd());
|
||||
ops.add(rdcspv::OpFunctionEnd());
|
||||
|
||||
editor.AddFunction(ops.data(), ops.size());
|
||||
editor.AddFunction(ops);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -569,31 +569,30 @@ static void CreatePSInputFetcher(rdcarray<uint32_t> &fragspv, uint32_t &structSt
|
||||
rdcspv::Id glsl450 = editor.ImportExtInst("GLSL.std.450");
|
||||
|
||||
{
|
||||
rdcarray<rdcspv::Operation> ops;
|
||||
rdcspv::OperationList ops;
|
||||
|
||||
rdcspv::Id voidType = editor.DeclareType(rdcspv::scalar<void>());
|
||||
|
||||
ops.push_back(rdcspv::OpFunction(voidType, entryID, rdcspv::FunctionControl::None,
|
||||
editor.DeclareType(rdcspv::FunctionType(voidType, {}))));
|
||||
ops.add(rdcspv::OpFunction(voidType, entryID, rdcspv::FunctionControl::None,
|
||||
editor.DeclareType(rdcspv::FunctionType(voidType, {}))));
|
||||
|
||||
ops.push_back(rdcspv::OpLabel(editor.MakeId()));
|
||||
ops.add(rdcspv::OpLabel(editor.MakeId()));
|
||||
{
|
||||
rdcspv::Id structPtr = ssboVar;
|
||||
|
||||
if(structPtr == rdcspv::Id())
|
||||
{
|
||||
// if we don't have the struct as a bind, we need to cast it from the pointer
|
||||
structPtr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpConvertUToPtr(bufptrtype, structPtr, addressConstant));
|
||||
structPtr = ops.add(rdcspv::OpConvertUToPtr(bufptrtype, editor.MakeId(), addressConstant));
|
||||
|
||||
editor.SetName(structPtr, "HitBuffer");
|
||||
}
|
||||
|
||||
rdcspv::Id uintPtr = editor.DeclareType(rdcspv::Pointer(uint32Type, bufferClass));
|
||||
rdcspv::Id hit_count = editor.MakeId();
|
||||
|
||||
// get a pointer to buffer.hit_count
|
||||
ops.push_back(rdcspv::OpAccessChain(uintPtr, hit_count, structPtr, {uintConsts[0]}));
|
||||
rdcspv::Id hit_count =
|
||||
ops.add(rdcspv::OpAccessChain(uintPtr, editor.MakeId(), structPtr, {uintConsts[0]}));
|
||||
|
||||
rdcspv::Id scope = editor.AddConstantImmediate<uint32_t>((uint32_t)rdcspv::Scope::Device);
|
||||
rdcspv::Id semantics =
|
||||
@@ -603,32 +602,30 @@ static void CreatePSInputFetcher(rdcarray<uint32_t> &fragspv, uint32_t &structSt
|
||||
rdcspv::Id fragCoordLoaded = editor.MakeId();
|
||||
if(fragCoord.member == ~0U)
|
||||
{
|
||||
ops.push_back(rdcspv::OpLoad(float4Type, fragCoordLoaded, fragCoord.base));
|
||||
ops.add(rdcspv::OpLoad(float4Type, fragCoordLoaded, fragCoord.base));
|
||||
}
|
||||
else
|
||||
{
|
||||
rdcspv::Id posptr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(float4InPtr, posptr, fragCoord.base,
|
||||
{editor.AddConstantImmediate(fragCoord.member)}));
|
||||
ops.push_back(rdcspv::OpLoad(float4Type, fragCoordLoaded, posptr));
|
||||
rdcspv::Id posptr =
|
||||
ops.add(rdcspv::OpAccessChain(float4InPtr, editor.MakeId(), fragCoord.base,
|
||||
{editor.AddConstantImmediate(fragCoord.member)}));
|
||||
ops.add(rdcspv::OpLoad(float4Type, fragCoordLoaded, posptr));
|
||||
}
|
||||
|
||||
rdcspv::Id bool2Type = editor.DeclareType(rdcspv::Vector(rdcspv::scalar<bool>(), 2));
|
||||
|
||||
// grab x and y
|
||||
rdcspv::Id fragXY = editor.MakeId();
|
||||
ops.push_back(
|
||||
rdcspv::OpVectorShuffle(float2Type, fragXY, fragCoordLoaded, fragCoordLoaded, {0, 1}));
|
||||
rdcspv::Id fragXY = ops.add(rdcspv::OpVectorShuffle(
|
||||
float2Type, editor.MakeId(), fragCoordLoaded, fragCoordLoaded, {0, 1}));
|
||||
|
||||
// subtract from the destination co-ord
|
||||
rdcspv::Id fragXYRelative = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpFSub(float2Type, fragXYRelative, fragXY, destXY));
|
||||
rdcspv::Id fragXYRelative =
|
||||
ops.add(rdcspv::OpFSub(float2Type, editor.MakeId(), fragXY, destXY));
|
||||
|
||||
// abs()
|
||||
rdcspv::Id fragXYAbs = editor.MakeId();
|
||||
ops.push_back(rdcspv::Operation(
|
||||
rdcspv::Id fragXYAbs = ops.add(rdcspv::Operation(
|
||||
rdcspv::Op::ExtInst, {
|
||||
float2Type.value(), fragXYAbs.value(), glsl450.value(),
|
||||
float2Type.value(), editor.MakeId().value(), glsl450.value(),
|
||||
(uint32_t)rdcspv::GLSLstd450::FAbs, fragXYRelative.value(),
|
||||
}));
|
||||
|
||||
@@ -637,66 +634,62 @@ static void CreatePSInputFetcher(rdcarray<uint32_t> &fragspv, uint32_t &structSt
|
||||
editor.AddConstant(rdcspv::OpConstantComposite(float2Type, editor.MakeId(), {half, half}));
|
||||
|
||||
// less than 0.5
|
||||
rdcspv::Id inPixelXY = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpFOrdLessThan(bool2Type, inPixelXY, fragXYAbs, threshold));
|
||||
rdcspv::Id inPixelXY =
|
||||
ops.add(rdcspv::OpFOrdLessThan(bool2Type, editor.MakeId(), fragXYAbs, threshold));
|
||||
|
||||
// both less than 0.5
|
||||
rdcspv::Id inPixel = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAll(boolType, inPixel, inPixelXY));
|
||||
rdcspv::Id inPixel = ops.add(rdcspv::OpAll(boolType, editor.MakeId(), inPixelXY));
|
||||
|
||||
// bool inPixel = all(abs(gl_FragCoord.xy - dest.xy) < 0.5f);
|
||||
|
||||
rdcspv::Id killLabel = editor.MakeId();
|
||||
rdcspv::Id continueLabel = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpSelectionMerge(killLabel, rdcspv::SelectionControl::None));
|
||||
ops.push_back(rdcspv::OpBranchConditional(inPixel, continueLabel, killLabel));
|
||||
ops.push_back(rdcspv::OpLabel(continueLabel));
|
||||
ops.add(rdcspv::OpSelectionMerge(killLabel, rdcspv::SelectionControl::None));
|
||||
ops.add(rdcspv::OpBranchConditional(inPixel, continueLabel, killLabel));
|
||||
ops.add(rdcspv::OpLabel(continueLabel));
|
||||
|
||||
// allocate a slot with atomic add
|
||||
rdcspv::Id slot = editor.MakeId();
|
||||
ops.push_back(
|
||||
rdcspv::OpAtomicIAdd(uint32Type, slot, hit_count, scope, semantics, uintConsts[1]));
|
||||
rdcspv::Id slot = ops.add(rdcspv::OpAtomicIAdd(uint32Type, editor.MakeId(), hit_count, scope,
|
||||
semantics, uintConsts[1]));
|
||||
|
||||
editor.SetName(slot, "slot");
|
||||
|
||||
rdcspv::Id inRange = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpULessThan(boolType, inRange, slot, arrayLength));
|
||||
rdcspv::Id inRange = ops.add(rdcspv::OpULessThan(boolType, editor.MakeId(), slot, arrayLength));
|
||||
|
||||
rdcspv::Id killLabel2 = editor.MakeId();
|
||||
continueLabel = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpSelectionMerge(killLabel2, rdcspv::SelectionControl::None));
|
||||
ops.push_back(rdcspv::OpBranchConditional(inRange, continueLabel, killLabel2));
|
||||
ops.push_back(rdcspv::OpLabel(continueLabel));
|
||||
ops.add(rdcspv::OpSelectionMerge(killLabel2, rdcspv::SelectionControl::None));
|
||||
ops.add(rdcspv::OpBranchConditional(inRange, continueLabel, killLabel2));
|
||||
ops.add(rdcspv::OpLabel(continueLabel));
|
||||
|
||||
rdcspv::Id hitptr = editor.DeclareType(rdcspv::Pointer(PSHit, bufferClass));
|
||||
|
||||
// get a pointer to the hit for our slot
|
||||
rdcspv::Id hit = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(hitptr, hit, structPtr, {uintConsts[1], slot}));
|
||||
rdcspv::Id hit =
|
||||
ops.add(rdcspv::OpAccessChain(hitptr, editor.MakeId(), structPtr, {uintConsts[1], slot}));
|
||||
|
||||
// store fixed properties
|
||||
|
||||
rdcspv::MemoryAccessAndParamDatas alignedAccess;
|
||||
alignedAccess.setAligned(sizeof(uint32_t));
|
||||
|
||||
rdcspv::Id storePtr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(float4BufPtr, storePtr, hit, {uintConsts[0]}));
|
||||
ops.push_back(rdcspv::OpStore(storePtr, fragCoordLoaded, alignedAccess));
|
||||
rdcspv::Id storePtr =
|
||||
ops.add(rdcspv::OpAccessChain(float4BufPtr, editor.MakeId(), hit, {uintConsts[0]}));
|
||||
ops.add(rdcspv::OpStore(storePtr, fragCoordLoaded, alignedAccess));
|
||||
|
||||
rdcspv::Id loaded = editor.MakeId();
|
||||
rdcspv::Id loaded;
|
||||
if(primitiveID.base != rdcspv::Id())
|
||||
{
|
||||
loaded = editor.MakeId();
|
||||
if(primitiveID.member == ~0U)
|
||||
{
|
||||
ops.push_back(rdcspv::OpLoad(uint32Type, loaded, primitiveID.base));
|
||||
loaded = ops.add(rdcspv::OpLoad(uint32Type, editor.MakeId(), primitiveID.base));
|
||||
}
|
||||
else
|
||||
{
|
||||
rdcspv::Id posptr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(uint32InPtr, posptr, primitiveID.base,
|
||||
{editor.AddConstantImmediate(primitiveID.member)}));
|
||||
ops.push_back(rdcspv::OpLoad(uint32Type, loaded, posptr));
|
||||
rdcspv::Id posptr =
|
||||
ops.add(rdcspv::OpAccessChain(uint32InPtr, editor.MakeId(), primitiveID.base,
|
||||
{editor.AddConstantImmediate(primitiveID.member)}));
|
||||
loaded = ops.add(rdcspv::OpLoad(uint32Type, editor.MakeId(), posptr));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -705,23 +698,21 @@ static void CreatePSInputFetcher(rdcarray<uint32_t> &fragspv, uint32_t &structSt
|
||||
loaded = uintConsts[0];
|
||||
}
|
||||
|
||||
storePtr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(uint32BufPtr, storePtr, hit, {uintConsts[1]}));
|
||||
ops.push_back(rdcspv::OpStore(storePtr, loaded, alignedAccess));
|
||||
storePtr = ops.add(rdcspv::OpAccessChain(uint32BufPtr, editor.MakeId(), hit, {uintConsts[1]}));
|
||||
ops.add(rdcspv::OpStore(storePtr, loaded, alignedAccess));
|
||||
|
||||
if(sampleIndex.base != rdcspv::Id())
|
||||
{
|
||||
loaded = editor.MakeId();
|
||||
if(sampleIndex.member == ~0U)
|
||||
{
|
||||
ops.push_back(rdcspv::OpLoad(uint32Type, loaded, sampleIndex.base));
|
||||
loaded = ops.add(rdcspv::OpLoad(uint32Type, editor.MakeId(), sampleIndex.base));
|
||||
}
|
||||
else
|
||||
{
|
||||
rdcspv::Id posptr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(uint32InPtr, posptr, sampleIndex.base,
|
||||
{editor.AddConstantImmediate(sampleIndex.member)}));
|
||||
ops.push_back(rdcspv::OpLoad(uint32Type, loaded, posptr));
|
||||
rdcspv::Id posptr =
|
||||
ops.add(rdcspv::OpAccessChain(uint32InPtr, editor.MakeId(), sampleIndex.base,
|
||||
{editor.AddConstantImmediate(sampleIndex.member)}));
|
||||
loaded = ops.add(rdcspv::OpLoad(uint32Type, editor.MakeId(), posptr));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -730,24 +721,23 @@ static void CreatePSInputFetcher(rdcarray<uint32_t> &fragspv, uint32_t &structSt
|
||||
loaded = uintConsts[0];
|
||||
}
|
||||
|
||||
storePtr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(uint32BufPtr, storePtr, hit, {uintConsts[2]}));
|
||||
ops.push_back(rdcspv::OpStore(storePtr, loaded, alignedAccess));
|
||||
storePtr = ops.add(rdcspv::OpAccessChain(uint32BufPtr, editor.MakeId(), hit, {uintConsts[2]}));
|
||||
ops.add(rdcspv::OpStore(storePtr, loaded, alignedAccess));
|
||||
|
||||
// TODO store custom properties, and derivatives
|
||||
|
||||
// join up with the early-outs we did
|
||||
ops.push_back(rdcspv::OpBranch(killLabel2));
|
||||
ops.push_back(rdcspv::OpLabel(killLabel2));
|
||||
ops.push_back(rdcspv::OpBranch(killLabel));
|
||||
ops.push_back(rdcspv::OpLabel(killLabel));
|
||||
ops.add(rdcspv::OpBranch(killLabel2));
|
||||
ops.add(rdcspv::OpLabel(killLabel2));
|
||||
ops.add(rdcspv::OpBranch(killLabel));
|
||||
ops.add(rdcspv::OpLabel(killLabel));
|
||||
}
|
||||
// don't return, kill. This makes it well-defined that we don't write anything to our outputs
|
||||
ops.push_back(rdcspv::OpKill());
|
||||
ops.add(rdcspv::OpKill());
|
||||
|
||||
ops.push_back(rdcspv::OpFunctionEnd());
|
||||
ops.add(rdcspv::OpFunctionEnd());
|
||||
|
||||
editor.AddFunction(ops.data(), ops.size());
|
||||
editor.AddFunction(ops);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user