c/render: Refactor out a render pass object

This commit is contained in:
Jakob Bornecrantz 2023-09-27 14:21:09 +01:00
parent 7c512b2fc5
commit 29574dfea3
3 changed files with 161 additions and 66 deletions

View file

@ -100,6 +100,12 @@ struct comp_renderer
//! Which buffer was last submitted and has a fence pending.
int32_t fenced_buffer;
/*!
* The render pass used to render to the target, it depends on the
* target's format so will be recreated each time the target changes.
*/
struct render_gfx_render_pass target_render_pass;
/*!
* Array of "rendering" target resources equal in size to the number of
* comp_target images. Each target resources holds all of the resources
@ -212,13 +218,15 @@ renderer_build_rendering_target_resources(struct comp_renderer *r,
struct comp_compositor *c = r->c;
struct render_gfx_target_data data;
data.format = r->c->target->format;
data.is_external = true;
data.width = r->c->target->width;
data.height = r->c->target->height;
VkImageView image_view = r->c->target->images[index].view;
VkExtent2D extent = {r->c->target->width, r->c->target->height};
render_gfx_target_resources_init(rtr, &c->nr, r->c->target->images[index].view, &data);
render_gfx_target_resources_init( //
rtr, //
&c->nr, //
&r->target_render_pass, //
image_view, //
extent); //
}
/*!
@ -376,6 +384,13 @@ renderer_create_renderings_and_fences(struct comp_renderer *r)
if (!use_compute) {
r->rtr_array = U_TYPED_ARRAY_CALLOC(struct render_gfx_target_resources, r->buffer_count);
render_gfx_render_pass_init( //
&r->target_render_pass, // rgrp
&r->c->nr, // r
r->c->target->format, // format
VK_ATTACHMENT_LOAD_OP_CLEAR, // load_op
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); // final_layout
for (uint32_t i = 0; i < r->buffer_count; ++i) {
renderer_build_rendering_target_resources(r, &r->rtr_array[i], i);
}
@ -414,6 +429,9 @@ renderer_close_renderings_and_fences(struct comp_renderer *r)
render_gfx_target_resources_close(&r->rtr_array[i]);
}
// Close the render pass used for rendering to the target.
render_gfx_render_pass_close(&r->target_render_pass);
free(r->rtr_array);
r->rtr_array = NULL;
}

View file

@ -422,6 +422,60 @@ update_mesh_discriptor_set(struct vk_bundle *vk,
}
/*
*
* 'Exported' render pass functions.
*
*/
bool
render_gfx_render_pass_init(struct render_gfx_render_pass *rgrp,
struct render_resources *r,
VkFormat format,
VkAttachmentLoadOp load_op,
VkImageLayout final_layout)
{
C(create_implicit_render_pass( //
r->vk, // vk_bundle
format, // target_format
load_op, // load_op
final_layout, // final_layout
&rgrp->render_pass)); // out_render_pass
C(create_mesh_pipeline( //
r->vk, // vk_bundle
rgrp->render_pass, // render_pass
r->mesh.pipeline_layout, // pipeline_layout
r->pipeline_cache, // pipeline_cache
r->mesh.src_binding, // src_binding
r->mesh.index_count_total, // mesh_index_count_total
r->mesh.stride, // mesh_stride
r->shaders->mesh_vert, // mesh_vert
r->shaders->mesh_frag, // mesh_frag
&rgrp->mesh.pipeline)); // out_mesh_pipeline
// Set fields.
rgrp->r = r;
rgrp->format = format;
rgrp->sample_count = VK_SAMPLE_COUNT_1_BIT;
rgrp->load_op = load_op;
rgrp->final_layout = final_layout;
return true;
}
void
render_gfx_render_pass_close(struct render_gfx_render_pass *rgrp)
{
struct vk_bundle *vk = rgrp->r->vk;
D(RenderPass, rgrp->render_pass);
D(Pipeline, rgrp->mesh.pipeline);
U_ZERO(rgrp);
}
/*
*
* 'Exported' target resources functions.
@ -431,40 +485,24 @@ update_mesh_discriptor_set(struct vk_bundle *vk,
bool
render_gfx_target_resources_init(struct render_gfx_target_resources *rtr,
struct render_resources *r,
struct render_gfx_render_pass *rgrp,
VkImageView target,
struct render_gfx_target_data *data)
VkExtent2D extent)
{
struct vk_bundle *vk = r->vk;
rtr->r = r;
assert(data->is_external);
C(create_framebuffer( //
vk, // vk_bundle,
target, // image_view,
rgrp->render_pass, // render_pass,
extent.width, // width,
extent.height, // height,
&rtr->framebuffer)); // out_external_framebuffer
rtr->data = *data;
C(create_implicit_render_pass( //
vk, // vk_bundle
data->format, // target_format
VK_ATTACHMENT_LOAD_OP_CLEAR, // load_op
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // final_layout
&rtr->render_pass)); // out_render_pass
C(create_mesh_pipeline(vk, // vk_bundle
rtr->render_pass, // render_pass
r->mesh.pipeline_layout, // pipeline_layout
r->pipeline_cache, // pipeline_cache
r->mesh.src_binding, // src_binding
r->mesh.index_count_total, // mesh_index_count_total
r->mesh.stride, // mesh_stride
r->shaders->mesh_vert, // mesh_vert
r->shaders->mesh_frag, // mesh_frag
&rtr->mesh.pipeline)); // out_mesh_pipeline
C(create_framebuffer(vk, // vk_bundle,
target, // image_view,
rtr->render_pass, // render_pass,
data->width, // width,
data->height, // height,
&rtr->framebuffer)); // out_external_framebuffer
// Set fields.
rtr->rgrp = rgrp;
rtr->extent = extent;
return true;
}
@ -474,9 +512,9 @@ render_gfx_target_resources_close(struct render_gfx_target_resources *rtr)
{
struct vk_bundle *vk = vk_from_rtr(rtr);
D(RenderPass, rtr->render_pass);
D(Pipeline, rtr->mesh.pipeline);
D(Framebuffer, rtr->framebuffer);
U_ZERO(rtr);
}
@ -592,13 +630,17 @@ render_gfx_begin_target(struct render_gfx *rr, struct render_gfx_target_resource
assert(rr->rtr == NULL);
rr->rtr = rtr;
VkRenderPass render_pass = rtr->rgrp->render_pass;
VkFramebuffer framebuffer = rtr->framebuffer;
VkExtent2D extent = rtr->extent;
// This is shared across both views.
begin_render_pass(vk, //
rr->r->cmd, //
rr->rtr->render_pass, //
rr->rtr->framebuffer, //
rr->rtr->data.width, //
rr->rtr->data.height); //
begin_render_pass(vk, //
rr->r->cmd, //
render_pass, //
framebuffer, //
extent.width, //
extent.height); //
return true;
}
@ -702,7 +744,7 @@ render_gfx_distortion(struct render_gfx *rr)
vk->vkCmdBindPipeline( //
r->cmd, // commandBuffer
VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
rr->rtr->mesh.pipeline); // pipeline
rr->rtr->rgrp->mesh.pipeline); // pipeline
/*

View file

@ -526,28 +526,69 @@ struct render_viewport_data
/*
*
* Rendering target
* Render pass
*
*/
/*!
* Each rendering (@ref render_gfx) render to one or more targets
* (@ref render_gfx_target_resources), each target can have one or more
* views (@ref render_gfx_view), this struct holds all the data that is
* specific to the target.
* A render pass while not depending on a @p VkFramebuffer does depend on the
* format of the target image(s), and other options for the render pass. These
* are used to create a @p VkRenderPass, all @p VkFramebuffer(s) and
* @p VkPipeline depends on the @p VkRenderPass so hang off this struct.
*/
struct render_gfx_target_data
struct render_gfx_render_pass
{
// The format that should be used to read from the target.
struct render_resources *r;
//! The format of the image(s) we are rendering to.
VkFormat format;
// Is this target a external target.
bool is_external;
//! Sample count for this render pass.
VkSampleCountFlagBits sample_count;
//! Total height and width of the target.
uint32_t width, height;
//! Load op used on the attachment(s).
VkAttachmentLoadOp load_op;
//! Final layout of the target image(s).
VkImageLayout final_layout;
//! Render pass used for rendering.
VkRenderPass render_pass;
struct
{
//! Pipeline layout used for mesh, does not depend on framebuffer.
VkPipeline pipeline;
} mesh;
};
/*!
* Creates all resources held by the render pass, does not free the struct itself.
*
* @public @memberof render_gfx_render_pass
*/
bool
render_gfx_render_pass_init(struct render_gfx_render_pass *rgrp,
struct render_resources *r,
VkFormat format,
VkAttachmentLoadOp load_op,
VkImageLayout final_layout);
/*!
* Frees all resources held by the render pass, does not free the struct itself.
*
* @public @memberof render_gfx_render_pass
*/
void
render_gfx_render_pass_close(struct render_gfx_render_pass *rgrp);
/*
*
* Rendering target
*
*/
/*!
* Each rendering (@ref render_gfx) render to one or more targets
* (@ref render_gfx_target_resources), each target can have one or more
@ -564,23 +605,16 @@ struct render_gfx_target_resources
//! Collections of static resources.
struct render_resources *r;
//! The data for this target.
struct render_gfx_target_data data;
//! Render pass.
struct render_gfx_render_pass *rgrp;
//! Render pass used for rendering, does not depend on framebuffer.
VkRenderPass render_pass;
struct
{
//! Pipeline layout used for mesh, does not depend on framebuffer.
VkPipeline pipeline;
} mesh;
// The extent of the framebuffer.
VkExtent2D extent;
//! Framebuffer for this target, depends on given VkImageView.
VkFramebuffer framebuffer;
};
/*!
* Init a target resource struct, caller has to keep target alive until closed.
*
@ -589,8 +623,9 @@ struct render_gfx_target_resources
bool
render_gfx_target_resources_init(struct render_gfx_target_resources *rtr,
struct render_resources *r,
struct render_gfx_render_pass *rgrp,
VkImageView target,
struct render_gfx_target_data *data);
VkExtent2D extent);
/*!
* Frees all resources held by the target, does not free the struct itself.