Skip to content

Commit

Permalink
Changes to push constants
Browse files Browse the repository at this point in the history
  • Loading branch information
haing committed Apr 15, 2016
1 parent 2f06008 commit d2e835f
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 59 deletions.
2 changes: 1 addition & 1 deletion include/cinder/vk/Pipeline.h
Expand Up @@ -169,7 +169,7 @@ class Pipeline : public BaseDeviceObject {
Options& setCullModeBack() { return setCullMode( VK_CULL_MODE_BACK_BIT ); }
Options& setCullModeFrontAndBack() { return setCullMode( VK_CULL_MODE_FRONT_AND_BACK ); }

Options& setSamples( VkSampleCountFlagBits value ) { mSamples = value; return *this; }
Options& setRasterizationSamples( VkSampleCountFlagBits value ) { mSamples = value; return *this; }

private:
VkPrimitiveTopology mTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
Expand Down
9 changes: 8 additions & 1 deletion include/cinder/vk/UniformLayout.h
Expand Up @@ -177,6 +177,7 @@ class UniformLayout {
STORAGE_IMAGE = 0x000000004,
STORAGE_BUFFER = 0x000000008,
PUSH_CONSTANTS = 0x000000010,
ANY_BLOCK = BLOCK | PUSH_CONSTANTS,
ANY_IMAGE = SAMPLER | STORAGE_IMAGE,
ANY = BLOCK | SAMPLER | STORAGE_IMAGE | STORAGE_BUFFER | PUSH_CONSTANTS
};
Expand Down Expand Up @@ -207,6 +208,8 @@ class UniformLayout {

void sortByOffset();

std::vector<VkPushConstantRange> getPushConstantRanges() const;

private:
bool mDirty = false;

Expand Down Expand Up @@ -259,6 +262,8 @@ class UniformLayout {
UniformLayout& setBinding( const std::string& bindingName, uint32_t bindingNumber, VkShaderStageFlags bindingStages, uint32_t setNumber );
const std::vector<Binding>& getBindings() const { return mBindings; }

std::vector<VkPushConstantRange> getPushConstantRanges() const;

void addSet( uint32_t setNumber, uint32_t changeFrequency );
UniformLayout& setSet( uint32_t setNumber, uint32_t changeFrequency );
const std::vector<Set>& getSets() const { return mSets; }
Expand Down Expand Up @@ -377,7 +382,9 @@ class UniformSet {
UniformSet( const UniformLayout& layout, const UniformSet::Options& options, vk::Device *device );
virtual ~UniformSet();

static UniformSetRef create( const UniformLayout& layout, const UniformSet::Options& options = UniformSet::Options(), vk::Device *device = nullptr );
static UniformSetRef create( const UniformLayout& layout, const UniformSet::Options& options = UniformSet::Options(), vk::Device *device = nullptr );

std::vector<VkPushConstantRange> getPushConstantRanges() const;

const std::vector<UniformSet::SetRef>& getSets() const { return mSets; }
const std::vector<std::vector<VkDescriptorSetLayoutBinding>>& getCachedDescriptorSetLayoutBindings() const { return mCachedDescriptorSetLayoutBindings; }
Expand Down
27 changes: 10 additions & 17 deletions include/cinder/vk/scoped.h
Expand Up @@ -45,22 +45,8 @@
namespace cinder { namespace vk {

class Context;

////! \class ScopedSemaphore
////!
////!
//class ScopedSemaphore : public BaseVkObject {
//public:
//
// ScopedSemaphore( Context *context = nullptr );
// virtual ~ScopedSemaphore();
//
// VkSemaphore obj() const { return mSemaphore; }
// const VkSemaphore* ptr() const { return &mSemaphore; }
//
//private:
// VkSemaphore mSemaphore = VK_NULL_HANDLE;
//};
class ShaderProg;
using ShaderProgRef = std::shared_ptr<ShaderProg>;

struct ScopedColor : private Noncopyable {
ScopedColor();
Expand All @@ -73,7 +59,6 @@ struct ScopedColor : private Noncopyable {
ColorAf mColor;
};


//! Controls the current blend mode for the current scope.
struct ScopedBlend : private Noncopyable {
//! Enables or disables blending (`GL_BLEND`) state.
Expand Down Expand Up @@ -111,6 +96,14 @@ struct ScopedBlendAdditive : public ScopedBlend
{}
};

struct ScopedShaderProg : private Noncopyable {
ScopedShaderProg( const ShaderProgRef &prog );
~ScopedShaderProg();

private:
Context *mCtx;
};

struct ScopedScissor : private Noncopyable {
//! Implicitly enables scissor test
ScopedScissor( const ivec2 &lowerLeftPosition, const ivec2 &dimension );
Expand Down
2 changes: 1 addition & 1 deletion src/cinder/vk/Pipeline.cpp
Expand Up @@ -110,7 +110,7 @@ void PipelineLayout::initialize( const std::vector<VkDescriptorSetLayout>& descr
createInfo.pushConstantRangeCount = 0;
createInfo.pPushConstantRanges = NULL;
createInfo.setLayoutCount = static_cast<uint32_t>( descriptorSetLayouts.size() );
createInfo.pSetLayouts = descriptorSetLayouts.data();
createInfo.pSetLayouts = descriptorSetLayouts.empty() ? nullptr : descriptorSetLayouts.data();

VkResult res = vkCreatePipelineLayout( mDevice->getDevice(), &createInfo, NULL, &mPipelineLayout );
assert( res == VK_SUCCESS );
Expand Down
11 changes: 6 additions & 5 deletions src/cinder/vk/ShaderProg.cpp
Expand Up @@ -810,14 +810,15 @@ void extractBlock( VkShaderStageFlagBits shaderStage, const spir2cross::Resource
outUniformLayout->addSet( bindingSet, CHANGES_DONTCARE );

for( uint32_t index = 0; index < typeInfo.member_types.size(); ++index ) {
std::string memberName = backCompiler->get_member_name( res.type_id, index );
uint32_t memberId = typeInfo.member_types[index];
auto& memberTypeInfo = backCompiler->get_type( memberId );
uint32_t memberOffset = backCompiler->get_member_decoration( res.type_id, index, spv::DecorationOffset );
std::string memberName = backCompiler->get_member_name( res.type_id, index );
uint32_t memberId = typeInfo.member_types[index];
auto& memberTypeInfo = backCompiler->get_type( memberId );
uint32_t memberOffset = backCompiler->get_member_decoration( res.type_id, index, spv::DecorationOffset );
uint32_t memberArraySize = memberTypeInfo.array.empty() ? 1 : memberTypeInfo.array[0];
GlslUniformDataType memberDataType = spirTypeToGlslUniformDataType( memberTypeInfo );

std::string uniformName = bindingName + "." + memberName;
outUniformLayout->addUniform( uniformName, memberDataType, memberOffset );
outUniformLayout->addUniform( uniformName, memberDataType, memberOffset, memberArraySize );
}

// Block size
Expand Down
54 changes: 48 additions & 6 deletions src/cinder/vk/UniformLayout.cpp
Expand Up @@ -268,6 +268,22 @@ void UniformLayout::Binding::sortByOffset()
mBlock.sortUniformsByOffset();
}

std::vector<VkPushConstantRange> UniformLayout::Binding::getPushConstantRanges() const
{
std::vector<VkPushConstantRange> result;
if( isPushConstants() ) {
const auto& uniforms = mBlock.getUniforms();
for( const auto& uniformStore : uniforms ) {
VkPushConstantRange range = {};
range.stageFlags = getStages();
range.offset = static_cast<uint32_t>( uniformStore.first.getOffset() );
range.size = static_cast<uint32_t>( uniformStore.first.getArraySize()*glslUniformDataTypeSizeBytes( uniformStore.first.getDataType() ) );
result.push_back( range );
}
}
return result;
}

// -------------------------------------------------------------------------------------------------
// UniformLayout
// -------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -320,7 +336,7 @@ void UniformLayout::addUniformImpl( GlslUniformDataType dataType, const std::str

std::string bindingName = tokens[0];

auto bindingRef = findBindingObject( bindingName, Binding::Type::BLOCK, true );
auto bindingRef = findBindingObject( bindingName, Binding::Type::ANY_BLOCK, true );
if( bindingRef ) {
// NOTE: Use the full name (in block.uniform format) for the uniform name
auto uniformRef = bindingRef->mBlock.findUniformObject( name, dataType, true );
Expand Down Expand Up @@ -357,7 +373,7 @@ void UniformLayout::setUniformValue( GlslUniformDataType dataType, const std::st

// Find the binding that contains the block we need
std::string bindingName = tokens[0];
auto bindingRef = findBindingObject( bindingName, Binding::Type::BLOCK, false );
auto bindingRef = findBindingObject( bindingName, Binding::Type::ANY_BLOCK, false );
if( ! bindingRef ) {
return;
}
Expand Down Expand Up @@ -465,6 +481,16 @@ UniformLayout& UniformLayout::setBinding( const std::string& bindingName, uint32
return *this;
}

std::vector<VkPushConstantRange> UniformLayout::getPushConstantRanges() const
{
std::vector<VkPushConstantRange> result;
for( const auto& binding : mBindings ) {
auto ranges = binding.getPushConstantRanges();
std::copy( std::begin( ranges ), std::end( ranges ), std::back_inserter( result ) );
}
return result;
}

void UniformLayout::addSet( uint32_t setNumber, uint32_t changeFrequency )
{
auto it = std::find_if(
Expand Down Expand Up @@ -858,6 +884,11 @@ UniformSet::UniformSet( const UniformLayout& layout, const UniformSet::Options&
// Create DescriptorSetLayoutBindings
for( auto& set : mSets ) {
for( const auto& binding : set->mBindings ) {
// Skip push constants
if( UniformLayout::Binding::Type::PUSH_CONSTANTS == binding.getType() ) {
continue;
}
// Proceed with the rest
VkDescriptorSetLayoutBinding layoutBinding = {};
layoutBinding.binding = binding.getBinding();
layoutBinding.descriptorCount = 1;
Expand All @@ -866,25 +897,21 @@ UniformSet::UniformSet( const UniformLayout& layout, const UniformSet::Options&
switch( binding.getType() ) {
case UniformLayout::Binding::Type::BLOCK: {
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
//layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
}
break;

case UniformLayout::Binding::Type::SAMPLER: {
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
//layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
}
break;

case UniformLayout::Binding::Type::STORAGE_IMAGE: {
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
//layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
}
break;

case UniformLayout::Binding::Type::STORAGE_BUFFER: {
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
//layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
}
break;
}
Expand All @@ -902,6 +929,9 @@ UniformSet::UniformSet( const UniformLayout& layout, const UniformSet::Options&
//}

const auto& srcBindings = set->mDescriptorSetLayoutBindings;
if( srcBindings.empty() ) {
continue;
}

// Find the max binding number
uint32_t maxBindingNumber = 0;
Expand Down Expand Up @@ -1007,6 +1037,18 @@ UniformSetRef UniformSet::create( const UniformLayout& layout, const UniformSet:
return result;
}

std::vector<VkPushConstantRange> UniformSet::getPushConstantRanges() const
{
std::vector<VkPushConstantRange> result;
for( const auto& set : mSets ) {
for( const auto& binding : set->mBindings ) {
auto ranges = binding.getPushConstantRanges();
std::copy( std::begin( ranges ), std::end( ranges ), std::back_inserter( result ) );
}
}
return result;
}

UniformSet::Binding* UniformSet::findBindingObject( const std::string& name, Binding::Type bindingType )
{
UniformSet::Binding* result = nullptr;
Expand Down
119 changes: 119 additions & 0 deletions src/cinder/vk/draw.cpp
Expand Up @@ -165,6 +165,124 @@ void draw( const Texture2dRef &texture, const Rectf &dstRect )

void drawSolidRect( const Rectf &r, const vec2 &upperLeftTexCoord, const vec2 &lowerRightTexCoord )
{
struct DrawCache {
vk::ShaderProgRef shader;
vk::UniformSetRef uniformSet;
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
vk::DescriptorPoolRef descriptorPool;
vk::DescriptorSetRef descriptorSet;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VkPushConstantRange pcrMvp;
VkPushConstantRange pcrRect;
VkPushConstantRange pcrUvs;
VkPushConstantRange pcrColor;
DrawCache() {}
};

static vk::VertexBufferRef sVertexBufferCache;
static std::shared_ptr<DrawCache> sDrawCache;

// Handle caching
{
// Cache vertex buffer
if( ! sVertexBufferCache ) {
// Triangle strip
std::vector<float> data = {
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
};
// Vertex buffer
sVertexBufferCache = vk::VertexBuffer::create( static_cast<const void*>( data.data() ), data.size()*sizeof( float ), vk::VertexBuffer::Format().setTransientAllocation() );
}

if( ! sDrawCache ) {
sDrawCache = std::shared_ptr<DrawCache>( new DrawCache() );
}

const auto& shader = vk::context()->getShaderProg();
if( shader != sDrawCache->shader ) {
// Cache shader
sDrawCache->shader = shader;
// Cache uniform set
sDrawCache->uniformSet = vk::UniformSet::create( shader->getUniformLayout());
// Descriptor layout, pool, set
if( ! sDrawCache->uniformSet->getCachedDescriptorSetLayoutBindings().empty() ) {
const auto& layoutBindings = sDrawCache->uniformSet->getCachedDescriptorSetLayoutBindings()[0];
sDrawCache->descriptorSetLayout = vk::context()->getDevice()->getDescriptorSetLayoutSelector()->getSelectedLayout( layoutBindings );
sDrawCache->descriptorPool = vk::DescriptorPool::create( sDrawCache->uniformSet->getCachedDescriptorSetLayoutBindings() );
sDrawCache->descriptorSet = vk::DescriptorSet::create( sDrawCache->descriptorPool.get(), sDrawCache->descriptorSetLayout );
// Update descriptor set
auto descriptorSetWrites = sDrawCache->uniformSet->getSets()[0]->getBindingUpdates( sDrawCache->descriptorSet->vkObject() );
sDrawCache->descriptorSet->update( descriptorSetWrites );
}
// Pipeline layout
sDrawCache->pipelineLayout = vk::context()->getDevice()->getPipelineLayoutSelector()->getSelectedLayout( { sDrawCache->descriptorSetLayout } );
}
}

// Pipeline
VkPipeline pipeline = VK_NULL_HANDLE;
{
// Vertex input attribute description
// Position
VkVertexInputAttributeDescription viad0 = {};
viad0.binding = 0;
viad0.format = VK_FORMAT_R32G32B32A32_SFLOAT;
viad0.location = 0;
viad0.offset = 0;

// Vertex input binding description
VkVertexInputBindingDescription vibd = {};
vibd.binding = 0;
vibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
vibd.stride = 4*sizeof(float) + 2*sizeof(float) + 4*sizeof(float);

auto ctx = vk::context();
auto& pipelineSelector = ctx->getDevice()->getPipelineSelector();
pipelineSelector->setTopology( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP );
pipelineSelector->setVertexInputAttributeDescriptions( { viad0 } );
pipelineSelector->setVertexInputBindingDescriptions( { vibd } );
pipelineSelector->setCullMode( ctx->getCullMode() );
pipelineSelector->setFrontFace( ctx->getFrontFace() );
pipelineSelector->setDepthBias( ctx->getDepthBiasEnable(), ctx->getDepthBiasSlopeFactor(), ctx->getDepthBiasConstantFactor(), ctx->getDepthBiasClamp() );
pipelineSelector->setRasterizationSamples( ctx->getRenderPass()->getSubpassSampleCount( ctx->getSubpass() ) );
pipelineSelector->setDepthTest( ctx->getDepthTest() );
pipelineSelector->setDepthWrite( ctx->getDepthWrite() );
pipelineSelector->setColorBlendAttachments( ctx->getColorBlendAttachments() );
pipelineSelector->setShaderStages( sDrawCache->shader->getPipelineShaderStages() );
pipelineSelector->setRenderPass( ctx->getRenderPass()->getRenderPass() );
pipelineSelector->setSubPass( ctx->getSubpass() );
pipelineSelector->setPipelineLayout( sDrawCache->pipelineLayout );
pipeline = pipelineSelector->getSelectedPipeline();
}

// Get current command buffer
auto cmdBufRef = vk::context()->getCommandBuffer();
auto cmdBuf = cmdBufRef->getCommandBuffer();

mat4 mvp = vk::getModelViewProjection();
vkCmdPushConstants( cmdBuf, sDrawCache->pipelineLayout, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, sizeof(mat4), &mvp );
vkCmdPushConstants( cmdBuf, sDrawCache->pipelineLayout, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 64, sizeof(Rectf), &r );

// Bind vertex buffer
std::vector<VkBuffer> vertexBuffers = { sVertexBufferCache->getBuffer() };
std::vector<VkDeviceSize> offsets = { 0 };
vkCmdBindVertexBuffers( cmdBuf, 0, static_cast<uint32_t>( vertexBuffers.size() ), vertexBuffers.data(), offsets.data() );

// Bind pipeline
vkCmdBindPipeline( cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline );

// Bind descriptor sets
std::vector<VkDescriptorSet> descSets = {sDrawCache->descriptorSet->vkObject() };
vkCmdBindDescriptorSets( cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, sDrawCache->pipelineLayout, 0, static_cast<uint32_t>( descSets.size() ), descSets.data(), 0, nullptr );

// Draw geometry
uint32_t numVertices = 4;
vkCmdDraw( cmdBuf, numVertices, 1, 0, 0 );

/*
const ColorAf& color = vk::context()->getCurrentColor();
vec2 uv0 = upperLeftTexCoord;
vec2 uv1 = lowerRightTexCoord;
Expand Down Expand Up @@ -276,6 +394,7 @@ void drawSolidRect( const Rectf &r, const vec2 &upperLeftTexCoord, const vec2 &l
// Draw geometry
uint32_t numVertices = 4;
vkCmdDraw( cmdBuf, numVertices, 1, 0, 0 );
*/
}

}} // namespace cinder::vk

0 comments on commit d2e835f

Please sign in to comment.