diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build index 7c6216a1c5a..ae15fff4649 100644 --- a/src/imagination/vulkan/meson.build +++ b/src/imagination/vulkan/meson.build @@ -38,6 +38,7 @@ pvr_files = files( 'winsys/pvr_winsys_helper.c', 'pvr_blit.c', 'pvr_bo.c', + 'pvr_clear.c', 'pvr_cmd_buffer.c', 'pvr_csb.c', 'pvr_descriptor_set.c', diff --git a/src/imagination/vulkan/pvr_clear.c b/src/imagination/vulkan/pvr_clear.c new file mode 100644 index 00000000000..8b9359725df --- /dev/null +++ b/src/imagination/vulkan/pvr_clear.c @@ -0,0 +1,121 @@ +/* + * Copyright © 2022 Imagination Technologies Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "pvr_clear.h" +#include "pvr_pds.h" +#include "pvr_private.h" +#include "vk_alloc.h" +#include "vk_log.h" + +void pvr_pds_clear_vertex_shader_program_init_base( + struct pvr_pds_vertex_shader_program *program, + const struct pvr_bo *usc_shader_bo) +{ + *program = (struct pvr_pds_vertex_shader_program){ + .num_streams = 1, + .streams = { + [0] = { + /* We'll get this from this interface's client when generating the + * data segment. This will be the address of the vertex buffer. + */ + .address = 0, + .stride = PVR_CLEAR_VERTEX_COORDINATES * sizeof(uint32_t), + .num_elements = 1, + .elements = { + [0] = { + .size = PVR_CLEAR_VERTEX_COUNT * PVR_CLEAR_VERTEX_COORDINATES, + }, + }, + }, + }, + }; + + pvr_pds_setup_doutu(&program->usc_task_control, + usc_shader_bo->vma->dev_addr.addr, + 0, + PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE), + false); +} + +VkResult pvr_pds_clear_vertex_shader_program_create_and_upload( + struct pvr_pds_vertex_shader_program *program, + struct pvr_device *device, + const struct pvr_bo *vertices_bo, + struct pvr_pds_upload *const upload_out) +{ + const struct pvr_device_info *dev_info = &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->code_size + program->data_size) * sizeof(*staging_buffer); + + staging_buffer = vk_alloc(&device->vk.alloc, + staging_buffer_size, + 8, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (!staging_buffer) { + result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + goto err_exit; + } + + pvr_pds_vertex_shader(program, + staging_buffer, + PDS_GENERATE_DATA_SEGMENT, + dev_info); + pvr_pds_vertex_shader(program, + &staging_buffer[program->data_size], + PDS_GENERATE_CODE_SEGMENT, + dev_info); + + /* FIXME: Figure out the define for alignment of 16. */ + result = pvr_gpu_upload_pds(device, + &staging_buffer[0], + program->data_size, + 16, + &staging_buffer[program->data_size], + program->code_size, + 16, + 16, + upload_out); + if (result != VK_SUCCESS) + goto err_free_staging_buffer; + + vk_free(&device->vk.alloc, staging_buffer); + return VK_SUCCESS; + +err_free_staging_buffer: + vk_free(&device->vk.alloc, staging_buffer); + +err_exit: + *upload_out = (struct pvr_pds_upload){ 0 }; + return result; +} diff --git a/src/imagination/vulkan/pvr_clear.h b/src/imagination/vulkan/pvr_clear.h new file mode 100644 index 00000000000..d040c9084ac --- /dev/null +++ b/src/imagination/vulkan/pvr_clear.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2022 Imagination Technologies Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef PVR_CLEAR_H +#define PVR_CLEAR_H + +#include + +#define PVR_CLEAR_VERTEX_COUNT 4 +#define PVR_CLEAR_VERTEX_COORDINATES 3 + +struct pvr_bo; +struct pvr_device; +struct pvr_pds_upload; +struct pvr_pds_vertex_shader_program; + +void pvr_pds_clear_vertex_shader_program_init_base( + struct pvr_pds_vertex_shader_program *program, + const struct pvr_bo *usc_shader_bo); + +VkResult pvr_pds_clear_vertex_shader_program_create_and_upload( + struct pvr_pds_vertex_shader_program *program, + struct pvr_device *device, + const struct pvr_bo *vertices_bo, + struct pvr_pds_upload *const upload_out); + +#endif /* PVR_CLEAR_H */ diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index 4415910173d..c956db30ff6 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -41,6 +41,7 @@ #include "hwdef/rogue_hw_utils.h" #include "pipe/p_defines.h" #include "pvr_bo.h" +#include "pvr_clear.h" #include "pvr_csb.h" #include "pvr_csb_enum_helpers.h" #include "pvr_debug.h" @@ -1769,8 +1770,6 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device) const float vf_y_max = (float)rogue_get_param_vf_max_y(dev_info); const struct rogue_shader_binary *passthrough_vert_shader; struct pvr_pds_vertex_shader_program pds_program; - size_t staging_buffer_size; - uint32_t *staging_buffer; VkResult result; const float vertices[4][3] = { { 0.0f, 0.0f, 0.0f }, @@ -1778,6 +1777,11 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device) { 0.0f, vf_y_max, 0.0f }, { vf_x_max, vf_y_max, 0.0f } }; + static_assert(ARRAY_SIZE(vertices) == PVR_CLEAR_VERTEX_COUNT, + "Size mismatch"); + static_assert(ARRAY_SIZE(vertices[0]) == PVR_CLEAR_VERTEX_COORDINATES, + "Size mismatch"); + if (PVR_HAS_FEATURE(dev_info, gs_rta_support)) { struct util_dynarray passthrough_rta_vert_shader; @@ -1821,63 +1825,16 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device) if (result != VK_SUCCESS) goto err_free_usc_shader; - pds_program = (struct pvr_pds_vertex_shader_program) { - .num_streams = 1, - .streams = { - [0] = { - .address = state->vertices_bo->vma->dev_addr.addr, - .stride = sizeof(vertices[0]), - .num_elements = 1, - .elements = { - [0] = { - .size = sizeof(vertices[0]), - }, - }, - }, - }, - }; + pvr_pds_clear_vertex_shader_program_init_base(&pds_program, + state->usc_vertex_shader_bo); - pvr_pds_setup_doutu(&pds_program.usc_task_control, - state->usc_vertex_shader_bo->vma->dev_addr.addr, - 0, - PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE), - false); - - pvr_pds_vertex_shader(&pds_program, NULL, PDS_GENERATE_SIZES, dev_info); - - staging_buffer_size = - (pds_program.code_size + pds_program.data_size) * sizeof(*staging_buffer); - - staging_buffer = vk_alloc(&device->vk.alloc, - staging_buffer_size, - 8, - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - if (!staging_buffer) - goto err_free_verices_buffer; - - pvr_pds_vertex_shader(&pds_program, - staging_buffer, - PDS_GENERATE_DATA_SEGMENT, - dev_info); - pvr_pds_vertex_shader(&pds_program, - &staging_buffer[pds_program.data_size], - PDS_GENERATE_CODE_SEGMENT, - dev_info); - - /* FIXME: Figure out the define for alignment of 16. */ - result = pvr_gpu_upload_pds(device, - &staging_buffer[0], - pds_program.data_size, - 16, - &staging_buffer[pds_program.data_size], - pds_program.code_size, - 16, - 16, - &state->pds); + result = + pvr_pds_clear_vertex_shader_program_create_and_upload(&pds_program, + device, + state->vertices_bo, + &state->pds); if (result != VK_SUCCESS) - goto err_free_staging_buffer; - - vk_free(&device->vk.alloc, staging_buffer); + goto err_free_verices_buffer; pvr_device_setup_graphics_static_clear_ppp_base(&state->ppp_base); pvr_device_setup_graphics_static_clear_ppp_templates(state->ppp_templates); @@ -1908,9 +1865,6 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device) return VK_SUCCESS; -err_free_staging_buffer: - vk_free(&device->vk.alloc, staging_buffer); - err_free_verices_buffer: pvr_bo_free(device, state->vertices_bo);