Sign in to follow this  

Dynamic Uniform Buffers (Solved)

Recommended Posts

I'm having issues getting Dynamic Uniform Buffers to work with dynamic offsets. I can't seem to figure out why or how I'm getting this error. Can somebody help me understand what I'm doing wrong?

 

2866 | 23 | Descriptor set 0x22 encountered the following validation error at vkCmdDraw() time: Dynamic descriptor in binding #0 at global descriptor index 0 uses buffer 0000000000000030 with dynamic offset 256 combined with offset 0 and range 416 that oversteps the buffer size of 416.

 


void Shader::Begin(UInt index)
{
    Renderer *ren = GetParent<Renderer>();

    CmdBufferManager *drawBufferManager = ren->GetQueue(VK_QUEUE_GRAPHICS_BIT)->GetCmdBufferManager(U"DrawCommands");

    VkCommandBufferInheritanceInfo inherInfo = {
        VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
        0,
        ren->GetRenderPass(),
        0,
        ren->CurrentFrameBuffer(),
        VK_FALSE,
        0,
        0
    };

    VkCommandBufferBeginInfo beginInfo = {};
    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
    beginInfo.pInheritanceInfo = &inherInfo;

    drawBufferManager->Begin(index, beginInfo);

    ren->UpdateViewport();

    vkCmdBindPipeline(*drawBufferManager->Get(index), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);

    UInt *offsets = 0;
    UInt_64 ind = 0;
    UInt size = 0;

    for (UInt_64 i = 0; i < descriptorWrites.size(); ++i)
    {
        if (descriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
            continue;

        ++size;
    }

    offsets = new UInt[size];

    for (UInt_64 i = 0; i < descriptorWrites.size(); ++i)
    {
        if (descriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
            continue;

        offsets[ind++] = static_cast<UInt>(uniformBuffers[i].GetAllignment(uniformBuffers[i].GetDataSize() * bindCalls));
    }

    vkCmdBindDescriptorSets(*drawBufferManager->Get(index), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, size, offsets);

    delete[] offsets;
}

 

Edited by Karutoh

Share this post


Link to post
Share on other sites

VkDescriptorBufferInfo's member, range must be the max data size of a single object. For example if my data for a single object was for the MVP Matrices, and all together it was 48 bytes, you then would use GetAllignment for the range member, in respects of minUniformBufferOffsetAlignmentminUniformBufferOffsetAlignment for me was 256 bytes, so instead of using 48 I would use 256 bytes, if my matrices went over 256 bytes, then it would be "rounded" up to 512 bytes. This is also on the dynamic_uniform sample located in the Vulkan API-Samples folder.

UInt_64 Buffer::GetAllignment(Renderer *ren, UInt_64 i)
{
	VkPhysicalDeviceProperties prop;
	vkGetPhysicalDeviceProperties(ren->PhysicalDevice(), &prop);

	if (prop.limits.minUniformBufferOffsetAlignment)
		return (i + prop.limits.minUniformBufferOffsetAlignment - 1) & ~(prop.limits.minUniformBufferOffsetAlignment - 1);

	return i;
}
Edited by Karutoh

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this