Skip to content

Commit

Permalink
Implement dynamic buffer offsets.
Browse files Browse the repository at this point in the history
Tests: *dynamic*
Bug: b/126330097
Change-Id: I7e4f7e3d921acb72878b7728216415ba66f63ec7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28249
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
  • Loading branch information
ben-clayton committed Apr 3, 2019
1 parent fcbb145 commit 225a130
Show file tree
Hide file tree
Showing 25 changed files with 287 additions and 108 deletions.
5 changes: 0 additions & 5 deletions src/Device/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,6 @@ namespace sw

void Context::init()
{
for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
{
descriptorSets[i] = nullptr;
}

// Set vertex streams to null stream
for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{
Expand Down
4 changes: 3 additions & 1 deletion src/Device/Context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define sw_Context_hpp

#include "Vulkan/VkConfig.h"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Sampler.hpp"
#include "Stream.hpp"
#include "Point.hpp"
Expand Down Expand Up @@ -153,7 +154,8 @@ namespace sw
int colorWriteActive(int index);
bool colorUsed();

vk::DescriptorSet *descriptorSets[vk::MAX_BOUND_DESCRIPTOR_SETS];
vk::DescriptorSet::Bindings descriptorSets = {};
vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
Stream input[MAX_VERTEX_INPUTS];
void *indexBuffer;

Expand Down
2 changes: 1 addition & 1 deletion src/Device/QuadRasterizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace sw
QuadRasterizer(const PixelProcessor::State &state, SpirvShader const *spirvShader);
virtual ~QuadRasterizer();

virtual void generate();
void generate();

protected:
Pointer<Byte> constants;
Expand Down
6 changes: 2 additions & 4 deletions src/Device/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,10 +388,8 @@ namespace sw
draw->setupPrimitives = setupPrimitives;
draw->setupState = setupState;

for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
{
data->descriptorSets[i] = context->descriptorSets[i];
}
data->descriptorSets = context->descriptorSets;
data->descriptorDynamicOffsets = context->descriptorDynamicOffsets;

for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{
Expand Down
4 changes: 3 additions & 1 deletion src/Device/Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "System/MutexLock.hpp"
#include "System/Thread.hpp"
#include "Device/Config.hpp"
#include "Vulkan/VkDescriptorSet.hpp"

#include <list>

Expand Down Expand Up @@ -114,7 +115,8 @@ namespace sw
{
const Constants *constants;

vk::DescriptorSet *descriptorSets[vk::MAX_BOUND_DESCRIPTOR_SETS];
vk::DescriptorSet::Bindings descriptorSets = {};
vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};

const void *input[MAX_VERTEX_INPUTS];
unsigned int stride[MAX_VERTEX_INPUTS];
Expand Down
17 changes: 8 additions & 9 deletions src/Pipeline/ComputeProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,9 @@ namespace sw

void ComputeProgram::emit()
{
Pointer<Pointer<Byte>> descriptorSetsIn = *Pointer<Pointer<Pointer<Byte>>>(data + OFFSET(Data, descriptorSets));
size_t numDescriptorSets = routine.pipelineLayout->getNumDescriptorSets();
for(unsigned int i = 0; i < numDescriptorSets; i++)
{
routine.descriptorSets[i] = descriptorSetsIn[i];
}

routine.pushConstants = Pointer<Byte>(data + OFFSET(Data, pushConstants));
routine.descriptorSets = data + OFFSET(Data, descriptorSets);
routine.descriptorDynamicOffsets = data + OFFSET(Data, descriptorDynamicOffsets);
routine.pushConstants = data + OFFSET(Data, pushConstants);

auto &modes = shader->getModes();

Expand Down Expand Up @@ -178,13 +173,17 @@ namespace sw
}

void ComputeProgram::run(
Routine *routine, void** descriptorSets, PushConstantStorage const &pushConstants,
Routine *routine,
vk::DescriptorSet::Bindings const &descriptorSets,
vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets,
PushConstantStorage const &pushConstants,
uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
{
auto runWorkgroup = (void(*)(void*))(routine->getEntry());

Data data;
data.descriptorSets = descriptorSets;
data.descriptorDynamicOffsets = descriptorDynamicOffsets;
data.numWorkgroups[X] = groupCountX;
data.numWorkgroups[Y] = groupCountY;
data.numWorkgroups[Z] = groupCountZ;
Expand Down
9 changes: 7 additions & 2 deletions src/Pipeline/ComputeProgram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "Reactor/Reactor.hpp"
#include "Device/Context.hpp"
#include "Vulkan/VkDescriptorSet.hpp"

#include <functional>

Expand Down Expand Up @@ -48,7 +49,10 @@ namespace sw
// run executes the compute shader routine for all workgroups.
// TODO(bclayton): This probably does not belong here. Consider moving.
static void run(
Routine *routine, void** descriptorSets, PushConstantStorage const &pushConstants,
Routine *routine,
vk::DescriptorSet::Bindings const &descriptorSetBindings,
vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets,
PushConstantStorage const &pushConstants,
uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);

protected:
Expand All @@ -60,7 +64,8 @@ namespace sw

struct Data
{
void** descriptorSets;
vk::DescriptorSet::Bindings descriptorSets;
vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets;
uint4 numWorkgroups;
uint4 workgroupID;
PushConstantStorage pushConstants;
Expand Down
2 changes: 2 additions & 0 deletions src/Pipeline/PixelProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace sw
{
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.
Expand Down
12 changes: 0 additions & 12 deletions src/Pipeline/PixelRoutine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,6 @@ namespace sw
{
}

void PixelRoutine::generate()
{
Pointer<Pointer<Byte>> descriptorSets = Pointer<Pointer<Byte>>(data + OFFSET(DrawData, descriptorSets));
auto numDescriptorSets = routine.pipelineLayout->getNumDescriptorSets();
for(unsigned int i = 0; i < numDescriptorSets; i++)
{
routine.descriptorSets[i] = descriptorSets[i];
}

QuadRasterizer::generate();
}

void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y)
{
#if PERF_PROFILE
Expand Down
2 changes: 0 additions & 2 deletions src/Pipeline/PixelRoutine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ namespace sw

virtual ~PixelRoutine();

void generate() override;

protected:
Float4 z[4]; // Multisampled z
Float4 w; // Used as is
Expand Down
25 changes: 18 additions & 7 deletions src/Pipeline/SpirvShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "System/Math.hpp"
#include "Vulkan/VkBuffer.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkPipelineLayout.hpp"
#include "Device/Config.hpp"

Expand Down Expand Up @@ -1722,15 +1723,25 @@ namespace sw
ASSERT(d.DescriptorSet >= 0);
ASSERT(d.Binding >= 0);

size_t bindingOffset = routine->pipelineLayout->getBindingOffset(d.DescriptorSet, d.Binding);
auto set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet*
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
size_t arrayIndex = 0; // TODO: descriptor arrays
size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex);

Pointer<Byte> set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet*
Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); // VkDescriptorBufferInfo*
Pointer<Byte> buffer = *Pointer<Pointer<Byte>>(binding + OFFSET(VkDescriptorBufferInfo, buffer)); // vk::Buffer*
Pointer<Byte> bufferInfo = Pointer<Byte>(set + bindingOffset); // VkDescriptorBufferInfo*
Pointer<Byte> buffer = *Pointer<Pointer<Byte>>(bufferInfo + OFFSET(VkDescriptorBufferInfo, buffer)); // vk::Buffer*
Pointer<Byte> data = *Pointer<Pointer<Byte>>(buffer + vk::Buffer::DataOffset); // void*
Int offset = *Pointer<Int>(binding + OFFSET(VkDescriptorBufferInfo, offset));
Pointer<Byte> address = data + offset;
routine->physicalPointers[resultId] = address;
Int offset = *Pointer<Int>(bufferInfo + OFFSET(VkDescriptorBufferInfo, offset));
if (setLayout->isBindingDynamic(d.Binding))
{
uint32_t dynamicBindingIndex =
routine->pipelineLayout->getDynamicOffsetBase(d.DescriptorSet) +
setLayout->getDynamicDescriptorOffset(d.Binding) +
arrayIndex;
offset += routine->descriptorDynamicOffsets[dynamicBindingIndex];
}

routine->physicalPointers[resultId] = data + offset;
break;
}
case spv::StorageClassPushConstant:
Expand Down
3 changes: 2 additions & 1 deletion src/Pipeline/SpirvShader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,8 @@ namespace sw
Value inputs = Value{MAX_INTERFACE_COMPONENTS};
Value outputs = Value{MAX_INTERFACE_COMPONENTS};

std::array<Pointer<Byte>, vk::MAX_BOUND_DESCRIPTOR_SETS> descriptorSets;
Pointer<Pointer<Byte>> descriptorSets;
Pointer<Int> descriptorDynamicOffsets;
Pointer<Byte> pushConstants;
Int killMask = Int{0};

Expand Down
9 changes: 2 additions & 7 deletions src/Pipeline/VertexProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ namespace sw
As<Float4>(Int4((*Pointer<Int>(data + OFFSET(DrawData, instanceID)))));
}

routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
routine.pushConstants = data + OFFSET(DrawData, pushConstants);

Pointer<Pointer<Byte>> descriptorSets = Pointer<Pointer<Byte>>(data + OFFSET(DrawData, descriptorSets));
auto numDescriptorSets = routine.pipelineLayout->getNumDescriptorSets();
for(unsigned int i = 0; i < numDescriptorSets; i++)
{
routine.descriptorSets[i] = descriptorSets[i];
}
}

VertexProgram::~VertexProgram()
Expand Down
82 changes: 53 additions & 29 deletions src/Vulkan/VkCommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class PipelineBind : public CommandBuffer::Command
protected:
void play(CommandBuffer::ExecutionState& executionState) override
{
executionState.pipelines[pipelineBindPoint] = Cast(pipeline);
executionState.pipelineState[pipelineBindPoint].pipeline = Cast(pipeline);
}

private:
Expand All @@ -171,11 +171,12 @@ class Dispatch : public CommandBuffer::Command
protected:
void play(CommandBuffer::ExecutionState& executionState) override
{
ComputePipeline* pipeline = static_cast<ComputePipeline*>(
executionState.pipelines[VK_PIPELINE_BIND_POINT_COMPUTE]);
auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];

ComputePipeline* pipeline = static_cast<ComputePipeline*>(pipelineState.pipeline);
pipeline->run(groupCountX, groupCountY, groupCountZ,
MAX_BOUND_DESCRIPTOR_SETS,
executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_COMPUTE],
pipelineState.descriptorSets,
pipelineState.descriptorDynamicOffsets,
executionState.pushConstants);
}

Expand All @@ -198,12 +199,13 @@ class DispatchIndirect : public CommandBuffer::Command
{
auto cmd = reinterpret_cast<VkDispatchIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset));

ComputePipeline* pipeline = static_cast<ComputePipeline*>(
executionState.pipelines[VK_PIPELINE_BIND_POINT_COMPUTE]);
auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];

ComputePipeline* pipeline = static_cast<ComputePipeline*>(pipelineState.pipeline);
pipeline->run(cmd->x, cmd->y, cmd->z,
MAX_BOUND_DESCRIPTOR_SETS,
executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_COMPUTE],
executionState.pushConstants);
pipelineState.descriptorSets,
pipelineState.descriptorDynamicOffsets,
executionState.pushConstants);
}

private:
Expand Down Expand Up @@ -304,19 +306,16 @@ struct DrawBase : public CommandBuffer::Command
void draw(CommandBuffer::ExecutionState& executionState, bool indexed,
uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance)
{
GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(
executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]);
auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_GRAPHICS];

GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(pipelineState.pipeline);

sw::Context context = pipeline->getContext();

executionState.bindVertexInputs(context, vertexOffset, firstInstance);

const auto& boundDescriptorSets = executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_GRAPHICS];
for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
{
context.descriptorSets[i] = reinterpret_cast<vk::DescriptorSet*>(boundDescriptorSets[i]);
}

context.descriptorSets = pipelineState.descriptorSets;
context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
context.pushConstants = executionState.pushConstants;

if (indexed)
Expand Down Expand Up @@ -683,21 +682,38 @@ struct WaitEvent : public CommandBuffer::Command

struct BindDescriptorSet : public CommandBuffer::Command
{
BindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, uint32_t set, const VkDescriptorSet& descriptorSet)
: pipelineBindPoint(pipelineBindPoint), set(set), descriptorSet(descriptorSet)
BindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, uint32_t set, const VkDescriptorSet& descriptorSet,
uint32_t dynamicOffsetCount, uint32_t const *dynamicOffsets)
: pipelineBindPoint(pipelineBindPoint), set(set), descriptorSet(descriptorSet),
dynamicOffsetCount(dynamicOffsetCount)
{
for (uint32_t i = 0; i < dynamicOffsetCount; i++)
{
this->dynamicOffsets[i] = dynamicOffsets[i];
}
}

void play(CommandBuffer::ExecutionState& executionState)
{
ASSERT((pipelineBindPoint < VK_PIPELINE_BIND_POINT_RANGE_SIZE) && (set < MAX_BOUND_DESCRIPTOR_SETS));
executionState.boundDescriptorSets[pipelineBindPoint][set] = descriptorSet;
ASSERT_OR_RETURN((pipelineBindPoint < VK_PIPELINE_BIND_POINT_RANGE_SIZE) && (set < MAX_BOUND_DESCRIPTOR_SETS));
auto &pipelineState = executionState.pipelineState[pipelineBindPoint];
auto pipelineLayout = pipelineState.pipeline->getLayout();
auto dynamicOffsetBase = pipelineLayout->getDynamicOffsetBase(set);
ASSERT_OR_RETURN(dynamicOffsetBase + dynamicOffsetCount <= MAX_DESCRIPTOR_SET_COMBINED_BUFFERS_DYNAMIC);

pipelineState.descriptorSets[set] = vk::Cast(descriptorSet);
for (uint32_t i = 0; i < dynamicOffsetCount; i++)
{
pipelineState.descriptorDynamicOffsets[dynamicOffsetBase + i] = dynamicOffsets[i];
}
}

private:
VkPipelineBindPoint pipelineBindPoint;
uint32_t set;
const VkDescriptorSet descriptorSet;
uint32_t dynamicOffsetCount;
vk::DescriptorSet::DynamicOffsets dynamicOffsets;
};

struct SetPushConstants : public CommandBuffer::Command
Expand Down Expand Up @@ -974,20 +990,28 @@ void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t re
UNIMPLEMENTED("setStencilReference");
}

void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout vkLayout,
uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
{
ASSERT(state == RECORDING);

if(dynamicOffsetCount > 0)
{
UNIMPLEMENTED("bindDescriptorSets");
}

for(uint32_t i = 0; i < descriptorSetCount; i++)
{
addCommand<BindDescriptorSet>(pipelineBindPoint, firstSet + i, pDescriptorSets[i]);
auto descriptorSetIndex = firstSet + i;
auto layout = vk::Cast(vkLayout);
auto setLayout = layout->getDescriptorSetLayout(descriptorSetIndex);

auto numDynamicDescriptors = setLayout->getDynamicDescriptorCount();
ASSERT(numDynamicDescriptors == 0 || pDynamicOffsets != nullptr);
ASSERT(dynamicOffsetCount >= numDynamicDescriptors);

addCommand<BindDescriptorSet>(
pipelineBindPoint, descriptorSetIndex, pDescriptorSets[i],
dynamicOffsetCount, pDynamicOffsets);

pDynamicOffsets += numDynamicDescriptors;
dynamicOffsetCount -= numDynamicDescriptors;
}
}

Expand Down
Loading

0 comments on commit 225a130

Please sign in to comment.