pvr: Add clear program in pvr_device.

It gets used to flush fragment work for a graphics pipeline
barrier.

Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18124>
This commit is contained in:
Karmjit Mahil 2022-07-18 13:29:32 +01:00
parent 62ef714ce4
commit 4eb0991a6f
6 changed files with 165 additions and 1 deletions

View file

@ -257,4 +257,14 @@ rogue_get_compute_max_work_group_size(const struct pvr_device_info *dev_info)
return ROGUE_MAX_INSTANCES_PER_TASK * max_tasks_per_usc;
}
/* Don't use this directly. Use the x and y define macros. */
static inline uint32_t
__rogue_get_param_vf_max(const struct pvr_device_info *dev_info)
{
return (rogue_get_render_size_max(dev_info) * 3 / 2) - 1;
}
#define rogue_get_param_vf_max_x(dev_info) __rogue_get_param_vf_max(dev_info)
#define rogue_get_param_vf_max_y(dev_info) __rogue_get_param_vf_max(dev_info)
#endif /* ROGUE_HW_UTILS_H */

View file

@ -695,6 +695,7 @@ static uint32_t pvr_pds_get_bank_based_constants(uint32_t num_backs,
* \returns Pointer to just beyond the buffer for the data - i.e the value
* of the buffer after writing its contents.
*/
/* FIXME: Implement PDS_GENERATE_CODEDATA_SEGMENTS? */
uint32_t *
pvr_pds_vertex_shader(struct pvr_pds_vertex_shader_program *restrict program,
uint32_t *restrict buffer,

View file

@ -1474,6 +1474,127 @@ static void pvr_device_finish_compute_idfwdf_state(struct pvr_device *device)
pvr_bo_free(device, device->idfwdf_state.usc);
}
static VkResult
pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
{
struct pvr_device_static_clear_state *state = &device->static_clear_state;
const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info);
const float vf_x_max = (float)rogue_get_param_vf_max_x(dev_info);
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 },
{ vf_x_max, 0.0f, 0.0f },
{ 0.0f, vf_y_max, 0.0f },
{ vf_x_max, vf_y_max, 0.0f } };
pvr_hard_code_get_passthrough_vertex_shader(dev_info,
&passthrough_vert_shader);
result = pvr_gpu_upload_usc(device,
passthrough_vert_shader->data,
passthrough_vert_shader->size,
cache_line_size,
&state->usc_vertex_shader_bo);
if (result != VK_SUCCESS)
return result;
result = pvr_gpu_upload(device,
device->heaps.general_heap,
vertices,
sizeof(vertices),
sizeof(vertices[0][0]),
&state->vertices_bo);
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_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);
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_free_verices_buffer:
pvr_bo_free(device, state->vertices_bo);
err_free_usc_shader:
pvr_bo_free(device, state->usc_vertex_shader_bo);
return result;
}
static void
pvr_device_finish_graphics_static_clear_state(struct pvr_device *device)
{
struct pvr_device_static_clear_state *state = &device->static_clear_state;
pvr_bo_free(device, state->pds.pvr_bo);
pvr_bo_free(device, state->vertices_bo);
pvr_bo_free(device, state->usc_vertex_shader_bo);
}
/* FIXME: We should be calculating the size when we upload the code in
* pvr_srv_setup_static_pixel_event_program().
*/
@ -1659,10 +1780,14 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice,
if (result != VK_SUCCESS)
goto err_pvr_free_compute_fence;
result = pvr_queues_create(device, pCreateInfo);
result = pvr_device_init_graphics_static_clear_state(device);
if (result != VK_SUCCESS)
goto err_pvr_finish_compute_idfwdf;
result = pvr_queues_create(device, pCreateInfo);
if (result != VK_SUCCESS)
goto err_pvr_finish_graphics_static_clear;
pvr_device_init_default_sampler_state(device);
if (pCreateInfo->pEnabledFeatures)
@ -1685,6 +1810,9 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice,
return VK_SUCCESS;
err_pvr_finish_graphics_static_clear:
pvr_device_finish_graphics_static_clear_state(device);
err_pvr_finish_compute_idfwdf:
pvr_device_finish_compute_idfwdf_state(device);
@ -1722,6 +1850,7 @@ void pvr_DestroyDevice(VkDevice _device,
PVR_FROM_HANDLE(pvr_device, device, _device);
pvr_queues_destroy(device);
pvr_device_finish_graphics_static_clear_state(device);
pvr_device_finish_compute_idfwdf_state(device);
pvr_bo_free(device, device->pds_compute_fence_program.pvr_bo);
pvr_bo_free(device, device->nop_program.pds.pvr_bo);

View file

@ -349,3 +349,17 @@ void pvr_hard_code_get_idfwdf_program(
*usc_shareds_out = 12U;
*usc_temps_out = 4U;
}
void pvr_hard_code_get_passthrough_vertex_shader(
const struct pvr_device_info *const dev_info,
const struct rogue_shader_binary **const program_out)
{
static const struct rogue_shader_binary shader = {
.size = 8U,
.data = { 0, 0, 0, 0, 0, 0, 0, 0 }
};
mesa_loge(
"No hard coded passthrough vertex shader. Returning empty shader.");
*program_out = &shader;
};

View file

@ -125,4 +125,8 @@ void pvr_hard_code_get_idfwdf_program(
uint32_t *usc_shareds_out,
uint32_t *usc_temps_out);
void pvr_hard_code_get_passthrough_vertex_shader(
const struct pvr_device_info *const dev_info,
const struct rogue_shader_binary **const program_out);
#endif /* PVR_HARDCODE_SHADERS_H */

View file

@ -293,6 +293,12 @@ struct pvr_device {
struct pvr_pds_upload sw_compute_barrier_pds;
} idfwdf_state;
struct pvr_device_static_clear_state {
struct pvr_bo *usc_vertex_shader_bo;
struct pvr_bo *vertices_bo;
struct pvr_pds_upload pds;
} static_clear_state;
VkPhysicalDeviceFeatures features;
};