Commit 09591b87 by Nicolas Capens Committed by Nicolas Capens

Pass descriptor sets to SPIR-V compilation

The at draw time currently bound descriptors are passed down to the SPIR-V code generation so that we can read the sampler parameters and image view parameters. An important exception is compute shaders, which are currently compiled before the invoke calls. Also still TODO is taking the parameters into account during routine lookup in the cache. This change also eliminates the now unused 'enableMask' from PixelProgram and VertexProgram. Bug b/129523279 Change-Id: I1ea75ec5a7b83783a1efacb238143a419afa5bda Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28446Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 82eb22e2
......@@ -30,7 +30,7 @@ namespace vk
class DescriptorSet;
class ImageView;
class PipelineLayout;
} // namespace vk
}
namespace sw
{
......
......@@ -349,7 +349,7 @@ namespace sw
if(!routine)
{
QuadRasterizer *generator = new PixelProgram(state, context->pipelineLayout, context->pixelShader);
QuadRasterizer *generator = new PixelProgram(state, context->pipelineLayout, context->pixelShader, context->descriptorSets);
generator->generate();
routine = (*generator)("PixelRoutine_%0.8X", state.shaderID);
delete generator;
......
......@@ -142,7 +142,7 @@ namespace sw
if(!routine) // Create one
{
VertexRoutine *generator = new VertexProgram(state, context->pipelineLayout, context->vertexShader);
VertexRoutine *generator = new VertexProgram(state, context->pipelineLayout, context->vertexShader, context->descriptorSets);
generator->generate();
routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
delete generator;
......
......@@ -24,11 +24,12 @@ namespace
namespace sw
{
ComputeProgram::ComputeProgram(SpirvShader const *shader, vk::PipelineLayout const *pipelineLayout)
ComputeProgram::ComputeProgram(SpirvShader const *shader, vk::PipelineLayout const *pipelineLayout, const vk::DescriptorSet::Bindings &descriptorSets)
: data(Arg<0>()),
routine(pipelineLayout),
shader(shader),
pipelineLayout(pipelineLayout)
pipelineLayout(pipelineLayout),
descriptorSets(descriptorSets)
{
}
......@@ -157,7 +158,7 @@ namespace sw
});
// Process numLanes of the workgroup.
shader->emit(&routine, activeLaneMask);
shader->emit(&routine, activeLaneMask, descriptorSets);
}
}
......
......@@ -39,7 +39,7 @@ namespace sw
class ComputeProgram : public Function<Void(Pointer<Byte>)>
{
public:
ComputeProgram(SpirvShader const *spirvShader, vk::PipelineLayout const *pipelineLayout);
ComputeProgram(SpirvShader const *spirvShader, vk::PipelineLayout const *pipelineLayout, const vk::DescriptorSet::Bindings &descriptorSets);
virtual ~ComputeProgram();
......@@ -74,6 +74,7 @@ namespace sw
SpirvRoutine routine;
SpirvShader const * const shader;
vk::PipelineLayout const * const pipelineLayout;
const vk::DescriptorSet::Bindings &descriptorSets;
};
} // namespace sw
......
......@@ -29,14 +29,12 @@ namespace sw
void PixelProgram::applyShader(Int cMask[4])
{
enableIndex = 0;
routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
routine.pushConstants = data + OFFSET(DrawData, pushConstants);
auto activeLaneMask = SIMD::Int(0xFFFFFFFF); // TODO: Control this.
spirvShader->emit(&routine, activeLaneMask);
spirvShader->emit(&routine, activeLaneMask, descriptorSets);
spirvShader->emitEpilog(&routine);
for(int i = 0; i < RENDERTARGETS; i++)
......@@ -232,12 +230,6 @@ namespace sw
}
}
Int4 PixelProgram::enableMask()
{
Int4 enable = true ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
return enable;
}
Float4 PixelProgram::linearToSRGB(const Float4 &x) // Approximates x^(1.0/2.2)
{
Float4 sqrtx = Rcp_pp(RcpSqrt_pp(x));
......
......@@ -26,8 +26,9 @@ namespace sw
PixelProgram(
const PixelProcessor::State &state,
vk::PipelineLayout const *pipelineLayout,
SpirvShader const *spirvShader) :
PixelRoutine(state, pipelineLayout, spirvShader)
SpirvShader const *spirvShader,
const vk::DescriptorSet::Bindings &descriptorSets) :
PixelRoutine(state, pipelineLayout, spirvShader, descriptorSets)
{
}
......@@ -43,15 +44,9 @@ namespace sw
// Color outputs
Vector4f c[RENDERTARGETS];
// Per pixel based on conditions reached
Int enableIndex;
Array<Int4, 1 + 24> enableStack;
// Raster operations
void clampColor(Vector4f oC[RENDERTARGETS]);
Int4 enableMask();
Float4 linearToSRGB(const Float4 &x);
};
}
......
......@@ -35,9 +35,11 @@ namespace sw
PixelRoutine::PixelRoutine(
const PixelProcessor::State &state,
vk::PipelineLayout const *pipelineLayout,
SpirvShader const *spirvShader)
SpirvShader const *spirvShader,
const vk::DescriptorSet::Bindings &descriptorSets)
: QuadRasterizer(state, spirvShader),
routine(pipelineLayout)
routine(pipelineLayout),
descriptorSets(descriptorSets)
{
spirvShader->emitProlog(&routine);
......
......@@ -27,7 +27,8 @@ namespace sw
public:
PixelRoutine(const PixelProcessor::State &state,
vk::PipelineLayout const *pipelineLayout,
SpirvShader const *spirvShader);
SpirvShader const *spirvShader,
const vk::DescriptorSet::Bindings &descriptorSets);
virtual ~PixelRoutine();
......@@ -37,6 +38,7 @@ namespace sw
Float4 rhw; // Reciprocal w
SpirvRoutine routine;
const vk::DescriptorSet::Bindings &descriptorSets;
// Depth output
Float4 oDepth;
......
......@@ -19,6 +19,7 @@
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkPipelineLayout.hpp"
#include "Vulkan/VkDescriptorSetLayout.hpp"
#include "Device/Config.hpp"
#include <spirv/unified1/spirv.hpp>
......@@ -1371,11 +1372,9 @@ namespace sw
}
}
void SpirvShader::emit(SpirvRoutine *routine, RValue<SIMD::Int> const &activeLaneMask) const
void SpirvShader::emit(SpirvRoutine *routine, RValue<SIMD::Int> const &activeLaneMask, const vk::DescriptorSet::Bindings &descriptorSets) const
{
EmitState state;
state.setActiveLaneMask(activeLaneMask);
state.routine = routine;
EmitState state(routine, activeLaneMask, descriptorSets);
// Emit everything up to the first label
// TODO: Separate out dispatch of block from non-block instructions?
......
......@@ -20,6 +20,7 @@
#include "System/Types.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkConfig.h"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Device/Config.hpp"
#include <spirv/unified1/spirv.hpp>
......@@ -480,7 +481,7 @@ namespace sw
std::vector<InterfaceComponent> outputs;
void emitProlog(SpirvRoutine *routine) const;
void emit(SpirvRoutine *routine, RValue<SIMD::Int> const &activeLaneMask) const;
void emit(SpirvRoutine *routine, RValue<SIMD::Int> const &activeLaneMask, const vk::DescriptorSet::Bindings &descriptorSets) const;
void emitEpilog(SpirvRoutine *routine) const;
using BuiltInHash = std::hash<std::underlying_type<spv::BuiltIn>::type>;
......@@ -610,6 +611,13 @@ namespace sw
class EmitState
{
public:
EmitState(SpirvRoutine *routine, RValue<SIMD::Int> activeLaneMask, const vk::DescriptorSet::Bindings &descriptorSets)
: routine(routine),
activeLaneMaskValue(activeLaneMask.value),
descriptorSets(descriptorSets)
{
}
RValue<SIMD::Int> activeLaneMask() const
{
ASSERT(activeLaneMaskValue != nullptr);
......@@ -638,6 +646,8 @@ namespace sw
Block::Set visited; // Blocks already built.
std::unordered_map<Block::Edge, RValue<SIMD::Int>, Block::Edge::Hash> edgeActiveLaneMasks;
std::queue<Block::ID> *pending;
const vk::DescriptorSet::Bindings &descriptorSets;
};
// EmitResult is an enumerator of result values from the Emit functions.
......
......@@ -27,16 +27,11 @@ namespace sw
VertexProgram::VertexProgram(
const VertexProcessor::State &state,
vk::PipelineLayout const *pipelineLayout,
SpirvShader const *spirvShader)
: VertexRoutine(state, pipelineLayout, spirvShader)
SpirvShader const *spirvShader,
const vk::DescriptorSet::Bindings &descriptorSets)
: VertexRoutine(state, pipelineLayout, spirvShader),
descriptorSets(descriptorSets)
{
ifDepth = 0;
loopRepDepth = 0;
currentLabel = -1;
whileTest = false;
enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
auto it = spirvShader->inputBuiltins.find(spv::BuiltInInstanceIndex);
if (it != spirvShader->inputBuiltins.end())
{
......@@ -57,10 +52,6 @@ namespace sw
void VertexProgram::program(UInt &index)
{
// shader->print("VertexShader-%0.8X.txt", state.shaderID);
enableIndex = 0;
auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex);
if (it != spirvShader->inputBuiltins.end())
{
......@@ -70,20 +61,8 @@ namespace sw
}
auto activeLaneMask = SIMD::Int(0xFFFFFFFF); // TODO: Control this.
spirvShader->emit(&routine, activeLaneMask);
if(currentLabel != -1)
{
Nucleus::setInsertBlock(returnBlock);
}
spirvShader->emit(&routine, activeLaneMask, descriptorSets);
spirvShader->emitEpilog(&routine);
}
Int4 VertexProgram::enableMask()
{
Int4 enable = true ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
return enable;
}
}
......@@ -32,31 +32,15 @@ namespace sw
VertexProgram(
const VertexProcessor::State &state,
vk::PipelineLayout const *pipelineLayout,
SpirvShader const *spirvShader);
SpirvShader const *spirvShader,
const vk::DescriptorSet::Bindings &descriptorSets);
virtual ~VertexProgram();
private:
Int enableIndex;
Array<Int4, 1 + 24> enableStack;
void program(UInt &index) override;
RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int &offset);
Int4 enableMask();
int ifDepth;
int loopRepDepth;
int currentLabel;
bool whileTest;
BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4];
BasicBlock *loopRepEndBlock[4];
BasicBlock *labelBlock[2048];
std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock;
bool isConditionalIf[24 + 24];
const vk::DescriptorSet::Bindings &descriptorSets;
};
}
......
......@@ -505,10 +505,10 @@ void ComputePipeline::compileShaders(const VkAllocationCallbacks* pAllocator, co
ASSERT(shader == nullptr);
// FIXME (b/119409619): use allocator.
// FIXME(b/119409619): use allocator.
shader = new sw::SpirvShader(code);
sw::ComputeProgram program(shader, layout);
vk::DescriptorSet::Bindings descriptorSets; // FIXME(b/129523279): Delay code generation until invoke time.
sw::ComputeProgram program(shader, layout, descriptorSets);
program.generate();
......
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