Synchronization between drawcalls in Vulkan

≡放荡痞女 提交于 2020-01-30 09:13:45

问题


As far as I understand, if I have a drawcall that in some way uses the results of any previous drawcall or writes to the same render target (framebuffer), then I need to make sure that the later drawcall sees the memory effects of all previous drawcalls.

But what about, when I am rendering a scene with a bunch of objects, each such object is one drawcall and all these drawcalls write to the same framebuffer.

Do I need to issue a memory barrier after every drawcall ?

For example Sascha Willem's pbrbasic example has this code (a bit simplified) and I do not see any pipelines barriers there:

VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));

vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);

VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0);
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);

VkDeviceSize offsets[1] = { 0 };

vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL);
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &models.objects[models.objectIndex].vertices.buffer, offsets);
vkCmdBindIndexBuffer(drawCmdBuffers[i], models.objects[models.objectIndex].indices.buffer, 0, VK_INDEX_TYPE_UINT32);

Material mat = materials[materialIndex];

for (uint32_t y = 0; y < GRID_DIM; y++) {
    for (uint32_t x = 0; x < GRID_DIM; x++) {
        glm::vec3 pos = glm::vec3(float(x - (GRID_DIM / 2.0f)) * 2.5f, 0.0f, float(y - (GRID_DIM / 2.0f)) * 2.5f);
        vkCmdPushConstants(drawCmdBuffers[i], pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::vec3), &pos);
        mat.params.metallic = glm::clamp((float)x / (float)(GRID_DIM - 1), 0.1f, 1.0f);
        mat.params.roughness = glm::clamp((float)y / (float)(GRID_DIM - 1), 0.05f, 1.0f);
        vkCmdPushConstants(drawCmdBuffers[i], pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(glm::vec3), sizeof(Material::PushBlock), &mat);
        vkCmdDrawIndexed(drawCmdBuffers[i], models.objects[models.objectIndex].indexCount, 1, 0, 0, 0);
    }
}

drawUI(drawCmdBuffers[i]);

vkCmdEndRenderPass(drawCmdBuffers[i]);

VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));

Are there any guarantees that drawcalls logically following after will see the memory effects of drawcalls logically before them ?

So the question is, when do I need to synchronize between different drawcalls ?


回答1:


uses the results of any previous drawcall or writes to the same render target

Those are not the same thing. The side-effects of a rendering operation (stuff you modify via image load/store or SSBOs) and stuff written to the framebuffer have very different needs as far as synchronization is concerned.

The fixed function operations that lead to the writing of a value to the framebuffer (scissor test, depth test, blending, etc) are governed by rasterization order: they must happen atomically and in that particular order, within a given primitive and for a particular sample potentially being written to the frame buffer. And the execution of such operations must also respect primitive order: the order of primitives generated by drawing commands, but also the order of primitives within a drawing command.

So as far as rendering is concerned, draw calls will respect the results of previous draw calls, within the same subpass (between subpasses is governed by explicit subpass dependencies). You don't need to do anything special to make blending work. If you have two overlapping triangles, with one happening after the other by primitive order, the second draw's blending will use the results of the first draw. It just works.

Any other writing by your shader requires explicit synchronization.



来源:https://stackoverflow.com/questions/56849788/synchronization-between-drawcalls-in-vulkan

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!