Results 1 to 5 of 5

Thread: Push Constant not updating

  1. #1
    Junior Member
    Join Date
    Apr 2017
    Posts
    13

    Push Constant not updating

    I cant find why my push constant is not being updated in the compute pipeline. The struct which the push constant point is being updated, but it looks like the new values are not going forward the compute shader.

    Here is the commandBuffer code:
    Code :
    	VkCommandBufferBeginInfo cmdBufInfo = commandBufferBeginInfo();
     
    	ErrorCheck(vkBeginCommandBuffer(s_compute.commandBuffer[0], &cmdBufInfo));
            vkCmdPushConstants(
    		s_compute.commandBuffer[0],
    		s_compute.pipelineLayout,
    		VK_SHADER_STAGE_COMPUTE_BIT,
    		0,
    		sizeof(computeValues),
    		&computeValues);
    	for (std::map<Material*, std::vector<RenderObject*>>::iterator it = _render_resource->materials.begin(); it != _render_resource->materials.end(); ++it)
    	{
    		// Add memory barrier to ensure that the indirect commands have been consumed before the compute shader updates them
    		VkBufferMemoryBarrier bufferBarrier = bufferMemoryBarrier();
    		bufferBarrier.buffer = it->first->buffers[indirectCommand].buffer;
    		bufferBarrier.size = it->first->buffers[indirectCommand].descriptor.range;
    		bufferBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
    		bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
    		bufferBarrier.srcQueueFamilyIndex = _graphics_family_index;
    		bufferBarrier.dstQueueFamilyIndex = _compute_family_index;
     
    		vkCmdPipelineBarrier(
    			s_compute.commandBuffer[0],
    			VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
    			VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
    			VK_FLAGS_NONE,
    			0, nullptr,
    			1, &bufferBarrier,
    			0, nullptr);
     
    		vkCmdBindPipeline(s_compute.commandBuffer[0], VK_PIPELINE_BIND_POINT_COMPUTE, s_compute.pipeline);
     
    		vkCmdBindDescriptorSets(s_compute.commandBuffer[0], VK_PIPELINE_BIND_POINT_COMPUTE, s_compute.pipelineLayout, 0, 1, &it->first->descriptorSets[descriptionSet], 0, 0);
    		vkCmdDispatch(s_compute.commandBuffer[0], it->second.size() / 16, 1, 1);
     
    		// Add memory barrier to ensure that the compute shader has finished writing the indirect command buffer before it's consumed
    		bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
    		bufferBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
    		bufferBarrier.buffer = it->first->buffers[indirectCommand].buffer;
    		bufferBarrier.size = it->first->buffers[indirectCommand].descriptor.range;
    		bufferBarrier.srcQueueFamilyIndex = _compute_family_index;
    		bufferBarrier.dstQueueFamilyIndex = _compute_family_index;
     
    		vkCmdPipelineBarrier(
    			s_compute.commandBuffer[0],
    			VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
    			VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
    			VK_FLAGS_NONE,
    			0, nullptr,
    			1, &bufferBarrier,
    			0, nullptr);
     
    	}
    	vkEndCommandBuffer(s_compute.commandBuffer[0]);

    When the push contant was passed by uniform binding it was working great, but now i need it to be a push constant.

    Do you know why it could be happening?

  2. #2
    Junior Member
    Join Date
    Apr 2017
    Posts
    13
    Quote Originally Posted by Harukoxd View Post
    I cant find why my push constant is not being updated in the compute pipeline. The struct which the push constant point is being updated, but it looks like the new values are not going forward the compute shader.

    Here is the commandBuffer code:
    Code :
    	VkCommandBufferBeginInfo cmdBufInfo = commandBufferBeginInfo();
     
    	ErrorCheck(vkBeginCommandBuffer(s_compute.commandBuffer[0], &cmdBufInfo));
            vkCmdPushConstants(
    		s_compute.commandBuffer[0],
    		s_compute.pipelineLayout,
    		VK_SHADER_STAGE_COMPUTE_BIT,
    		0,
    		sizeof(computeValues),
    		&computeValues);
    	for (std::map<Material*, std::vector<RenderObject*>>::iterator it = _render_resource->materials.begin(); it != _render_resource->materials.end(); ++it)
    	{
    		// Add memory barrier to ensure that the indirect commands have been consumed before the compute shader updates them
    		VkBufferMemoryBarrier bufferBarrier = bufferMemoryBarrier();
    		bufferBarrier.buffer = it->first->buffers[indirectCommand].buffer;
    		bufferBarrier.size = it->first->buffers[indirectCommand].descriptor.range;
    		bufferBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
    		bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
    		bufferBarrier.srcQueueFamilyIndex = _graphics_family_index;
    		bufferBarrier.dstQueueFamilyIndex = _compute_family_index;
     
    		vkCmdPipelineBarrier(
    			s_compute.commandBuffer[0],
    			VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
    			VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
    			VK_FLAGS_NONE,
    			0, nullptr,
    			1, &bufferBarrier,
    			0, nullptr);
     
    		vkCmdBindPipeline(s_compute.commandBuffer[0], VK_PIPELINE_BIND_POINT_COMPUTE, s_compute.pipeline);
     
    		vkCmdBindDescriptorSets(s_compute.commandBuffer[0], VK_PIPELINE_BIND_POINT_COMPUTE, s_compute.pipelineLayout, 0, 1, &it->first->descriptorSets[descriptionSet], 0, 0);
    		vkCmdDispatch(s_compute.commandBuffer[0], it->second.size() / 16, 1, 1);
     
    		// Add memory barrier to ensure that the compute shader has finished writing the indirect command buffer before it's consumed
    		bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
    		bufferBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
    		bufferBarrier.buffer = it->first->buffers[indirectCommand].buffer;
    		bufferBarrier.size = it->first->buffers[indirectCommand].descriptor.range;
    		bufferBarrier.srcQueueFamilyIndex = _compute_family_index;
    		bufferBarrier.dstQueueFamilyIndex = _compute_family_index;
     
    		vkCmdPipelineBarrier(
    			s_compute.commandBuffer[0],
    			VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
    			VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
    			VK_FLAGS_NONE,
    			0, nullptr,
    			1, &bufferBarrier,
    			0, nullptr);
     
    	}
    	vkEndCommandBuffer(s_compute.commandBuffer[0]);

    When the push contant was passed by uniform binding it was working great, but now i need it to be a push constant.

    Do you know why it could be happening?
    Can someone please tell me an advice? Do you need some more info? What ever im stuck with this

  3. #3
    Senior Member
    Join Date
    Dec 2013
    Location
    Germany
    Posts
    149
    Can you add all other relevant parts? Especially the pipeline layout creation part where you define your push constant ranges.

  4. #4
    Junior Member
    Join Date
    Apr 2017
    Posts
    13
    Quote Originally Posted by Sascha Willems View Post
    Can you add all other relevant parts? Especially the pipeline layout creation part where you define your push constant ranges.
    Code :
    		VkDescriptorSetLayoutCreateInfo descriptorLayout =
    		descriptorSetLayoutCreateInfo(
    			setLayoutBindings.data(),
    			static_cast<uint32_t>(setLayoutBindings.size()));
     
    	ErrorCheck(vkCreateDescriptorSetLayout(_device, &descriptorLayout, nullptr, &compute.descriptorSetLayout));
     
    	VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo =
    		pipelineLayoutCreateInfo(
    			&compute.descriptorSetLayout,
    			1);
    	VkPushConstantRange _pushConstantRange =
    		pushConstantRange(
    			VK_SHADER_STAGE_COMPUTE_BIT,
    			sizeof(computeValues),
    			0);
     
    	// Push constant ranges are part of the pipeline layout
    	pPipelineLayoutCreateInfo.pushConstantRangeCount = 1;
    	pPipelineLayoutCreateInfo.pPushConstantRanges = &_pushConstantRange;
     
    	ErrorCheck(vkCreatePipelineLayout(_device, &pPipelineLayoutCreateInfo, nullptr, &compute.pipelineLayout));

    And the push constant struct

    Code :
    	struct ComputeValues{
    		glm::vec4 cameraPos;
    		glm::vec4 frustumPlanes[6];
    	} computeValues;

    And here is where this values are updated, it works when i use uniforms, then they are being updated:
    Code :
    void Renderer::UpdateUniformBuffers(bool forced, bool breakFrustum)
    {
    ............
    	if(_camera->cameraChanged || forced)
    	{
    		if (!breakFrustum)
    		{
    			computeValues.cameraPos = glm::vec4(_camera->GetPosition(), 1);
    			frustum.update(_camera->Matrices.projection * _camera->Matrices.view);
    			memcpy(computeValues.frustumPlanes, frustum.planes.data(), sizeof(glm::vec4) * 6);
    		}
    		memcpy(_camera->uniformBuffer.mapped, &_camera->Matrices, sizeof(_camera->Matrices));
    	}
    Last edited by Harukoxd; 10-29-2017 at 04:37 PM.

  5. #5
    Senior Member
    Join Date
    Dec 2013
    Location
    Germany
    Posts
    149
    Unlike uniforms, push constant values are stored in the command buffer where you call the vkCmdPushConstants, so if you want to update your (push constant) values you need to recreate/update the command buffer.
    Last edited by Sascha Willems; 10-29-2017 at 05:07 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean