radv: add support for VK_AMD_draw_indirect_count
authorFredrik Höglund <fredrik@kde.org>
Wed, 23 Nov 2016 22:05:01 +0000 (23:05 +0100)
committerDave Airlie <airlied@redhat.com>
Wed, 23 Nov 2016 22:19:27 +0000 (08:19 +1000)
Reviewed-by: Dave Airlie <airlied@redhat.com>
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_device.c

index 824f9d80af8e35a02c1c3677b4f929a3b00cd140..d1e4deb86c2f10fc305798f77c42c2389b124a74 100644 (file)
@@ -1849,16 +1849,25 @@ static void
 radv_emit_indirect_draw(struct radv_cmd_buffer *cmd_buffer,
                        VkBuffer _buffer,
                        VkDeviceSize offset,
+                       VkBuffer _count_buffer,
+                       VkDeviceSize count_offset,
                        uint32_t draw_count,
                        uint32_t stride,
                        bool indexed)
 {
        RADV_FROM_HANDLE(radv_buffer, buffer, _buffer);
+       RADV_FROM_HANDLE(radv_buffer, count_buffer, _count_buffer);
        struct radeon_winsys_cs *cs = cmd_buffer->cs;
        unsigned di_src_sel = indexed ? V_0287F0_DI_SRC_SEL_DMA
                                            : V_0287F0_DI_SRC_SEL_AUTO_INDEX;
        uint64_t indirect_va = cmd_buffer->device->ws->buffer_get_va(buffer->bo);
        indirect_va += offset + buffer->offset;
+       uint64_t count_va = 0;
+
+       if (count_buffer) {
+               count_va = cmd_buffer->device->ws->buffer_get_va(count_buffer->bo);
+               count_va += count_offset + count_buffer->offset;
+       }
 
        if (!draw_count)
                return;
@@ -1876,36 +1885,42 @@ radv_emit_indirect_draw(struct radv_cmd_buffer *cmd_buffer,
        radeon_emit(cs, 0);
        radeon_emit(cs, ((R_00B130_SPI_SHADER_USER_DATA_VS_0 + AC_USERDATA_VS_BASE_VERTEX * 4) - SI_SH_REG_OFFSET) >> 2);
        radeon_emit(cs, ((R_00B130_SPI_SHADER_USER_DATA_VS_0 + AC_USERDATA_VS_START_INSTANCE * 4) - SI_SH_REG_OFFSET) >> 2);
-       radeon_emit(cs, 0); /* draw_index */
+       radeon_emit(cs, S_2C3_COUNT_INDIRECT_ENABLE(!!count_va)); /* draw_index and count_indirect enable */
        radeon_emit(cs, draw_count); /* count */
-       radeon_emit(cs, 0); /* count_addr -- disabled */
-       radeon_emit(cs, 0);
+       radeon_emit(cs, count_va); /* count_addr */
+       radeon_emit(cs, count_va >> 32);
        radeon_emit(cs, stride); /* stride */
        radeon_emit(cs, di_src_sel);
 }
 
-void radv_CmdDrawIndirect(
-       VkCommandBuffer                             commandBuffer,
-       VkBuffer                                    _buffer,
-       VkDeviceSize                                offset,
-       uint32_t                                    drawCount,
-       uint32_t                                    stride)
+static void
+radv_cmd_draw_indirect_count(VkCommandBuffer                             commandBuffer,
+                             VkBuffer                                    buffer,
+                             VkDeviceSize                                offset,
+                             VkBuffer                                    countBuffer,
+                             VkDeviceSize                                countBufferOffset,
+                             uint32_t                                    maxDrawCount,
+                             uint32_t                                    stride)
 {
        RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
        radv_cmd_buffer_flush_state(cmd_buffer);
 
        unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 14);
 
-       radv_emit_indirect_draw(cmd_buffer, _buffer, offset, drawCount, stride, false);
+       radv_emit_indirect_draw(cmd_buffer, buffer, offset,
+                               countBuffer, countBufferOffset, maxDrawCount, stride, false);
 
        assert(cmd_buffer->cs->cdw <= cdw_max);
 }
 
-void radv_CmdDrawIndexedIndirect(
+static void
+radv_cmd_draw_indexed_indirect_count(
        VkCommandBuffer                             commandBuffer,
-       VkBuffer                                    _buffer,
+       VkBuffer                                    buffer,
        VkDeviceSize                                offset,
-       uint32_t                                    drawCount,
+       VkBuffer                                    countBuffer,
+       VkDeviceSize                                countBufferOffset,
+       uint32_t                                    maxDrawCount,
        uint32_t                                    stride)
 {
        RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
@@ -1930,11 +1945,62 @@ void radv_CmdDrawIndexedIndirect(
        radeon_emit(cmd_buffer->cs, PKT3(PKT3_INDEX_BUFFER_SIZE, 0, 0));
        radeon_emit(cmd_buffer->cs, index_max_size);
 
-       radv_emit_indirect_draw(cmd_buffer, _buffer, offset, drawCount, stride, true);
+       radv_emit_indirect_draw(cmd_buffer, buffer, offset,
+                               countBuffer, countBufferOffset, maxDrawCount, stride, true);
 
        assert(cmd_buffer->cs->cdw <= cdw_max);
 }
 
+void radv_CmdDrawIndirect(
+       VkCommandBuffer                             commandBuffer,
+       VkBuffer                                    buffer,
+       VkDeviceSize                                offset,
+       uint32_t                                    drawCount,
+       uint32_t                                    stride)
+{
+       radv_cmd_draw_indirect_count(commandBuffer, buffer, offset,
+                                    VK_NULL_HANDLE, 0, drawCount, stride);
+}
+
+void radv_CmdDrawIndexedIndirect(
+       VkCommandBuffer                             commandBuffer,
+       VkBuffer                                    buffer,
+       VkDeviceSize                                offset,
+       uint32_t                                    drawCount,
+       uint32_t                                    stride)
+{
+       radv_cmd_draw_indexed_indirect_count(commandBuffer, buffer, offset,
+                                            VK_NULL_HANDLE, 0, drawCount, stride);
+}
+
+void radv_CmdDrawIndirectCountAMD(
+       VkCommandBuffer                             commandBuffer,
+       VkBuffer                                    buffer,
+       VkDeviceSize                                offset,
+       VkBuffer                                    countBuffer,
+       VkDeviceSize                                countBufferOffset,
+       uint32_t                                    maxDrawCount,
+       uint32_t                                    stride)
+{
+       radv_cmd_draw_indirect_count(commandBuffer, buffer, offset,
+                                    countBuffer, countBufferOffset,
+                                    maxDrawCount, stride);
+}
+
+void radv_CmdDrawIndexedIndirectCountAMD(
+       VkCommandBuffer                             commandBuffer,
+       VkBuffer                                    buffer,
+       VkDeviceSize                                offset,
+       VkBuffer                                    countBuffer,
+       VkDeviceSize                                countBufferOffset,
+       uint32_t                                    maxDrawCount,
+       uint32_t                                    stride)
+{
+       radv_cmd_draw_indexed_indirect_count(commandBuffer, buffer, offset,
+                                            countBuffer, countBufferOffset,
+                                            maxDrawCount, stride);
+}
+
 void radv_CmdDispatch(
        VkCommandBuffer                             commandBuffer,
        uint32_t                                    x,
index 58484bdda7f0ff2ede94fd1341845a6cebf26e67..1b8864d6bc30cbd51355c9c55d6b4782ae11232e 100644 (file)
@@ -178,6 +178,10 @@ static const VkExtensionProperties device_extensions[] = {
                .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
                .specVersion = 68,
        },
+       {
+               .extensionName = VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME,
+               .specVersion = 1,
+       },
        {
                .extensionName = VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME,
                .specVersion = 1,