mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 16:00:08 +01:00
pvr: add support for VK_KHR_dynamic_rendering
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com> Co-authored-by: Ella Stanforth <ella@igalia.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:
parent
5b752ccab0
commit
146364ab9f
13 changed files with 1699 additions and 106 deletions
|
|
@ -1834,7 +1834,7 @@ static VkResult pvr_add_deferred_rta_clear(struct pvr_cmd_buffer *cmd_buffer,
|
|||
struct pvr_render_pass_info *pass_info = &cmd_buffer->state.render_pass_info;
|
||||
struct pvr_sub_cmd_gfx *sub_cmd = &cmd_buffer->state.current_sub_cmd->gfx;
|
||||
const struct pvr_renderpass_hwsetup_render *hw_render =
|
||||
&pass_info->pass->hw_setup->renders[sub_cmd->hw_render_idx];
|
||||
pvr_pass_info_get_hw_render(pass_info, sub_cmd->hw_render_idx);
|
||||
const struct pvr_image_view *image_view;
|
||||
const struct pvr_image *image;
|
||||
uint32_t base_layer;
|
||||
|
|
@ -1872,6 +1872,12 @@ static VkResult pvr_add_deferred_rta_clear(struct pvr_cmd_buffer *cmd_buffer,
|
|||
assert(attachment->colorAttachment < hw_render->color_init_count);
|
||||
index = hw_render->color_init[attachment->colorAttachment].index;
|
||||
|
||||
image_view = pass_info->attachments[index];
|
||||
} else if (cmd_buffer->state.current_sub_cmd->is_dynamic_render) {
|
||||
const struct pvr_dynamic_render_info *dr_info = pass_info->dr_info;
|
||||
const uint32_t index =
|
||||
dr_info->color_attachments[attachment->colorAttachment].index_color;
|
||||
|
||||
image_view = pass_info->attachments[index];
|
||||
} else {
|
||||
const struct pvr_renderpass_hwsetup_subpass *hw_pass =
|
||||
|
|
@ -1938,19 +1944,25 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
{
|
||||
const struct pvr_render_pass *pass = cmd_buffer->state.render_pass_info.pass;
|
||||
struct pvr_render_pass_info *pass_info = &cmd_buffer->state.render_pass_info;
|
||||
const struct pvr_renderpass_hwsetup_subpass *hw_pass =
|
||||
pvr_get_hw_subpass(pass, pass_info->subpass_idx);
|
||||
struct pvr_sub_cmd_gfx *sub_cmd = &cmd_buffer->state.current_sub_cmd->gfx;
|
||||
struct pvr_device_info *dev_info = &cmd_buffer->device->pdevice->dev_info;
|
||||
struct pvr_render_subpass *sub_pass = &pass->subpasses[hw_pass->index];
|
||||
const struct pvr_renderpass_hwsetup_subpass *hw_pass;
|
||||
bool vs_has_rt_id_output, multiview_enabled;
|
||||
uint32_t vs_output_size_in_bytes;
|
||||
bool vs_has_rt_id_output;
|
||||
|
||||
/* TODO: This function can be optimized so that most of the device memory
|
||||
* gets allocated together in one go and then filled as needed. There might
|
||||
* also be opportunities to reuse pds code and data segments.
|
||||
*/
|
||||
|
||||
if (pass) {
|
||||
hw_pass = pvr_get_hw_subpass(pass, pass_info->subpass_idx);
|
||||
multiview_enabled = pass->multiview_enabled;
|
||||
} else {
|
||||
multiview_enabled = pass_info->dr_info->hw_render.multiview_enabled;
|
||||
hw_pass = NULL;
|
||||
}
|
||||
|
||||
assert(cmd_buffer->state.current_sub_cmd->type == PVR_SUB_CMD_TYPE_GRAPHICS);
|
||||
|
||||
pvr_reset_graphics_dirty_state(cmd_buffer, false);
|
||||
|
|
@ -1959,7 +1971,7 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
sub_cmd->empty_cmd = false;
|
||||
|
||||
vs_has_rt_id_output = pvr_clear_needs_rt_id_output(dev_info,
|
||||
pass->multiview_enabled,
|
||||
multiview_enabled,
|
||||
rect_count,
|
||||
rects);
|
||||
|
||||
|
|
@ -1978,6 +1990,7 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
|
||||
if (attachment->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
uint32_t packed_clear_color[PVR_CLEAR_COLOR_ARRAY_SIZE];
|
||||
struct pvr_renderpass_hwsetup_render *hw_render;
|
||||
const struct usc_mrt_resource *mrt_resource;
|
||||
uint32_t global_attachment_idx;
|
||||
uint32_t local_attachment_idx;
|
||||
|
|
@ -1985,19 +1998,31 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
|
||||
local_attachment_idx = attachment->colorAttachment;
|
||||
|
||||
assert(cmd_buffer->state.current_sub_cmd->is_dynamic_render ||
|
||||
pass->hw_setup->render_count > 0);
|
||||
hw_render =
|
||||
pvr_pass_info_get_hw_render(&cmd_buffer->state.render_pass_info, 0);
|
||||
|
||||
/* TODO: verify that the hw_render if is_render_init is true is exclusive to
|
||||
* a non dynamic rendering path.
|
||||
*/
|
||||
if (is_render_init) {
|
||||
struct pvr_renderpass_hwsetup_render *hw_render;
|
||||
|
||||
assert(pass->hw_setup->render_count > 0);
|
||||
hw_render = &pass->hw_setup->renders[0];
|
||||
|
||||
mrt_resource =
|
||||
&hw_render->init_setup.mrt_resources[local_attachment_idx];
|
||||
|
||||
assert(local_attachment_idx < hw_render->color_init_count);
|
||||
global_attachment_idx =
|
||||
hw_render->color_init[local_attachment_idx].index;
|
||||
} else if (cmd_buffer->state.current_sub_cmd->is_dynamic_render) {
|
||||
const struct pvr_dynamic_render_info *dr_info = pass_info->dr_info;
|
||||
|
||||
mrt_resource =
|
||||
&dr_info->mrt_setup->mrt_resources[local_attachment_idx];
|
||||
global_attachment_idx =
|
||||
dr_info->color_attachments[local_attachment_idx].index_color;
|
||||
} else {
|
||||
struct pvr_render_subpass *sub_pass = &pass->subpasses[hw_pass->index];
|
||||
|
||||
mrt_resource = &hw_pass->setup.mrt_resources[local_attachment_idx];
|
||||
|
||||
assert(local_attachment_idx < sub_pass->color_count);
|
||||
|
|
@ -2008,8 +2033,14 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
if (global_attachment_idx == VK_ATTACHMENT_UNUSED)
|
||||
continue;
|
||||
|
||||
if (cmd_buffer->state.current_sub_cmd->is_dynamic_render) {
|
||||
const struct pvr_dynamic_render_info *dr_info = pass_info->dr_info;
|
||||
|
||||
format = dr_info->attachments[global_attachment_idx].vk_format;
|
||||
} else {
|
||||
assert(global_attachment_idx < pass->attachment_count);
|
||||
format = pass->attachments[global_attachment_idx].vk_format;
|
||||
}
|
||||
|
||||
assert(format != VK_FORMAT_UNDEFINED);
|
||||
|
||||
|
|
@ -2026,7 +2057,7 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
vs_has_rt_id_output);
|
||||
if (result != VK_SUCCESS)
|
||||
return;
|
||||
} else if (hw_pass->z_replicate != -1 &&
|
||||
} else if (pass && hw_pass->z_replicate != -1 &&
|
||||
attachment->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||
const VkClearColorValue clear_color = {
|
||||
.float32 = { [0] = attachment->clearValue.depthStencil.depth, },
|
||||
|
|
@ -2140,6 +2171,8 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
|
||||
if (!PVR_HAS_FEATURE(dev_info, gs_rta_support) &&
|
||||
(clear_rect->baseArrayLayer != 0 || clear_rect->layerCount > 1)) {
|
||||
|
||||
if (pass_info->attachments) {
|
||||
result = pvr_add_deferred_rta_clear(cmd_buffer,
|
||||
attachment,
|
||||
clear_rect,
|
||||
|
|
@ -2148,6 +2181,9 @@ static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
|
|||
return;
|
||||
|
||||
continue;
|
||||
} else {
|
||||
pvr_finishme("incomplete support for deferred (emulated) RTA clears");
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Allocate all the buffers in one go before the loop, and add
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,6 +19,7 @@
|
|||
#include "pvr_common.h"
|
||||
#include "pvr_framebuffer.h"
|
||||
#include "pvr_job_render.h"
|
||||
#include "pvr_hw_pass.h"
|
||||
#include "pvr_types.h"
|
||||
|
||||
struct pvr_pds_upload;
|
||||
|
|
@ -113,7 +114,30 @@ struct pvr_transfer_cmd {
|
|||
struct pvr_cmd_buffer *cmd_buffer;
|
||||
};
|
||||
|
||||
struct pvr_color_attachment_output_map {
|
||||
uint32_t index_color;
|
||||
uint32_t index_resolve;
|
||||
};
|
||||
|
||||
struct pvr_dynamic_render_info {
|
||||
/* Inputs */
|
||||
struct pvr_render_pass_attachment *attachments;
|
||||
uint32_t attachment_count;
|
||||
|
||||
/* Outputs */
|
||||
struct pvr_color_attachment_output_map *color_attachments;
|
||||
uint32_t color_attachment_count;
|
||||
|
||||
struct usc_mrt_setup *mrt_setup;
|
||||
|
||||
struct pvr_renderpass_hwsetup_render hw_render;
|
||||
};
|
||||
|
||||
struct pvr_sub_cmd_gfx {
|
||||
struct pvr_dynamic_render_info *dr_info;
|
||||
struct pvr_renderpass_hwsetup_render *hw_render;
|
||||
uint32_t attachment_count;
|
||||
|
||||
const struct pvr_render_state *rstate;
|
||||
|
||||
struct pvr_render_job job;
|
||||
|
|
@ -249,11 +273,16 @@ struct pvr_sub_cmd {
|
|||
|
||||
enum pvr_sub_cmd_type type;
|
||||
|
||||
struct {
|
||||
/* True if the sub_cmd is owned by this command buffer. False if taken from
|
||||
* a secondary command buffer, in that case we are not supposed to free any
|
||||
* resources associated with the sub_cmd.
|
||||
*/
|
||||
bool owned;
|
||||
bool owned : 1;
|
||||
bool is_dynamic_render : 1;
|
||||
bool is_suspend : 1;
|
||||
bool is_resume : 1;
|
||||
};
|
||||
|
||||
union {
|
||||
struct pvr_sub_cmd_gfx gfx;
|
||||
|
|
@ -267,6 +296,8 @@ struct pvr_render_pass_info {
|
|||
const struct pvr_render_pass *pass;
|
||||
struct pvr_framebuffer *framebuffer;
|
||||
|
||||
struct pvr_dynamic_render_info *dr_info;
|
||||
struct pvr_renderpass_hwsetup_render *hw_render;
|
||||
struct pvr_render_state *rstate;
|
||||
|
||||
uint32_t attachment_count;
|
||||
|
|
@ -274,6 +305,7 @@ struct pvr_render_pass_info {
|
|||
|
||||
uint32_t subpass_idx;
|
||||
uint32_t current_hw_subpass;
|
||||
uint32_t sample_count;
|
||||
|
||||
VkRect2D render_area;
|
||||
|
||||
|
|
@ -285,6 +317,10 @@ struct pvr_render_pass_info {
|
|||
bool process_empty_tiles;
|
||||
bool enable_bg_tag;
|
||||
uint32_t isp_userpass;
|
||||
|
||||
bool dynamic_render;
|
||||
bool suspend;
|
||||
bool resume;
|
||||
};
|
||||
|
||||
struct pvr_ppp_state {
|
||||
|
|
@ -627,4 +663,8 @@ void pvr_calculate_vertex_cam_size(const struct pvr_device_info *dev_info,
|
|||
const struct pvr_renderpass_hwsetup_subpass *
|
||||
pvr_get_hw_subpass(const struct pvr_render_pass *pass, const uint32_t subpass);
|
||||
|
||||
struct pvr_renderpass_hwsetup_render *
|
||||
pvr_pass_info_get_hw_render(const struct pvr_render_pass_info *render_pass_info,
|
||||
uint32_t idx);
|
||||
|
||||
#endif /* PVR_CMD_BUFFER_H */
|
||||
|
|
|
|||
|
|
@ -991,6 +991,9 @@ pvr_create_device(struct pvr_physical_device *pdevice,
|
|||
device->global_cmd_buffer_submit_count = 0;
|
||||
device->global_queue_present_count = 0;
|
||||
|
||||
simple_mtx_init(&device->rs_mtx, mtx_plain);
|
||||
list_inithead(&device->render_states);
|
||||
|
||||
*pDevice = pvr_device_to_handle(device);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
@ -1057,6 +1060,36 @@ err_out:
|
|||
return result;
|
||||
}
|
||||
|
||||
void pvr_rstate_entry_add(struct pvr_device *device,
|
||||
struct pvr_render_state *rstate)
|
||||
{
|
||||
simple_mtx_lock(&device->rs_mtx);
|
||||
list_addtail(&rstate->link, &device->render_states);
|
||||
simple_mtx_unlock(&device->rs_mtx);
|
||||
}
|
||||
|
||||
void pvr_rstate_entry_remove(struct pvr_device *device,
|
||||
const struct pvr_render_state *rstate)
|
||||
{
|
||||
simple_mtx_lock(&device->rs_mtx);
|
||||
assert(rstate);
|
||||
|
||||
list_for_each_entry_safe (struct pvr_render_state,
|
||||
entry,
|
||||
&device->render_states,
|
||||
link) {
|
||||
if (entry != rstate)
|
||||
continue;
|
||||
|
||||
pvr_render_state_cleanup(device, rstate);
|
||||
list_del(&entry->link);
|
||||
|
||||
vk_free(&device->vk.alloc, entry);
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&device->rs_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
pvr_destroy_device(struct pvr_device *device,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
|
|
@ -1064,6 +1097,19 @@ pvr_destroy_device(struct pvr_device *device,
|
|||
if (!device)
|
||||
return;
|
||||
|
||||
simple_mtx_lock(&device->rs_mtx);
|
||||
list_for_each_entry_safe (struct pvr_render_state,
|
||||
rstate,
|
||||
&device->render_states,
|
||||
link) {
|
||||
pvr_render_state_cleanup(device, rstate);
|
||||
list_del(&rstate->link);
|
||||
|
||||
vk_free(&device->vk.alloc, rstate);
|
||||
}
|
||||
simple_mtx_unlock(&device->rs_mtx);
|
||||
simple_mtx_destroy(&device->rs_mtx);
|
||||
|
||||
pvr_border_color_table_finish(device);
|
||||
pvr_robustness_buffer_finish(device);
|
||||
pvr_spm_finish_scratch_buffer_store(device);
|
||||
|
|
@ -1929,6 +1975,7 @@ void pvr_render_state_cleanup(struct pvr_device *device,
|
|||
pvr_render_targets_fini(rstate->render_targets,
|
||||
rstate->render_targets_count);
|
||||
pvr_bo_suballoc_free(rstate->ppp_state_bo);
|
||||
vk_free(&device->vk.alloc, rstate->render_targets);
|
||||
}
|
||||
|
||||
VkResult pvr_render_state_setup(
|
||||
|
|
@ -2128,6 +2175,7 @@ void pvr_DestroyFramebuffer(VkDevice _device,
|
|||
return;
|
||||
|
||||
pvr_render_state_cleanup(device, framebuffer->rstate);
|
||||
/* the render state is freed with the framebuffer */
|
||||
|
||||
vk_object_base_finish(&framebuffer->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,9 @@ struct pvr_device {
|
|||
struct vk_sync *presignaled_sync;
|
||||
|
||||
struct pvr_border_color_table *border_color_table;
|
||||
|
||||
simple_mtx_t rs_mtx;
|
||||
struct list_head render_states;
|
||||
};
|
||||
|
||||
struct pvr_device_memory {
|
||||
|
|
@ -221,4 +224,10 @@ VkResult pvr_gpu_upload_usc(struct pvr_device *device,
|
|||
uint64_t code_alignment,
|
||||
struct pvr_suballoc_bo **const pvr_bo_out);
|
||||
|
||||
void pvr_rstate_entry_add(struct pvr_device *device,
|
||||
struct pvr_render_state *rstate);
|
||||
|
||||
void pvr_rstate_entry_remove(struct pvr_device *device,
|
||||
const struct pvr_render_state *rstate);
|
||||
|
||||
#endif /* PVR_DEVICE_H */
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ struct pvr_render_target {
|
|||
};
|
||||
|
||||
struct pvr_render_state {
|
||||
struct list_head link;
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t layers;
|
||||
|
|
@ -51,29 +53,7 @@ struct pvr_framebuffer {
|
|||
|
||||
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. */
|
||||
size_t ppp_state_size;
|
||||
|
||||
uint32_t render_targets_count;
|
||||
struct pvr_render_target *render_targets;
|
||||
|
||||
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;
|
||||
#else
|
||||
struct pvr_render_state *rstate;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct pvr_device;
|
||||
|
|
|
|||
|
|
@ -189,6 +189,8 @@ struct pvr_renderpass_hwsetup_render {
|
|||
|
||||
bool requires_frag_pr;
|
||||
|
||||
bool multiview_enabled;
|
||||
|
||||
/* View mask for multiview. */
|
||||
uint32_t view_mask;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,20 @@
|
|||
|
||||
#include "vk_log.h"
|
||||
|
||||
#include "pvr_cmd_buffer.h"
|
||||
#include "pvr_csb.h"
|
||||
#include "pvr_device.h"
|
||||
#include "pvr_formats.h"
|
||||
#include "pvr_image.h"
|
||||
#include "pvr_mrt.h"
|
||||
#include "pvr_pass.h"
|
||||
#include "pvr_physical_device.h"
|
||||
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include "pvr_mrt.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
#include "vulkan/runtime/vk_graphics_state.h"
|
||||
#include "vulkan/runtime/vk_image.h"
|
||||
|
||||
/* Which parts of the output registers/a tile buffer are currently allocated. */
|
||||
struct pvr_mrt_alloc_mask {
|
||||
|
|
@ -237,6 +242,246 @@ pvr_destroy_mrt_setup(const struct pvr_device *device,
|
|||
vk_free(&device->vk.alloc, setup->mrt_resources);
|
||||
}
|
||||
|
||||
static bool
|
||||
pvr_rendering_info_needs_load(const struct pvr_dynamic_render_info *dr_info)
|
||||
{
|
||||
for (unsigned i = 0; i < dr_info->hw_render.color_init_count; i++) {
|
||||
const uint32_t index = dr_info->hw_render.color_init[i].index;
|
||||
if (index == VK_ATTACHMENT_UNUSED)
|
||||
continue;
|
||||
|
||||
const VkAttachmentLoadOp op = dr_info->hw_render.color_init[i].op;
|
||||
if (op == VK_ATTACHMENT_LOAD_OP_LOAD || op == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static VkResult pvr_mrt_load_op_init(struct pvr_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
const struct pvr_render_pass_info *rp_info,
|
||||
struct pvr_load_op *load_op,
|
||||
uint32_t view_idx)
|
||||
{
|
||||
const struct pvr_dynamic_render_info *dr_info = rp_info->dr_info;
|
||||
VkResult result;
|
||||
|
||||
load_op->clears_loads_state.depth_clear_to_reg = PVR_NO_DEPTH_CLEAR_TO_REG;
|
||||
|
||||
assert(dr_info->hw_render.color_init_count <=
|
||||
PVR_LOAD_OP_CLEARS_LOADS_MAX_RTS);
|
||||
for (unsigned i = 0; i < dr_info->hw_render.color_init_count; i++) {
|
||||
const struct pvr_renderpass_colorinit *color_init =
|
||||
&dr_info->hw_render.color_init[i];
|
||||
const struct pvr_image *image;
|
||||
|
||||
assert(color_init->index < rp_info->attachment_count);
|
||||
load_op->clears_loads_state.dest_vk_format[i] =
|
||||
rp_info->attachments[color_init->index]->vk.view_format;
|
||||
|
||||
image = pvr_image_view_get_image(rp_info->attachments[color_init->index]);
|
||||
if (image->vk.samples > VK_SAMPLE_COUNT_1_BIT)
|
||||
load_op->clears_loads_state.unresolved_msaa_mask |= BITFIELD_BIT(i);
|
||||
|
||||
switch (color_init->op) {
|
||||
case VK_ATTACHMENT_LOAD_OP_CLEAR:
|
||||
load_op->clears_loads_state.rt_clear_mask |= BITFIELD_BIT(i);
|
||||
break;
|
||||
case VK_ATTACHMENT_LOAD_OP_LOAD:
|
||||
load_op->clears_loads_state.rt_load_mask |= BITFIELD_BIT(i);
|
||||
break;
|
||||
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
|
||||
case VK_ATTACHMENT_LOAD_OP_NONE:
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("unsupported loadOp");
|
||||
}
|
||||
}
|
||||
|
||||
load_op->clears_loads_state.mrt_setup = &dr_info->hw_render.init_setup;
|
||||
|
||||
result = pvr_load_op_shader_generate(device, alloc, load_op);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_free2(&device->vk.alloc, alloc, load_op);
|
||||
return result;
|
||||
}
|
||||
|
||||
load_op->view_indices[0] = view_idx;
|
||||
load_op->view_count = 1;
|
||||
|
||||
load_op->is_hw_object = true;
|
||||
load_op->hw_render = &dr_info->hw_render;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void pvr_load_op_fini(struct pvr_load_op *load_op)
|
||||
{
|
||||
pvr_bo_suballoc_free(load_op->pds_tex_state_prog.pvr_bo);
|
||||
pvr_bo_suballoc_free(load_op->pds_frag_prog.pvr_bo);
|
||||
pvr_bo_suballoc_free(load_op->usc_frag_prog_bo);
|
||||
}
|
||||
|
||||
static void pvr_load_op_destroy(struct pvr_device *device,
|
||||
const VkAllocationCallbacks *allocator,
|
||||
struct pvr_load_op *load_op)
|
||||
{
|
||||
pvr_load_op_fini(load_op);
|
||||
vk_free2(&device->vk.alloc, allocator, load_op);
|
||||
}
|
||||
|
||||
void
|
||||
pvr_mrt_load_op_state_cleanup(const struct pvr_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct pvr_load_op_state *state)
|
||||
{
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
while (state->load_op_count--) {
|
||||
const uint32_t load_op_idx = state->load_op_count;
|
||||
struct pvr_load_op *load_op = &state->load_ops[load_op_idx];
|
||||
|
||||
pvr_load_op_fini(load_op);
|
||||
}
|
||||
|
||||
vk_free2(&device->vk.alloc, alloc, state);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
pvr_mrt_load_op_state_create(struct pvr_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
const struct pvr_render_pass_info *rp_info,
|
||||
struct pvr_load_op_state **state)
|
||||
{
|
||||
const struct pvr_dynamic_render_info *dr_info = rp_info->dr_info;
|
||||
const uint32_t view_count = util_bitcount(dr_info->hw_render.view_mask);
|
||||
struct pvr_load_op_state *load_op_state;
|
||||
struct pvr_load_op *load_ops;
|
||||
VkResult result;
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
vk_multialloc_add(&ma, &load_op_state, __typeof__(*load_op_state), 1);
|
||||
vk_multialloc_add(&ma, &load_ops, __typeof__(*load_ops), view_count);
|
||||
|
||||
if (!vk_multialloc_zalloc(&ma, alloc, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
load_op_state->load_ops = load_ops;
|
||||
|
||||
u_foreach_bit (view_idx, dr_info->hw_render.view_mask) {
|
||||
struct pvr_load_op *const load_op =
|
||||
&load_op_state->load_ops[load_op_state->load_op_count];
|
||||
|
||||
result = pvr_mrt_load_op_init(device, alloc, rp_info, load_op, view_idx);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_load_op_state_cleanup;
|
||||
|
||||
load_op_state->load_op_count++;
|
||||
}
|
||||
|
||||
*state = load_op_state;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_load_op_state_cleanup:
|
||||
pvr_mrt_load_op_state_cleanup(device, alloc, load_op_state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* TODO: Can we gaurantee that if we have at least one render target there will
|
||||
* be a render target allocated as a REG?
|
||||
*/
|
||||
static inline bool pvr_needs_output_register_writes(
|
||||
const struct usc_mrt_setup *setup)
|
||||
{
|
||||
for (uint32_t i = 0; i < setup->num_render_targets; i++) {
|
||||
struct usc_mrt_resource *mrt_resource =
|
||||
&setup->mrt_resources[i];
|
||||
|
||||
if (mrt_resource->type == USC_MRT_RESOURCE_TYPE_OUTPUT_REG)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline VkResult pvr_mrt_add_missing_output_register_write(
|
||||
struct usc_mrt_setup *setup,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
const uint32_t last = setup->num_render_targets;
|
||||
struct usc_mrt_resource *mrt_resources;
|
||||
|
||||
if (pvr_needs_output_register_writes(setup))
|
||||
return VK_SUCCESS;
|
||||
|
||||
setup->num_render_targets++;
|
||||
|
||||
mrt_resources = vk_realloc(alloc,
|
||||
setup->mrt_resources,
|
||||
setup->num_render_targets *
|
||||
sizeof(*mrt_resources),
|
||||
8U,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
|
||||
if (!mrt_resources)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
setup->mrt_resources = mrt_resources;
|
||||
|
||||
mrt_resources[last].type = USC_MRT_RESOURCE_TYPE_OUTPUT_REG;
|
||||
mrt_resources[last].reg.output_reg = 0U;
|
||||
mrt_resources[last].reg.offset = 0U;
|
||||
mrt_resources[last].intermediate_size = 4U;
|
||||
mrt_resources[last].mrt_desc.intermediate_size = 4U;
|
||||
mrt_resources[last].mrt_desc.priority = 0U;
|
||||
mrt_resources[last].mrt_desc.valid_mask[0U] = ~0;
|
||||
mrt_resources[last].mrt_desc.valid_mask[1U] = ~0;
|
||||
mrt_resources[last].mrt_desc.valid_mask[2U] = ~0;
|
||||
mrt_resources[last].mrt_desc.valid_mask[3U] = ~0;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_mrt_load_ops_setup(struct pvr_cmd_buffer *cmd_buffer,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct pvr_load_op_state **load_op_state)
|
||||
{
|
||||
const struct pvr_cmd_buffer_state *state = &cmd_buffer->state;
|
||||
const struct pvr_dynamic_render_info *dr_info =
|
||||
state->render_pass_info.dr_info;
|
||||
struct pvr_device *device = cmd_buffer->device;
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
if (dr_info->mrt_setup->num_tile_buffers) {
|
||||
result = pvr_device_tile_buffer_ensure_cap(
|
||||
device,
|
||||
dr_info->mrt_setup->num_tile_buffers);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!pvr_rendering_info_needs_load(dr_info))
|
||||
return VK_SUCCESS;
|
||||
|
||||
result =
|
||||
pvr_mrt_add_missing_output_register_write(dr_info->mrt_setup,
|
||||
alloc);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
result = pvr_mrt_load_op_state_create(device,
|
||||
alloc,
|
||||
&state->render_pass_info,
|
||||
load_op_state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult pvr_pds_unitex_state_program_create_and_upload(
|
||||
struct pvr_device *device,
|
||||
const VkAllocationCallbacks *allocator,
|
||||
|
|
@ -413,3 +658,4 @@ err_free_usc_frag_prog_bo:
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,4 +189,15 @@ struct pvr_load_op_state {
|
|||
struct pvr_load_op *load_ops;
|
||||
};
|
||||
|
||||
struct pvr_dynamic_render_info;
|
||||
struct pvr_cmd_buffer;
|
||||
|
||||
VkResult pvr_mrt_load_ops_setup(struct pvr_cmd_buffer *cmd_buffer,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct pvr_load_op_state **state);
|
||||
void
|
||||
pvr_mrt_load_op_state_cleanup(const struct pvr_device *device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct pvr_load_op_state *state);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,10 +26,14 @@ struct pvr_render_pass_attachment {
|
|||
|
||||
VkAttachmentStoreOp store_op;
|
||||
|
||||
VkResolveModeFlagBits resolve_mode;
|
||||
|
||||
VkAttachmentLoadOp stencil_load_op;
|
||||
|
||||
VkAttachmentStoreOp stencil_store_op;
|
||||
|
||||
VkResolveModeFlagBits stencil_resolve_mode;
|
||||
|
||||
VkFormat vk_format;
|
||||
uint32_t sample_count;
|
||||
VkImageLayout initial_layout;
|
||||
|
|
@ -39,7 +43,11 @@ struct pvr_render_pass_attachment {
|
|||
|
||||
/* Can this surface be resolved by the PBE. */
|
||||
bool is_pbe_downscalable;
|
||||
bool is_depth;
|
||||
bool is_stencil;
|
||||
bool need_eot;
|
||||
|
||||
uint32_t resolve_target;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ pvr_cmd_buffer_state_get_view_count(const struct pvr_cmd_buffer_state *state)
|
|||
const struct pvr_sub_cmd_gfx *gfx_sub_cmd = &state->current_sub_cmd->gfx;
|
||||
const uint32_t hw_render_idx = gfx_sub_cmd->hw_render_idx;
|
||||
const struct pvr_renderpass_hwsetup_render *hw_render =
|
||||
&render_pass_info->pass->hw_setup->renders[hw_render_idx];
|
||||
pvr_pass_info_get_hw_render(render_pass_info, hw_render_idx);
|
||||
const uint32_t view_count = util_bitcount(hw_render->view_mask);
|
||||
|
||||
assert(state->current_sub_cmd->type == PVR_SUB_CMD_TYPE_GRAPHICS);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ struct pvr_query_pool {
|
|||
struct pvr_query_info {
|
||||
enum pvr_query_type type;
|
||||
|
||||
struct {
|
||||
bool is_dynamic_render : 1;
|
||||
bool is_suspend : 1;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t num_query_indices;
|
||||
|
|
|
|||
|
|
@ -412,6 +412,9 @@ VkResult pvr_add_query_program(struct pvr_cmd_buffer *cmd_buffer,
|
|||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
cmd_buffer->state.current_sub_cmd->is_dynamic_render = query_info->is_dynamic_render;
|
||||
cmd_buffer->state.current_sub_cmd->is_suspend = query_info->is_suspend;
|
||||
|
||||
switch (query_info->type) {
|
||||
case PVR_QUERY_TYPE_AVAILABILITY_WRITE:
|
||||
/* Adds a compute shader (fenced on the last 3D) that writes a non-zero
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue