c/[render|main]: Refactor scratch images

This commit does a few things:

* Makes the scratch images per view
* Introduces a new struct that is managed by the renderer
This commit is contained in:
Jakob Bornecrantz 2023-09-14 21:21:14 +01:00
parent fed360e98b
commit ee2fe9fd40
3 changed files with 129 additions and 90 deletions

View file

@ -87,6 +87,8 @@ struct comp_renderer
struct comp_mirror_to_debug_gui mirror_to_debug_gui; struct comp_mirror_to_debug_gui mirror_to_debug_gui;
//! Scratch images used for layer squasher.
struct render_scratch_images scratch;
//! @} //! @}
//! @name Image-dependent members //! @name Image-dependent members
@ -812,6 +814,9 @@ renderer_fini(struct comp_renderer *r)
// Do this after the mirror struct. // Do this after the mirror struct.
comp_layer_renderer_destroy(&(r->lr)); comp_layer_renderer_destroy(&(r->lr));
// Destroy any scratch images created.
render_scratch_images_close(&r->c->nr, &r->scratch);
} }
static VkImageView static VkImageView
@ -1033,13 +1038,13 @@ ensure_scratch_image(struct comp_renderer *r,
struct render_viewport_data r_viewport_data = { struct render_viewport_data r_viewport_data = {
.w = w, .w = w,
.h = h, .h = h,
.x = w, .x = 0,
.y = 0, .y = 0,
}; };
VkExtent2D extent = {w * 2, h}; VkExtent2D extent = {w, h};
if (!render_ensure_scratch_image(&r->c->nr, extent)) { if (!render_scratch_images_ensure(&r->c->nr, &r->scratch, extent)) {
U_LOG_E("Failed to create scratch image!"); U_LOG_E("Failed to create scratch image!");
assert(false); assert(false);
} }
@ -1059,13 +1064,13 @@ do_layers(struct comp_renderer *r,
// Create scratch image and get target views. // Create scratch image and get target views.
ensure_scratch_image(r, &target_views[0], &target_views[1]); ensure_scratch_image(r, &target_views[0], &target_views[1]);
VkImage target_images[2] = { VkImage target_images[2] = {
crc->r->scratch.color.image, r->scratch.color[0].image,
crc->r->scratch.color.image, r->scratch.color[1].image,
}; };
VkImageView target_image_views[2] = { VkImageView target_image_views[2] = {
crc->r->scratch.color.unorm_view, // Have to write in linear r->scratch.color[0].unorm_view, // Have to write in linear
crc->r->scratch.color.unorm_view, r->scratch.color[1].unorm_view,
}; };
struct xrt_normalized_rect pre_transforms[2] = { struct xrt_normalized_rect pre_transforms[2] = {
@ -1101,25 +1106,27 @@ do_distortion(struct comp_renderer *r, struct render_compute *crc, const struct
VkImage target_image = r->c->target->images[r->acquired_buffer].handle; VkImage target_image = r->c->target->images[r->acquired_buffer].handle;
VkImageView target_image_view = r->c->target->images[r->acquired_buffer].view; VkImageView target_image_view = r->c->target->images[r->acquired_buffer].view;
VkImageView view = crc->r->scratch.color.srgb_view; // Read with gamma curve.
VkSampler sampler = crc->r->samplers.clamp_to_border_black; VkSampler sampler = crc->r->samplers.clamp_to_border_black;
VkImageView src_image_views[2] = {view, view}; VkImageView src_image_views[2] = {
r->scratch.color[0].srgb_view, // Read with gamma curve.
r->scratch.color[1].srgb_view,
};
VkSampler src_samplers[2] = {sampler, sampler}; VkSampler src_samplers[2] = {sampler, sampler};
struct xrt_normalized_rect src_norm_rects[2] = { struct xrt_normalized_rect src_norm_rects[2] = {
{ {
// Left, takes up half the screen. // Left, takes up the full view of the first image.
.x = 0.0f, .x = 0.0f,
.y = 0.0f, .y = 0.0f,
.w = 0.5f, .w = 1.0f,
.h = 1.0f, .h = 1.0f,
}, },
{ {
// Right, takes up half the screen. // Right, takes up the full view of the second image.
.x = 0.5f, .x = 0.0f,
.y = 0.0f, .y = 0.0f,
.w = 0.5f, .w = 1.0f,
.h = 1.0f, .h = 1.0f,
}, },
}; };
@ -1626,17 +1633,17 @@ comp_renderer_draw(struct comp_renderer *r)
if (use_compute) { if (use_compute) {
// Covers only the first half of the view. // Covers only the first half of the view.
struct xrt_normalized_rect rect = {0, 0, 0.5f, 1.0f}; struct xrt_normalized_rect rect = {0, 0, 1.0f, 1.0f};
comp_mirror_do_blit( // comp_mirror_do_blit( //
&r->mirror_to_debug_gui, // &r->mirror_to_debug_gui, //
&c->base.vk, // &c->base.vk, //
frame_id, // frame_id, //
predicted_display_time_ns, // predicted_display_time_ns, //
c->nr.scratch.color.image, // r->scratch.color[0].image, //
c->nr.scratch.color.srgb_view, // r->scratch.color[0].srgb_view, //
clamp_to_edge, // clamp_to_edge, //
c->nr.scratch.extent, // r->scratch.extent, //
rect); // rect); //
} else { } else {
// Covers the whole view. // Covers the whole view.

View file

@ -299,22 +299,6 @@ struct render_resources
struct render_buffer ubos[2]; struct render_buffer ubos[2];
} mesh; } mesh;
/*!
* Used as a scratch buffer by the compute layer renderer.
*/
struct
{
VkExtent2D extent;
struct
{
VkDeviceMemory memory;
VkImage image;
VkImageView srgb_view;
VkImageView unorm_view;
} color;
} scratch;
/*! /*!
* Used as a default image empty image when none is given or to pad * Used as a default image empty image when none is given or to pad
* out fixed sized descriptor sets. * out fixed sized descriptor sets.
@ -452,12 +436,6 @@ render_distortion_images_ensure(struct render_resources *r,
void void
render_distortion_images_close(struct render_resources *r); render_distortion_images_close(struct render_resources *r);
/*!
* Ensure that the scratch image is created and has the given extent.
*/
bool
render_ensure_scratch_image(struct render_resources *r, VkExtent2D extent);
/*! /*!
* Returns the timestamps for when the latest GPU work started and stopped that * Returns the timestamps for when the latest GPU work started and stopped that
* was submitted using @ref render_gfx or @ref render_compute cmd buf builders. * was submitted using @ref render_gfx or @ref render_compute cmd buf builders.
@ -489,6 +467,47 @@ bool
render_resources_get_duration(struct render_resources *r, uint64_t *out_gpu_duration_ns); render_resources_get_duration(struct render_resources *r, uint64_t *out_gpu_duration_ns);
/*
*
* Scratch images.
*
*/
/*!
* Small helper struct to hold a scratch image, intended to be used with the
* compute pipeline where both srgb and unorm views are needed.
*/
struct render_scratch_color_image
{
VkDeviceMemory device_memory;
VkImage image;
VkImageView srgb_view;
VkImageView unorm_view;
};
/*!
* Helper struct to hold scratch images.
*/
struct render_scratch_images
{
VkExtent2D extent;
struct render_scratch_color_image color[2];
};
/*!
* Ensure that the scratch images are created and have the given extent.
*/
bool
render_scratch_images_ensure(struct render_resources *r, struct render_scratch_images *rsi, VkExtent2D extent);
/*!
* Close all resources on the given @ref render_scatch_images.
*/
void
render_scratch_images_close(struct render_resources *r, struct render_scratch_images *rsi);
/* /*
* *
* Shared between both gfx and compute. * Shared between both gfx and compute.

View file

@ -448,12 +448,7 @@ prepare_mock_image_locked(struct vk_bundle *vk, VkCommandBuffer cmd, VkImage dst
*/ */
static bool static bool
create_scratch_image_and_view(struct vk_bundle *vk, create_scratch_image_and_view(struct vk_bundle *vk, VkExtent2D extent, struct render_scratch_color_image *rsci)
VkExtent2D extent,
VkDeviceMemory *out_device_memory,
VkImage *out_image,
VkImageView *out_srgb_view,
VkImageView *out_unorm_view)
{ {
VkFormat srgb_format = VK_FORMAT_R8G8B8A8_SRGB; VkFormat srgb_format = VK_FORMAT_R8G8B8A8_SRGB;
VkFormat unorm_format = VK_FORMAT_R8G8B8A8_UNORM; VkFormat unorm_format = VK_FORMAT_R8G8B8A8_UNORM;
@ -506,24 +501,21 @@ create_scratch_image_and_view(struct vk_bundle *vk,
subresource_range, // subresource_range subresource_range, // subresource_range
&unorm_view)); // out_image_view &unorm_view)); // out_image_view
*out_device_memory = device_memory; rsci->device_memory = device_memory;
*out_image = image; rsci->image = image;
*out_srgb_view = srgb_view; rsci->srgb_view = srgb_view;
*out_unorm_view = unorm_view; rsci->unorm_view = unorm_view;
return true; return true;
} }
static void static void
teardown_scratch_image(struct render_resources *r) teardown_scratch_color_image(struct vk_bundle *vk, struct render_scratch_color_image *rsci)
{ {
struct vk_bundle *vk = r->vk; D(ImageView, rsci->unorm_view);
D(ImageView, rsci->srgb_view);
D(ImageView, r->scratch.color.unorm_view); D(Image, rsci->image);
D(ImageView, r->scratch.color.srgb_view); DF(Memory, rsci->device_memory);
D(Image, r->scratch.color.image);
DF(Memory, r->scratch.color.memory);
U_ZERO(&r->scratch.extent);
} }
@ -942,36 +934,6 @@ render_resources_init(struct render_resources *r,
return true; return true;
} }
bool
render_ensure_scratch_image(struct render_resources *r, VkExtent2D extent)
{
bool bret;
if (r->scratch.extent.width == extent.width && //
r->scratch.extent.height == extent.height && //
r->scratch.color.srgb_view != VK_NULL_HANDLE && //
r->scratch.color.unorm_view != VK_NULL_HANDLE) {
return true;
}
teardown_scratch_image(r);
bret = create_scratch_image_and_view( //
r->vk, //
extent, //
&r->scratch.color.memory, //
&r->scratch.color.image, //
&r->scratch.color.srgb_view, //
&r->scratch.color.unorm_view); //
if (!bret) {
return false;
}
r->scratch.extent = extent;
return true;
}
void void
render_resources_close(struct render_resources *r) render_resources_close(struct render_resources *r)
{ {
@ -1021,8 +983,6 @@ render_resources_close(struct render_resources *r)
} }
render_buffer_close(vk, &r->compute.distortion.ubo); render_buffer_close(vk, &r->compute.distortion.ubo);
teardown_scratch_image(r);
vk_cmd_pool_destroy(vk, &r->distortion_pool); vk_cmd_pool_destroy(vk, &r->distortion_pool);
D(CommandPool, r->cmd_pool); D(CommandPool, r->cmd_pool);
@ -1120,3 +1080,56 @@ render_resources_get_duration(struct render_resources *r, uint64_t *out_gpu_dura
return true; return true;
} }
/*
*
* 'Exported' scratch functions.
*
*/
bool
render_scratch_images_ensure(struct render_resources *r, struct render_scratch_images *rsi, VkExtent2D extent)
{
bool bret;
if (rsi->extent.width == extent.width && //
rsi->extent.height == extent.height && //
rsi->color[0].srgb_view != VK_NULL_HANDLE && //
rsi->color[0].unorm_view != VK_NULL_HANDLE) {
return true;
}
render_scratch_images_close(r, rsi);
for (uint32_t i = 0; i < ARRAY_SIZE(rsi->color); i++) {
bret = create_scratch_image_and_view( //
r->vk, //
extent, //
&rsi->color[i]); //
if (!bret) {
break;
}
}
if (!bret) {
render_scratch_images_close(r, rsi);
return false;
}
rsi->extent = extent;
return true;
}
void
render_scratch_images_close(struct render_resources *r, struct render_scratch_images *rsi)
{
struct vk_bundle *vk = r->vk;
for (uint32_t i = 0; i < ARRAY_SIZE(rsi->color); i++) {
teardown_scratch_color_image(vk, &rsi->color[i]);
}
U_ZERO(&rsi->extent);
}