From a70b724519303bd2f7298b193fcd4b55c8c1d86f Mon Sep 17 00:00:00 2001 From: Karmjit Mahil Date: Wed, 21 Sep 2022 14:40:23 +0100 Subject: [PATCH] pvr: Add clear rta vert shader pds program. The rta program will be used in following commits adding support for vkCmdClearAttachments(). Signed-off-by: Karmjit Mahil Reviewed-by: Frank Binns Part-of: --- src/imagination/vulkan/pvr_clear.c | 133 ++++++++++++++++++++++++++++++++ src/imagination/vulkan/pvr_clear.h | 34 ++++++++ src/imagination/vulkan/pvr_cmd_buffer.c | 19 +++-- src/imagination/vulkan/pvr_private.h | 9 +++ 4 files changed, 185 insertions(+), 10 deletions(-) diff --git a/src/imagination/vulkan/pvr_clear.c b/src/imagination/vulkan/pvr_clear.c index 8b93597..e67fd83 100644 --- a/src/imagination/vulkan/pvr_clear.c +++ b/src/imagination/vulkan/pvr_clear.c @@ -119,3 +119,136 @@ err_exit: *upload_out = (struct pvr_pds_upload){ 0 }; return result; } + +VkResult pvr_pds_clear_vertex_shader_program_create_and_upload_data( + struct pvr_pds_vertex_shader_program *program, + struct pvr_cmd_buffer *cmd_buffer, + struct pvr_bo *vertices_bo, + struct pvr_pds_upload *const pds_upload_out) +{ + struct pvr_device_info *dev_info = &cmd_buffer->device->pdevice->dev_info; + uint32_t staging_buffer_size; + uint32_t *staging_buffer; + VkResult result; + + program->streams[0].address = vertices_bo->vma->dev_addr.addr; + + pvr_pds_vertex_shader(program, NULL, PDS_GENERATE_SIZES, dev_info); + + staging_buffer_size = program->data_size * sizeof(*staging_buffer); + + staging_buffer = vk_alloc(&cmd_buffer->device->vk.alloc, + staging_buffer_size, + 8, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (!staging_buffer) { + *pds_upload_out = (struct pvr_pds_upload){ 0 }; + + result = vk_error(cmd_buffer, VK_ERROR_OUT_OF_HOST_MEMORY); + cmd_buffer->state.status = result; + return result; + } + + pvr_pds_vertex_shader(program, + staging_buffer, + PDS_GENERATE_DATA_SEGMENT, + dev_info); + + result = pvr_cmd_buffer_upload_pds(cmd_buffer, + staging_buffer, + program->data_size, + 4, + NULL, + 0, + 0, + 4, + pds_upload_out); + if (result != VK_SUCCESS) { + vk_free(&cmd_buffer->device->vk.alloc, staging_buffer); + + *pds_upload_out = (struct pvr_pds_upload){ 0 }; + + cmd_buffer->state.status = result; + return result; + } + + vk_free(&cmd_buffer->device->vk.alloc, staging_buffer); + + return VK_SUCCESS; +} + +void pvr_pds_clear_rta_vertex_shader_program_init_base( + struct pvr_pds_vertex_shader_program *program, + const struct pvr_bo *usc_shader_bo) +{ + pvr_pds_clear_vertex_shader_program_init_base(program, usc_shader_bo); + + /* We'll set the render target index to be the instance id + base array + * layer. Since the base array layer can change in between clear rects, we + * don't set it here and ask for it when generating the code and data + * section. + */ + /* This is 3 because the instance id register will follow the xyz coordinate + * registers in the register file. + * TODO: Maybe we want this to be hooked up to the compiler? + */ + program->iterate_instance_id = true; + program->instance_id_register = 3; +} + +VkResult pvr_pds_clear_rta_vertex_shader_program_create_and_upload_code( + struct pvr_pds_vertex_shader_program *program, + struct pvr_cmd_buffer *cmd_buffer, + uint32_t base_array_layer, + struct pvr_pds_upload *const pds_upload_out) +{ + struct pvr_device_info *dev_info = &cmd_buffer->device->pdevice->dev_info; + uint32_t staging_buffer_size; + uint32_t *staging_buffer; + VkResult result; + + program->instance_id_modifier = base_array_layer; + + pvr_pds_vertex_shader(program, NULL, PDS_GENERATE_SIZES, dev_info); + + staging_buffer_size = program->code_size * sizeof(*staging_buffer); + + staging_buffer = vk_alloc(&cmd_buffer->device->vk.alloc, + staging_buffer_size, + 8, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (!staging_buffer) { + *pds_upload_out = (struct pvr_pds_upload){ 0 }; + + result = vk_error(cmd_buffer, VK_ERROR_OUT_OF_HOST_MEMORY); + cmd_buffer->state.status = result; + return result; + } + + pvr_pds_vertex_shader(program, + staging_buffer, + PDS_GENERATE_CODE_SEGMENT, + dev_info); + + result = pvr_cmd_buffer_upload_pds(cmd_buffer, + NULL, + 0, + 0, + staging_buffer, + program->code_size, + 4, + 4, + pds_upload_out); + if (result != VK_SUCCESS) { + vk_free(&cmd_buffer->device->vk.alloc, staging_buffer); + + *pds_upload_out = (struct pvr_pds_upload){ 0 }; + + cmd_buffer->state.status = result; + return result; + } + + vk_free(&cmd_buffer->device->vk.alloc, staging_buffer); + + return VK_SUCCESS; +} diff --git a/src/imagination/vulkan/pvr_clear.h b/src/imagination/vulkan/pvr_clear.h index d040c90..4ccc26a 100644 --- a/src/imagination/vulkan/pvr_clear.h +++ b/src/imagination/vulkan/pvr_clear.h @@ -24,12 +24,14 @@ #ifndef PVR_CLEAR_H #define PVR_CLEAR_H +#include #include #define PVR_CLEAR_VERTEX_COUNT 4 #define PVR_CLEAR_VERTEX_COORDINATES 3 struct pvr_bo; +struct pvr_cmd_buffer; struct pvr_device; struct pvr_pds_upload; struct pvr_pds_vertex_shader_program; @@ -43,5 +45,37 @@ VkResult pvr_pds_clear_vertex_shader_program_create_and_upload( struct pvr_device *device, const struct pvr_bo *vertices_bo, struct pvr_pds_upload *const upload_out); +VkResult pvr_pds_clear_vertex_shader_program_create_and_upload_data( + struct pvr_pds_vertex_shader_program *program, + struct pvr_cmd_buffer *cmd_buffer, + struct pvr_bo *vertices_bo, + struct pvr_pds_upload *const pds_upload_out); + +void pvr_pds_clear_rta_vertex_shader_program_init_base( + struct pvr_pds_vertex_shader_program *program, + const struct pvr_bo *usc_shader_bo); + +/* Each code and data upload function clears the other's fields in the + * pds_upload_out. So when uploading the code, the data fields will be 0. + */ +VkResult pvr_pds_clear_rta_vertex_shader_program_create_and_upload_code( + struct pvr_pds_vertex_shader_program *program, + struct pvr_cmd_buffer *cmd_buffer, + uint32_t base_array_layer, + struct pvr_pds_upload *const pds_upload_out); + +static inline VkResult +pvr_pds_clear_rta_vertex_shader_program_create_and_upload_data( + struct pvr_pds_vertex_shader_program *program, + struct pvr_cmd_buffer *cmd_buffer, + struct pvr_bo *vertices_bo, + struct pvr_pds_upload *const pds_upload_out) +{ + return pvr_pds_clear_vertex_shader_program_create_and_upload_data( + program, + cmd_buffer, + vertices_bo, + pds_upload_out); +} #endif /* PVR_CLEAR_H */ diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c b/src/imagination/vulkan/pvr_cmd_buffer.c index 175145b..c9ef4d1 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -419,16 +419,15 @@ pvr_cmd_buffer_upload_usc(struct pvr_cmd_buffer *const cmd_buffer, return VK_SUCCESS; } -static VkResult -pvr_cmd_buffer_upload_pds(struct pvr_cmd_buffer *const cmd_buffer, - const uint32_t *data, - uint32_t data_size_dwords, - uint32_t data_alignment, - const uint32_t *code, - uint32_t code_size_dwords, - uint32_t code_alignment, - uint64_t min_alignment, - struct pvr_pds_upload *const pds_upload_out) +VkResult pvr_cmd_buffer_upload_pds(struct pvr_cmd_buffer *const cmd_buffer, + const uint32_t *data, + uint32_t data_size_dwords, + uint32_t data_alignment, + const uint32_t *code, + uint32_t code_size_dwords, + uint32_t code_alignment, + uint64_t min_alignment, + struct pvr_pds_upload *const pds_upload_out) { struct pvr_device *const device = cmd_buffer->device; VkResult result; diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 157e528..8fcafdc 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -1505,6 +1505,15 @@ VkResult pvr_cmd_buffer_alloc_mem(struct pvr_cmd_buffer *cmd_buffer, uint64_t size, uint32_t flags, struct pvr_bo **const pvr_bo_out); +VkResult pvr_cmd_buffer_upload_pds(struct pvr_cmd_buffer *const cmd_buffer, + const uint32_t *data, + uint32_t data_size_dwords, + uint32_t data_alignment, + const uint32_t *code, + uint32_t code_size_dwords, + uint32_t code_alignment, + uint64_t min_alignment, + struct pvr_pds_upload *const pds_upload_out); void pvr_calculate_vertex_cam_size(const struct pvr_device_info *dev_info, const uint32_t vs_output_size, -- 2.7.4