pvr: split out driver specific framebuffer data

Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38744>
This commit is contained in:
Luigi Santivetti
2025-09-18 10:50:57 +01:00
committed by Marge Bot
parent 0bf47f0435
commit bdfc24031b
6 changed files with 308 additions and 186 deletions
+79 -68
View File
@@ -369,8 +369,8 @@ static VkResult
pvr_cmd_buffer_emit_ppp_state(const struct pvr_cmd_buffer *const cmd_buffer,
struct pvr_csb *const csb)
{
const struct pvr_framebuffer *const framebuffer =
cmd_buffer->state.render_pass_info.framebuffer;
const struct pvr_render_state *const rstate =
cmd_buffer->state.render_pass_info.rstate;
assert(csb->stream_type == PVR_CMD_STREAM_TYPE_GRAPHICS ||
csb->stream_type == PVR_CMD_STREAM_TYPE_GRAPHICS_DEFERRED);
@@ -378,12 +378,12 @@ pvr_cmd_buffer_emit_ppp_state(const struct pvr_cmd_buffer *const cmd_buffer,
pvr_csb_set_relocation_mark(csb);
pvr_csb_emit (csb, VDMCTRL_PPP_STATE0, state0) {
state0.addrmsb = framebuffer->ppp_state_bo->dev_addr;
state0.word_count = framebuffer->ppp_state_size;
state0.addrmsb = rstate->ppp_state_bo->dev_addr;
state0.word_count = rstate->ppp_state_size;
}
pvr_csb_emit (csb, VDMCTRL_PPP_STATE1, state1) {
state1.addrlsb = framebuffer->ppp_state_bo->dev_addr;
state1.addrlsb = rstate->ppp_state_bo->dev_addr;
}
pvr_csb_clear_relocation_mark(csb);
@@ -1060,7 +1060,7 @@ static inline uint32_t pvr_stride_from_pitch(uint32_t pitch, VkFormat vk_format)
static void pvr_setup_pbe_state(
const struct pvr_device_info *dev_info,
const struct pvr_framebuffer *framebuffer,
const struct pvr_render_state *rstate,
uint32_t mrt_index,
const struct usc_mrt_resource *mrt_resource,
const struct pvr_image_view *const iview,
@@ -1170,10 +1170,10 @@ static void pvr_setup_pbe_state(
render_params.min_x_clip = MAX2(0, render_area->offset.x);
render_params.min_y_clip = MAX2(0, render_area->offset.y);
render_params.max_x_clip = MIN2(
framebuffer->width - 1,
rstate->width - 1,
PVR_DEC_IF_NOT_ZERO(render_area->offset.x + render_area->extent.width));
render_params.max_y_clip = MIN2(
framebuffer->height - 1,
rstate->height - 1,
PVR_DEC_IF_NOT_ZERO(render_area->offset.y + render_area->extent.height));
#undef PVR_DEC_IF_NOT_ZERO
@@ -1190,12 +1190,9 @@ static void pvr_setup_pbe_state(
}
static struct pvr_render_target *
pvr_get_render_target(const struct pvr_render_pass *pass,
const struct pvr_framebuffer *framebuffer,
uint32_t idx)
pvr_get_render_target(const struct pvr_renderpass_hwsetup_render *hw_render,
const struct pvr_render_state *rstate)
{
const struct pvr_renderpass_hwsetup_render *hw_render =
&pass->hw_setup->renders[idx];
uint32_t rt_idx = 0;
switch (hw_render->sample_count) {
@@ -1211,16 +1208,13 @@ pvr_get_render_target(const struct pvr_render_pass *pass,
break;
}
return &framebuffer->render_targets[rt_idx];
return &rstate->render_targets[rt_idx];
}
static uint32_t
pvr_pass_get_pixel_output_width(const struct pvr_render_pass *pass,
uint32_t idx,
const struct pvr_device_info *dev_info)
pvr_get_pixel_output_width(const struct pvr_renderpass_hwsetup_render *hw_render,
const struct pvr_device_info *dev_info)
{
const struct pvr_renderpass_hwsetup_render *hw_render =
&pass->hw_setup->renders[idx];
/* Default value based on the maximum value found in all existing cores. The
* maximum is used as this is being treated as a lower bound, making it a
* "safer" choice than the minimum value found in all existing cores.
@@ -1484,8 +1478,8 @@ pvr_setup_emit_state(const struct pvr_device_info *dev_info,
resource_type <= USC_MRT_RESOURCE_TYPE_MEMORY;
resource_type++) {
for (uint32_t i = 0; i < hw_render->eot_surface_count; i++) {
const struct pvr_framebuffer *framebuffer =
render_pass_info->framebuffer;
const struct pvr_render_state *rstate =
render_pass_info->rstate;
const struct pvr_renderpass_hwsetup_eot_surface *surface =
&hw_render->eot_surfaces[i];
const struct pvr_image_view *iview =
@@ -1522,7 +1516,7 @@ pvr_setup_emit_state(const struct pvr_device_info *dev_info,
: ~0;
pvr_setup_pbe_state(dev_info,
framebuffer,
rstate,
emit_state->emit_count,
mrt_resource,
iview,
@@ -1551,6 +1545,13 @@ pvr_is_render_area_tile_aligned(const struct pvr_cmd_buffer *cmd_buffer,
render_area->extent.width == iview->vk.extent.width;
}
static inline struct pvr_renderpass_hwsetup_render *
pvr_pass_info_get_hw_render(const struct pvr_render_pass_info *render_pass_info,
uint32_t idx)
{
return &render_pass_info->pass->hw_setup->renders[idx];
}
static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
struct pvr_cmd_buffer *cmd_buffer,
struct pvr_sub_cmd_gfx *sub_cmd)
@@ -1565,13 +1566,13 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
struct pvr_render_pass_info *render_pass_info =
&cmd_buffer->state.render_pass_info;
const struct pvr_renderpass_hwsetup_render *hw_render =
&render_pass_info->pass->hw_setup->renders[sub_cmd->hw_render_idx];
pvr_pass_info_get_hw_render(render_pass_info, sub_cmd->hw_render_idx);
struct pvr_render_job *job = &sub_cmd->job;
struct pvr_framebuffer *framebuffer = render_pass_info->framebuffer;
struct pvr_render_state *rstate = render_pass_info->rstate;
struct pvr_spm_bgobj_state *spm_bgobj_state =
&framebuffer->spm_bgobj_state_per_render[sub_cmd->hw_render_idx];
&rstate->spm_bgobj_state_per_render[sub_cmd->hw_render_idx];
struct pvr_spm_eot_state *spm_eot_state =
&framebuffer->spm_eot_state_per_render[sub_cmd->hw_render_idx];
&rstate->spm_eot_state_per_render[sub_cmd->hw_render_idx];
struct pvr_render_target *render_target;
VkResult result;
@@ -1622,9 +1623,7 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
&emit_state);
unsigned pixel_output_width =
pvr_pass_get_pixel_output_width(render_pass_info->pass,
sub_cmd->hw_render_idx,
dev_info);
pvr_get_pixel_output_width(hw_render, dev_info);
result = pvr_sub_cmd_gfx_per_job_fragment_programs_create_and_upload(
cmd_buffer,
@@ -1703,9 +1702,7 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
spm_eot_state->pixel_event_program_data_offset;
}
render_target = pvr_get_render_target(render_pass_info->pass,
framebuffer,
sub_cmd->hw_render_idx);
render_target = pvr_get_render_target(hw_render, render_pass_info->rstate);
job->view_state.rt_datasets = &render_target->rt_dataset[0];
job->ctrl_stream_addr = pvr_csb_get_start_address(&sub_cmd->control_stream);
@@ -1721,9 +1718,7 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
job->scissor_table_addr = PVR_DEV_ADDR_INVALID;
job->pixel_output_width =
pvr_pass_get_pixel_output_width(render_pass_info->pass,
sub_cmd->hw_render_idx,
dev_info);
pvr_get_pixel_output_width(hw_render, dev_info);
/* Setup depth/stencil job information. */
if (hw_render->ds_attach_idx != VK_ATTACHMENT_UNUSED) {
@@ -2603,9 +2598,8 @@ static inline uint32_t
pvr_render_pass_info_get_view_mask(const struct pvr_render_pass_info *rp_info)
{
const uint32_t hw_render_idx = rp_info->current_hw_subpass;
const struct pvr_render_pass *pass = rp_info->pass;
const struct pvr_renderpass_hwsetup_render *hw_render =
&pass->hw_setup->renders[hw_render_idx];
pvr_pass_info_get_hw_render(rp_info, hw_render_idx);
return hw_render->view_mask;
}
@@ -2660,7 +2654,7 @@ VkResult pvr_cmd_buffer_start_sub_cmd(struct pvr_cmd_buffer *cmd_buffer,
isp_max_tiles_in_flight,
1);
sub_cmd->gfx.hw_render_idx = state->render_pass_info.current_hw_subpass;
sub_cmd->gfx.framebuffer = state->render_pass_info.framebuffer;
sub_cmd->gfx.rstate = state->render_pass_info.rstate;
sub_cmd->gfx.empty_cmd = true;
sub_cmd->gfx.view_mask =
pvr_render_pass_info_get_view_mask(&state->render_pass_info);
@@ -3092,13 +3086,13 @@ static VkResult pvr_cmd_buffer_attachments_setup(
static inline VkResult pvr_render_targets_datasets_create(
struct pvr_device *device,
struct pvr_framebuffer *framebuffer,
struct pvr_render_state *rstate,
const struct pvr_renderpass_hwsetup_render *hw_render,
struct pvr_render_target *render_target)
{
const struct pvr_device_info *const dev_info = &device->pdevice->dev_info;
const uint32_t layers =
PVR_HAS_FEATURE(dev_info, gs_rta_support) ? framebuffer->layers : 1;
PVR_HAS_FEATURE(dev_info, gs_rta_support) ? rstate->layers : 1;
pthread_mutex_lock(&render_target->mutex);
@@ -3110,8 +3104,8 @@ static inline VkResult pvr_render_targets_datasets_create(
continue;
result = pvr_render_target_dataset_create(device,
framebuffer->width,
framebuffer->height,
rstate->width,
rstate->height,
hw_render->sample_count,
layers,
&rt_dataset);
@@ -3130,21 +3124,33 @@ static inline VkResult pvr_render_targets_datasets_create(
return VK_SUCCESS;
}
static VkResult pvr_render_targets_init(struct pvr_device *device,
struct pvr_render_pass *pass,
struct pvr_framebuffer *framebuffer)
static VkResult
pvr_render_targets_init(struct pvr_device *device,
struct pvr_render_state *rstate,
const struct pvr_renderpass_hwsetup_render *hw_render)
{
struct pvr_render_target *render_target =
pvr_get_render_target(hw_render, rstate);
return pvr_render_targets_datasets_create(device,
rstate,
hw_render,
render_target);
}
static VkResult
pvr_render_targets_init_for_render(struct pvr_device *device,
struct pvr_render_pass *pass,
struct pvr_framebuffer *framebuffer)
{
for (uint32_t i = 0; i < pass->hw_setup->render_count; i++) {
struct pvr_render_target *render_target =
pvr_get_render_target(pass, framebuffer, i);
const struct pvr_renderpass_hwsetup_render *hw_render =
&pass->hw_setup->renders[i];
VkResult result;
result = pvr_render_targets_datasets_create(device,
framebuffer,
hw_render,
render_target);
result = pvr_render_targets_init(device,
framebuffer->rstate,
hw_render);
if (result != VK_SUCCESS)
return result;
}
@@ -3163,7 +3169,7 @@ pvr_get_hw_subpass(const struct pvr_render_pass *pass, const uint32_t subpass)
static void pvr_perform_start_of_render_attachment_clear(
struct pvr_cmd_buffer *cmd_buffer,
const struct pvr_framebuffer *framebuffer,
uint32_t layers,
uint32_t index,
bool is_depth_stencil,
uint32_t *index_list_clear_mask)
@@ -3173,9 +3179,11 @@ static void pvr_perform_start_of_render_attachment_clear(
VK_IMAGE_ASPECT_COLOR_BIT;
struct pvr_render_pass_info *info = &cmd_buffer->state.render_pass_info;
const struct pvr_render_pass *pass = info->pass;
const struct pvr_renderpass_hwsetup *hw_setup = pass->hw_setup;
const struct pvr_renderpass_hwsetup *hw_setup = pass ? pass->hw_setup : NULL;
const uint32_t hw_render_idx = hw_setup ?
hw_setup->subpass_map[info->subpass_idx].render : 0;
const struct pvr_renderpass_hwsetup_render *hw_render =
&hw_setup->renders[hw_setup->subpass_map[info->subpass_idx].render];
pvr_pass_info_get_hw_render(info, hw_render_idx);
VkImageAspectFlags image_aspect;
struct pvr_image_view *iview;
uint32_t view_idx;
@@ -3217,8 +3225,7 @@ static void pvr_perform_start_of_render_attachment_clear(
/* If this is single-layer fullscreen, we already do the clears in
* pvr_sub_cmd_gfx_job_init().
*/
if (pvr_is_render_area_tile_aligned(cmd_buffer, iview) &&
framebuffer->layers == 1) {
if (pvr_is_render_area_tile_aligned(cmd_buffer, iview) && layers == 1) {
return;
}
@@ -3244,7 +3251,13 @@ static void pvr_perform_start_of_render_attachment_clear(
VkClearRect rect = {
.rect = info->render_area,
.baseArrayLayer = 0,
.layerCount = info->framebuffer->layers,
/* TODO:
*
* Verify where layers should come from, info->framebuffer
* vs layers (function argument). Aren't they the same?
* If they are, drop the argument altogether.
*/
.layerCount = info->rstate->layers,
};
assert(view_idx < info->clear_value_count);
@@ -3259,11 +3272,9 @@ static void
pvr_perform_start_of_render_clears(struct pvr_cmd_buffer *cmd_buffer)
{
struct pvr_render_pass_info *info = &cmd_buffer->state.render_pass_info;
const struct pvr_framebuffer *framebuffer = info->framebuffer;
const struct pvr_render_pass *pass = info->pass;
const struct pvr_renderpass_hwsetup *hw_setup = pass->hw_setup;
const struct pvr_renderpass_hwsetup *hw_setup = info->pass->hw_setup;
const struct pvr_renderpass_hwsetup_render *hw_render =
&hw_setup->renders[hw_setup->subpass_map[info->subpass_idx].render];
pvr_pass_info_get_hw_render(info, hw_setup->subpass_map[info->subpass_idx].render);
/* Mask of attachment clears using index lists instead of background object
* to clear.
@@ -3272,7 +3283,7 @@ pvr_perform_start_of_render_clears(struct pvr_cmd_buffer *cmd_buffer)
for (uint32_t i = 0; i < hw_render->color_init_count; i++) {
pvr_perform_start_of_render_attachment_clear(cmd_buffer,
framebuffer,
info->rstate->layers,
i,
false,
&index_list_clear_mask);
@@ -3294,7 +3305,7 @@ pvr_perform_start_of_render_clears(struct pvr_cmd_buffer *cmd_buffer)
uint32_t ds_index_list = 0;
pvr_perform_start_of_render_attachment_clear(cmd_buffer,
framebuffer,
info->rstate->layers,
0,
true,
&ds_index_list);
@@ -3304,9 +3315,8 @@ pvr_perform_start_of_render_clears(struct pvr_cmd_buffer *cmd_buffer)
static void pvr_stash_depth_format(struct pvr_cmd_buffer_state *state,
struct pvr_sub_cmd_gfx *const sub_cmd)
{
const struct pvr_render_pass *pass = state->render_pass_info.pass;
const struct pvr_renderpass_hwsetup_render *hw_render =
&pass->hw_setup->renders[sub_cmd->hw_render_idx];
pvr_pass_info_get_hw_render(&state->render_pass_info, sub_cmd->hw_render_idx);
if (hw_render->ds_attach_idx != VK_ATTACHMENT_UNUSED) {
struct pvr_image_view **iviews = state->render_pass_info.attachments;
@@ -3563,6 +3573,7 @@ void pvr_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
* look at cmd_buffer_begin_subpass() for example. */
state->render_pass_info.pass = pass;
state->render_pass_info.framebuffer = framebuffer;
state->render_pass_info.rstate = framebuffer->rstate;
state->render_pass_info.subpass_idx = 0;
state->render_pass_info.render_area = pRenderPassBeginInfo->renderArea;
state->render_pass_info.current_hw_subpass = 0;
@@ -3578,7 +3589,7 @@ void pvr_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
if (result != VK_SUCCESS)
return;
result = pvr_render_targets_init(cmd_buffer->device, pass, framebuffer);
result = pvr_render_targets_init_for_render(cmd_buffer->device, pass, framebuffer);
if (result != VK_SUCCESS) {
pvr_cmd_buffer_set_error_unwarned(cmd_buffer, result);
return;
@@ -7295,7 +7306,7 @@ pvr_resolve_unemitted_resolve_attachments(struct pvr_cmd_buffer *cmd_buffer,
{
struct pvr_cmd_buffer_state *state = &cmd_buffer->state;
const struct pvr_renderpass_hwsetup_render *hw_render =
&state->render_pass_info.pass->hw_setup->renders[info->current_hw_subpass];
pvr_pass_info_get_hw_render(&state->render_pass_info, info->current_hw_subpass);
for (uint32_t i = 0U; i < hw_render->eot_surface_count; i++) {
const struct pvr_renderpass_hwsetup_eot_surface *surface =
@@ -8054,7 +8065,7 @@ static bool pvr_is_stencil_store_load_needed(
return false;
hw_render_idx = state->current_sub_cmd->gfx.hw_render_idx;
hw_render = &pass->hw_setup->renders[hw_render_idx];
hw_render = pvr_pass_info_get_hw_render(&state->render_pass_info, hw_render_idx);
if (hw_render->ds_attach_idx == VK_ATTACHMENT_UNUSED)
return false;
+5 -2
View File
@@ -119,7 +119,7 @@ struct pvr_transfer_cmd {
};
struct pvr_sub_cmd_gfx {
const struct pvr_framebuffer *framebuffer;
const struct pvr_render_state *rstate;
struct pvr_render_job job;
@@ -272,6 +272,9 @@ struct pvr_render_pass_info {
const struct pvr_render_pass *pass;
struct pvr_framebuffer *framebuffer;
struct pvr_render_state *rstate;
uint32_t attachment_count;
struct pvr_image_view **attachments;
uint32_t subpass_idx;
@@ -536,7 +539,7 @@ pvr_cmd_buffer_set_error_unwarned(struct pvr_cmd_buffer *cmd_buffer,
static inline bool pvr_sub_cmd_gfx_requires_split_submit(
const struct pvr_sub_cmd_gfx *const sub_cmd)
{
return sub_cmd->job.run_frag && sub_cmd->framebuffer->layers > 1;
return sub_cmd->job.run_frag && sub_cmd->rstate->layers > 1;
}
#define PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer) \
+154 -91
View File
@@ -1827,8 +1827,8 @@ VkResult pvr_gpu_upload_pds(struct pvr_device *device,
}
static VkResult
pvr_framebuffer_create_ppp_state(struct pvr_device *device,
struct pvr_framebuffer *framebuffer)
pvr_render_state_create_ppp_state(struct pvr_device *device,
struct pvr_render_state *rstate)
{
const uint32_t cache_line_size =
pvr_get_slc_cache_line_size(&device->pdevice->dev_info);
@@ -1842,12 +1842,12 @@ pvr_framebuffer_create_ppp_state(struct pvr_device *device,
pvr_csb_pack (&ppp_state[1], TA_STATE_TERMINATE0, term0) {
term0.clip_right =
DIV_ROUND_UP(
framebuffer->width,
rstate->width,
ROGUE_TA_STATE_TERMINATE0_CLIP_RIGHT_BLOCK_SIZE_IN_PIXELS) -
1;
term0.clip_bottom =
DIV_ROUND_UP(
framebuffer->height,
rstate->height,
ROGUE_TA_STATE_TERMINATE0_CLIP_BOTTOM_BLOCK_SIZE_IN_PIXELS) -
1;
}
@@ -1862,12 +1862,12 @@ pvr_framebuffer_create_ppp_state(struct pvr_device *device,
ppp_state,
sizeof(ppp_state),
cache_line_size,
&framebuffer->ppp_state_bo);
&rstate->ppp_state_bo);
if (result != VK_SUCCESS)
return result;
/* Calculate the size of PPP state in dwords. */
framebuffer->ppp_state_size = sizeof(ppp_state) / sizeof(uint32_t);
rstate->ppp_state_size = sizeof(ppp_state) / sizeof(uint32_t);
return VK_SUCCESS;
}
@@ -1900,37 +1900,56 @@ static void pvr_render_targets_fini(struct pvr_render_target *render_targets,
}
}
VkResult pvr_CreateFramebuffer(VkDevice _device,
const VkFramebufferCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkFramebuffer *pFramebuffer)
static inline uint64_t
pvr_render_pass_get_scratch_buffer_size(struct pvr_device *device,
const struct pvr_render_pass *pass,
const struct pvr_render_state *rstate)
{
return pvr_spm_scratch_buffer_calc_required_size(
pass->hw_setup->renders,
pass->hw_setup->render_count,
pass->max_sample_count,
rstate->width,
rstate->height);
}
void pvr_render_state_cleanup(struct pvr_device *device,
const struct pvr_render_state *rstate)
{
if (!rstate)
return;
for (uint32_t i = 0; i < rstate->render_count; i++) {
pvr_spm_finish_bgobj_state(device,
&rstate->spm_bgobj_state_per_render[i]);
pvr_spm_finish_eot_state(device,
&rstate->spm_eot_state_per_render[i]);
}
pvr_spm_scratch_buffer_release(device, rstate->scratch_buffer);
pvr_render_targets_fini(rstate->render_targets,
rstate->render_targets_count);
pvr_bo_suballoc_free(rstate->ppp_state_bo);
}
VkResult pvr_render_state_setup(
struct pvr_device *device,
const VkAllocationCallbacks *pAllocator,
struct pvr_render_state *rstate,
uint32_t render_count,
const struct pvr_renderpass_hwsetup_render *renders)
{
VK_FROM_HANDLE(pvr_render_pass, pass, pCreateInfo->renderPass);
VK_FROM_HANDLE(pvr_device, device, _device);
const VkFramebufferAttachmentsCreateInfoKHR *pImageless;
struct pvr_spm_bgobj_state *spm_bgobj_state_per_render;
struct pvr_spm_eot_state *spm_eot_state_per_render;
struct pvr_render_target *render_targets;
struct pvr_framebuffer *framebuffer;
struct pvr_image_view **attachments;
uint32_t render_targets_count;
uint64_t scratch_buffer_size;
VkResult result;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
pImageless = vk_find_struct_const(pCreateInfo->pNext,
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
render_targets_count =
PVR_RENDER_TARGETS_PER_FRAMEBUFFER(&device->pdevice->dev_info);
VK_MULTIALLOC(ma);
vk_multialloc_add(&ma, &framebuffer, __typeof__(*framebuffer), 1);
vk_multialloc_add(&ma,
&attachments,
__typeof__(*attachments),
pCreateInfo->attachmentCount);
vk_multialloc_add(&ma,
&render_targets,
__typeof__(*render_targets),
@@ -1938,75 +1957,50 @@ VkResult pvr_CreateFramebuffer(VkDevice _device,
vk_multialloc_add(&ma,
&spm_eot_state_per_render,
__typeof__(*spm_eot_state_per_render),
pass->hw_setup->render_count);
render_count);
vk_multialloc_add(&ma,
&spm_bgobj_state_per_render,
__typeof__(*spm_bgobj_state_per_render),
pass->hw_setup->render_count);
render_count);
if (!vk_multialloc_zalloc2(&ma,
&device->vk.alloc,
pAllocator,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) {
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_object_base_init(&device->vk,
&framebuffer->base,
VK_OBJECT_TYPE_FRAMEBUFFER);
framebuffer->width = pCreateInfo->width;
framebuffer->height = pCreateInfo->height;
framebuffer->layers = pCreateInfo->layers;
framebuffer->attachments = attachments;
if (!pImageless)
framebuffer->attachment_count = pCreateInfo->attachmentCount;
else
framebuffer->attachment_count = pImageless->attachmentImageInfoCount;
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
if (!pImageless) {
framebuffer->attachments[i] =
pvr_image_view_from_handle(pCreateInfo->pAttachments[i]);
} else {
assert(i < pImageless->attachmentImageInfoCount);
}
}
result = pvr_framebuffer_create_ppp_state(device, framebuffer);
if (result != VK_SUCCESS)
goto err_free_framebuffer;
framebuffer->render_targets = render_targets;
framebuffer->render_targets_count = render_targets_count;
if (!pvr_render_targets_init(framebuffer->render_targets,
rstate->render_targets = render_targets;
rstate->render_targets_count = render_targets_count;
if (!pvr_render_targets_init(rstate->render_targets,
render_targets_count)) {
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
goto err_free_ppp_state_bo;
goto err_free_render_targets;
}
scratch_buffer_size =
pvr_spm_scratch_buffer_calc_required_size(pass,
framebuffer->width,
framebuffer->height);
assert(rstate->scratch_buffer_size);
result = pvr_spm_scratch_buffer_get_buffer(device,
scratch_buffer_size,
&framebuffer->scratch_buffer);
rstate->scratch_buffer_size,
&rstate->scratch_buffer);
if (result != VK_SUCCESS)
goto err_finish_render_targets;
for (uint32_t i = 0; i < pass->hw_setup->render_count; i++) {
result = pvr_render_state_create_ppp_state(device, rstate);
if (result != VK_SUCCESS)
goto err_release_scratch_buffer;
for (uint32_t i = 0; i < render_count; i++) {
result = pvr_spm_init_eot_state(device,
&spm_eot_state_per_render[i],
framebuffer,
&pass->hw_setup->renders[i]);
rstate,
&renders[i]);
if (result != VK_SUCCESS)
goto err_finish_eot_state;
result = pvr_spm_init_bgobj_state(device,
&spm_bgobj_state_per_render[i],
framebuffer,
&pass->hw_setup->renders[i]);
rstate,
&renders[i]);
if (result != VK_SUCCESS)
goto err_finish_bgobj_state;
@@ -2022,23 +2016,102 @@ err_finish_eot_state:
for (uint32_t j = 0; j < i; j++)
pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[j]);
goto err_finish_render_targets;
goto err_free_ppp_state_bo;
}
framebuffer->render_count = pass->hw_setup->render_count;
framebuffer->spm_eot_state_per_render = spm_eot_state_per_render;
framebuffer->spm_bgobj_state_per_render = spm_bgobj_state_per_render;
rstate->render_count = render_count;
rstate->spm_eot_state_per_render = spm_eot_state_per_render;
rstate->spm_bgobj_state_per_render = spm_bgobj_state_per_render;
return VK_SUCCESS;
err_free_ppp_state_bo:
pvr_bo_suballoc_free(rstate->ppp_state_bo);
err_release_scratch_buffer:
pvr_spm_scratch_buffer_release(device, rstate->scratch_buffer);
err_finish_render_targets:
pvr_render_targets_fini(rstate->render_targets, render_targets_count);
err_free_render_targets:
vk_free2(&device->vk.alloc, pAllocator, rstate->render_targets);
return result;
}
VkResult pvr_CreateFramebuffer(VkDevice _device,
const VkFramebufferCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkFramebuffer *pFramebuffer)
{
VK_FROM_HANDLE(pvr_render_pass, pass, pCreateInfo->renderPass);
VK_FROM_HANDLE(pvr_device, device, _device);
const VkFramebufferAttachmentsCreateInfoKHR *pImageless;
struct pvr_framebuffer *framebuffer;
struct pvr_image_view **attachments;
struct pvr_render_state *rstate;
VkResult result;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
pImageless = vk_find_struct_const(pCreateInfo->pNext,
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
VK_MULTIALLOC(ma);
vk_multialloc_add(&ma, &framebuffer, __typeof__(*framebuffer), 1);
vk_multialloc_add(&ma, &rstate, __typeof__(*rstate), 1);
vk_multialloc_add(&ma,
&attachments,
__typeof__(*attachments),
pCreateInfo->attachmentCount);
if (!vk_multialloc_zalloc2(&ma,
&device->vk.alloc,
pAllocator,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_object_base_init(&device->vk,
&framebuffer->base,
VK_OBJECT_TYPE_FRAMEBUFFER);
framebuffer->attachments = attachments;
if (!pImageless)
framebuffer->attachment_count = pCreateInfo->attachmentCount;
else
framebuffer->attachment_count = pImageless->attachmentImageInfoCount;
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
if (!pImageless) {
framebuffer->attachments[i] =
pvr_image_view_from_handle(pCreateInfo->pAttachments[i]);
} else {
assert(i < pImageless->attachmentImageInfoCount);
}
}
rstate->width = pCreateInfo->width;
rstate->height = pCreateInfo->height;
rstate->layers = pCreateInfo->layers;
rstate->scratch_buffer_size =
pvr_render_pass_get_scratch_buffer_size(device,
pass,
rstate);
result = pvr_render_state_setup(device,
pAllocator,
rstate,
pass->hw_setup->render_count,
pass->hw_setup->renders);
if (result != VK_SUCCESS)
goto err_free_framebuffer;
framebuffer->rstate = rstate;
*pFramebuffer = pvr_framebuffer_to_handle(framebuffer);
return VK_SUCCESS;
err_finish_render_targets:
pvr_render_targets_fini(framebuffer->render_targets, render_targets_count);
err_free_ppp_state_bo:
pvr_bo_suballoc_free(framebuffer->ppp_state_bo);
err_free_framebuffer:
vk_object_base_finish(&framebuffer->base);
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
@@ -2056,18 +2129,8 @@ void pvr_DestroyFramebuffer(VkDevice _device,
if (!framebuffer)
return;
for (uint32_t i = 0; i < framebuffer->render_count; i++) {
pvr_spm_finish_bgobj_state(device,
&framebuffer->spm_bgobj_state_per_render[i]);
pvr_render_state_cleanup(device, framebuffer->rstate);
pvr_spm_finish_eot_state(device,
&framebuffer->spm_eot_state_per_render[i]);
}
pvr_spm_scratch_buffer_release(device, framebuffer->scratch_buffer);
pvr_render_targets_fini(framebuffer->render_targets,
framebuffer->render_targets_count);
pvr_bo_suballoc_free(framebuffer->ppp_state_bo);
vk_object_base_finish(&framebuffer->base);
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
}
+44 -4
View File
@@ -22,17 +22,42 @@ struct pvr_render_target {
uint32_t valid_mask;
};
struct pvr_framebuffer {
struct vk_object_base base;
/* Saved information from pCreateInfo. */
struct pvr_render_state {
uint32_t width;
uint32_t height;
uint32_t layers;
uint32_t width_alignment;
uint32_t height_alignment;
/* Derived and other state. */
struct pvr_suballoc_bo *ppp_state_bo;
/* PPP state size in dwords. */
size_t ppp_state_size;
uint32_t render_targets_count;
struct pvr_render_target *render_targets;
uint64_t scratch_buffer_size;
struct pvr_spm_scratch_buffer *scratch_buffer;
uint32_t render_count;
struct pvr_spm_eot_state *spm_eot_state_per_render;
struct pvr_spm_bgobj_state *spm_bgobj_state_per_render;
};
struct pvr_framebuffer {
struct vk_object_base base;
uint32_t attachment_count;
struct pvr_image_view **attachments;
#if 0
/* Saved information from pCreateInfo. */
uint32_t width;
uint32_t height;
uint32_t layers;
/* Derived and other state. */
struct pvr_suballoc_bo *ppp_state_bo;
/* PPP state size in dwords. */
@@ -46,8 +71,23 @@ struct pvr_framebuffer {
uint32_t render_count;
struct pvr_spm_eot_state *spm_eot_state_per_render;
struct pvr_spm_bgobj_state *spm_bgobj_state_per_render;
#else
struct pvr_render_state *rstate;
#endif
};
struct pvr_device;
struct pvr_renderpass_hwsetup_render;
VkResult pvr_render_state_setup(struct pvr_device *device,
const VkAllocationCallbacks *pAllocator,
struct pvr_render_state *rstate,
uint32_t render_count,
const struct pvr_renderpass_hwsetup_render *renders);
void pvr_render_state_cleanup(struct pvr_device *device,
const struct pvr_render_state *rstate);
VK_DEFINE_NONDISP_HANDLE_CASTS(pvr_framebuffer,
base,
VkFramebuffer,
+17 -16
View File
@@ -86,10 +86,12 @@ void pvr_spm_finish_scratch_buffer_store(struct pvr_device *device)
}
}
uint64_t
pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass *pass,
uint32_t framebuffer_width,
uint32_t framebuffer_height)
uint64_t pvr_spm_scratch_buffer_calc_required_size(
const struct pvr_renderpass_hwsetup_render *renders,
uint32_t render_count,
uint32_t sample_count,
uint32_t framebuffer_width,
uint32_t framebuffer_height)
{
uint64_t dwords_per_pixel;
uint64_t buffer_size;
@@ -100,16 +102,15 @@ pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass *pass,
uint32_t nr_tile_buffers = 1;
uint32_t nr_output_regs = 1;
for (uint32_t i = 0; i < pass->hw_setup->render_count; i++) {
const struct pvr_renderpass_hwsetup_render *hw_render =
&pass->hw_setup->renders[i];
for (uint32_t i = 0; i < render_count; i++) {
const struct pvr_renderpass_hwsetup_render *hw_render = &renders[i];
nr_tile_buffers = MAX2(nr_tile_buffers, hw_render->tile_buffers_count);
nr_output_regs = MAX2(nr_output_regs, hw_render->output_regs_count);
}
dwords_per_pixel =
(uint64_t)pass->max_sample_count * nr_output_regs * nr_tile_buffers;
(uint64_t)sample_count * nr_output_regs * nr_tile_buffers;
buffer_size = ALIGN_POT((uint64_t)framebuffer_width,
ROGUE_CR_PBE_WORD0_MRT0_LINESTRIDE_ALIGNMENT);
@@ -641,12 +642,12 @@ static VkResult pvr_pds_pixel_event_program_create_and_upload(
VkResult
pvr_spm_init_eot_state(struct pvr_device *device,
struct pvr_spm_eot_state *spm_eot_state,
const struct pvr_framebuffer *framebuffer,
const struct pvr_render_state *rstate,
const struct pvr_renderpass_hwsetup_render *hw_render)
{
const VkExtent2D framebuffer_size = {
.width = framebuffer->width,
.height = framebuffer->height,
.width = rstate->width,
.height = rstate->height,
};
uint32_t pbe_state_words[PVR_MAX_COLOR_ATTACHMENTS]
[ROGUE_NUM_PBESTATE_STATE_WORDS];
@@ -659,7 +660,7 @@ pvr_spm_init_eot_state(struct pvr_device *device,
VkResult result;
pvr_dev_addr_t next_scratch_buffer_addr =
framebuffer->scratch_buffer->bo->vma->dev_addr;
rstate->scratch_buffer->bo->vma->dev_addr;
uint64_t mem_stored;
/* TODO: See if instead of having a separate path for devices with 8 output
@@ -942,15 +943,15 @@ static VkResult pvr_pds_bgnd_program_create_and_upload(
VkResult
pvr_spm_init_bgobj_state(struct pvr_device *device,
struct pvr_spm_bgobj_state *spm_bgobj_state,
const struct pvr_framebuffer *framebuffer,
const struct pvr_render_state *rstate,
const struct pvr_renderpass_hwsetup_render *hw_render)
{
const VkExtent2D framebuffer_size = {
.width = framebuffer->width,
.height = framebuffer->height,
.width = rstate->width,
.height = rstate->height,
};
pvr_dev_addr_t next_scratch_buffer_addr =
framebuffer->scratch_buffer->bo->vma->dev_addr;
rstate->scratch_buffer->bo->vma->dev_addr;
struct pvr_spm_per_load_program_state *load_program_state;
struct pvr_pds_upload pds_texture_data_upload;
struct pvr_sampler_descriptor *descriptor;
+9 -5
View File
@@ -51,6 +51,7 @@ struct pvr_device;
struct pvr_framebuffer;
struct pvr_render_pass;
struct pvr_renderpass_hwsetup_render;
struct pvr_render_state;
struct pvr_spm_scratch_buffer;
struct pvr_spm_scratch_buffer_store {
@@ -93,9 +94,12 @@ void pvr_spm_finish_scratch_buffer_store(struct pvr_device *device);
* attachments with no backing.
*/
uint64_t
pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass *pass,
uint32_t framebuffer_width,
uint32_t framebuffer_height);
pvr_spm_scratch_buffer_calc_required_size(
const struct pvr_renderpass_hwsetup_render *renders,
uint32_t render_count,
uint32_t sample_count,
uint32_t framebuffer_width,
uint32_t framebuffer_height);
VkResult pvr_spm_scratch_buffer_get_buffer(
struct pvr_device *device,
uint64_t size,
@@ -110,7 +114,7 @@ void pvr_device_finish_spm_load_state(struct pvr_device *device);
VkResult
pvr_spm_init_eot_state(struct pvr_device *device,
struct pvr_spm_eot_state *spm_eot_state,
const struct pvr_framebuffer *framebuffer,
const struct pvr_render_state *rstate,
const struct pvr_renderpass_hwsetup_render *hw_render);
void pvr_spm_finish_eot_state(struct pvr_device *device,
@@ -119,7 +123,7 @@ void pvr_spm_finish_eot_state(struct pvr_device *device,
VkResult
pvr_spm_init_bgobj_state(struct pvr_device *device,
struct pvr_spm_bgobj_state *spm_bgobj_state,
const struct pvr_framebuffer *framebuffer,
const struct pvr_render_state *rstate,
const struct pvr_renderpass_hwsetup_render *hw_render);
void pvr_spm_finish_bgobj_state(struct pvr_device *device,