mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-04 06:06:17 +00:00
c/render: Put distortion image functions in own file
This commit is contained in:
parent
f536ec2009
commit
6598760522
|
@ -142,6 +142,7 @@ if(XRT_HAVE_VULKAN)
|
||||||
${SHADER_HEADERS}
|
${SHADER_HEADERS}
|
||||||
render/render_buffer.c
|
render/render_buffer.c
|
||||||
render/render_compute.c
|
render/render_compute.c
|
||||||
|
render/render_distortion.c
|
||||||
render/render_gfx.c
|
render/render_gfx.c
|
||||||
render/render_interface.h
|
render/render_interface.h
|
||||||
render/render_resources.c
|
render/render_resources.c
|
||||||
|
|
|
@ -538,7 +538,7 @@ renderer_ensure_images_and_renderings(struct comp_renderer *r, bool force_recrea
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo: is it safe to fail here?
|
// @todo: is it safe to fail here?
|
||||||
if (!render_ensure_distortion_buffer(&r->c->nr, &r->c->base.vk, r->c->xdev, pre_rotate))
|
if (!render_distortion_images_ensure(&r->c->nr, &r->c->base.vk, r->c->xdev, pre_rotate))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
r->buffer_count = r->c->target->image_count;
|
r->buffer_count = r->c->target->image_count;
|
||||||
|
|
491
src/xrt/compositor/render/render_distortion.c
Normal file
491
src/xrt/compositor/render/render_distortion.c
Normal file
|
@ -0,0 +1,491 @@
|
||||||
|
// Copyright 2019-2023, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Code for handling distortion resources (not shaders).
|
||||||
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||||
|
* @ingroup comp_render
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xrt/xrt_device.h"
|
||||||
|
|
||||||
|
#include "math/m_api.h"
|
||||||
|
#include "math/m_matrix_2x2.h"
|
||||||
|
#include "math/m_vec2.h"
|
||||||
|
|
||||||
|
#include "render/render_interface.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Helper defines.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* This define will error if `RET` is not `VK_SUCCESS`, printing out that the
|
||||||
|
* `FUNC_STR` string has failed, then goto `GOTO`, `VK` will be used for the
|
||||||
|
* `VK_ERROR` call.
|
||||||
|
*/
|
||||||
|
#define CG(VK, RET, FUNC_STR, GOTO) \
|
||||||
|
do { \
|
||||||
|
VkResult CG_ret = RET; \
|
||||||
|
if (CG_ret != VK_SUCCESS) { \
|
||||||
|
VK_ERROR(VK, FUNC_STR ": %s", vk_result_string(CG_ret)); \
|
||||||
|
goto GOTO; \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calls `vkDestroy##TYPE` on `THING` if it is not `VK_NULL_HANDLE`, sets it to
|
||||||
|
* `VK_NULL_HANDLE` afterwards.
|
||||||
|
*/
|
||||||
|
#define D(TYPE, THING) \
|
||||||
|
if (THING != VK_NULL_HANDLE) { \
|
||||||
|
vk->vkDestroy##TYPE(vk->device, THING, NULL); \
|
||||||
|
THING = VK_NULL_HANDLE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calls `vkFree##TYPE` on `THING` if it is not `VK_NULL_HANDLE`, sets it to
|
||||||
|
* `VK_NULL_HANDLE` afterwards.
|
||||||
|
*/
|
||||||
|
#define DF(TYPE, THING) \
|
||||||
|
if (THING != VK_NULL_HANDLE) { \
|
||||||
|
vk->vkFree##TYPE(vk->device, THING, NULL); \
|
||||||
|
THING = VK_NULL_HANDLE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Helper functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
create_distortion_image_and_view(struct vk_bundle *vk,
|
||||||
|
VkExtent2D extent,
|
||||||
|
VkDeviceMemory *out_device_memory,
|
||||||
|
VkImage *out_image,
|
||||||
|
VkImageView *out_image_view)
|
||||||
|
{
|
||||||
|
VkFormat format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory device_memory = VK_NULL_HANDLE;
|
||||||
|
VkImageView image_view = VK_NULL_HANDLE;
|
||||||
|
VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
VkResult ret;
|
||||||
|
|
||||||
|
ret = vk_create_image_simple( //
|
||||||
|
vk, // vk_bundle
|
||||||
|
extent, // extent
|
||||||
|
format, // format
|
||||||
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
|
||||||
|
&device_memory, // out_device_memory
|
||||||
|
&image); // out_image
|
||||||
|
if (ret != VK_SUCCESS) {
|
||||||
|
VK_ERROR(vk, "vk_create_image_simple: %s", vk_result_string(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageSubresourceRange subresource_range = {
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = vk_create_view( //
|
||||||
|
vk, // vk_bundle
|
||||||
|
image, // image
|
||||||
|
view_type, // type
|
||||||
|
format, // format
|
||||||
|
subresource_range, // subresource_range
|
||||||
|
&image_view); // out_image_view
|
||||||
|
if (ret != VK_SUCCESS) {
|
||||||
|
VK_ERROR(vk, "vk_create_view: %s", vk_result_string(ret));
|
||||||
|
D(Image, image);
|
||||||
|
DF(Memory, device_memory);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_device_memory = device_memory;
|
||||||
|
*out_image = image;
|
||||||
|
*out_image_view = image_view;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_upload_for_first_level_and_layer_locked(
|
||||||
|
struct vk_bundle *vk, VkCommandBuffer cmd, VkBuffer src, VkImage dst, VkExtent2D extent)
|
||||||
|
{
|
||||||
|
VkImageSubresourceRange subresource_range = {
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk_cmd_image_barrier_gpu_locked( //
|
||||||
|
vk, //
|
||||||
|
cmd, //
|
||||||
|
dst, //
|
||||||
|
0, //
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT, //
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED, //
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //
|
||||||
|
subresource_range); //
|
||||||
|
|
||||||
|
VkImageSubresourceLayers subresource_layers = {
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkBufferImageCopy region = {
|
||||||
|
.bufferOffset = 0,
|
||||||
|
.bufferRowLength = 0,
|
||||||
|
.bufferImageHeight = 0,
|
||||||
|
.imageSubresource = subresource_layers,
|
||||||
|
.imageOffset = {0, 0, 0},
|
||||||
|
.imageExtent = {extent.width, extent.height, 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
vk->vkCmdCopyBufferToImage( //
|
||||||
|
cmd, // commandBuffer
|
||||||
|
src, // srcBuffer
|
||||||
|
dst, // dstImage
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // dstImageLayout
|
||||||
|
1, // regionCount
|
||||||
|
®ion); // pRegions
|
||||||
|
|
||||||
|
vk_cmd_image_barrier_gpu_locked( //
|
||||||
|
vk, //
|
||||||
|
cmd, //
|
||||||
|
dst, //
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT, //
|
||||||
|
VK_ACCESS_SHADER_READ_BIT, //
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, //
|
||||||
|
subresource_range); //
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
create_and_queue_upload_locked(struct vk_bundle *vk,
|
||||||
|
struct vk_cmd_pool *pool,
|
||||||
|
VkCommandBuffer cmd,
|
||||||
|
VkBuffer src_buffer,
|
||||||
|
VkDeviceMemory *out_image_device_memory,
|
||||||
|
VkImage *out_image,
|
||||||
|
VkImageView *out_image_view)
|
||||||
|
{
|
||||||
|
VkExtent2D extent = {COMP_DISTORTION_IMAGE_DIMENSIONS, COMP_DISTORTION_IMAGE_DIMENSIONS};
|
||||||
|
VkDeviceMemory device_memory = VK_NULL_HANDLE;
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VkImageView image_view = VK_NULL_HANDLE;
|
||||||
|
VkResult ret;
|
||||||
|
|
||||||
|
ret = create_distortion_image_and_view( //
|
||||||
|
vk, // vk_bundle
|
||||||
|
extent, // extent
|
||||||
|
&device_memory, // out_device_memory
|
||||||
|
&image, // out_image
|
||||||
|
&image_view); // out_image_view
|
||||||
|
if (ret != VK_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue_upload_for_first_level_and_layer_locked( //
|
||||||
|
vk, // vk_bundle
|
||||||
|
cmd, // cmd
|
||||||
|
src_buffer, // src
|
||||||
|
image, // dst
|
||||||
|
extent); // extent
|
||||||
|
|
||||||
|
*out_image_device_memory = device_memory;
|
||||||
|
*out_image = image;
|
||||||
|
*out_image_view = image_view;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Helper struct to make code easier to read.
|
||||||
|
*/
|
||||||
|
struct texture
|
||||||
|
{
|
||||||
|
struct xrt_vec2 pixels[COMP_DISTORTION_IMAGE_DIMENSIONS][COMP_DISTORTION_IMAGE_DIMENSIONS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tan_angles_transforms
|
||||||
|
{
|
||||||
|
struct xrt_vec2 offset;
|
||||||
|
struct xrt_vec2 scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
calc_uv_to_tanangle(struct xrt_device *xdev, uint32_t view, struct xrt_normalized_rect *out_rect)
|
||||||
|
{
|
||||||
|
const struct xrt_fov fov = xdev->hmd->distortion.fov[view];
|
||||||
|
|
||||||
|
const double tan_left = tan(fov.angle_left);
|
||||||
|
const double tan_right = tan(fov.angle_right);
|
||||||
|
|
||||||
|
const double tan_down = tan(fov.angle_down);
|
||||||
|
const double tan_up = tan(fov.angle_up);
|
||||||
|
|
||||||
|
const double tan_width = tan_right - tan_left;
|
||||||
|
const double tan_height = tan_up - tan_down;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I do not know why we have to calculate the offsets like this, but
|
||||||
|
* this one is the one that seems to work with what is currently in the
|
||||||
|
* calc timewarp matrix function and the distortion shader. It works
|
||||||
|
* with Index (unbalanced left and right angles) and WMR (unbalanced up
|
||||||
|
* and down angles) so here it is. In so far it matches what the gfx
|
||||||
|
* and non-timewarp compute pipeline produces.
|
||||||
|
*/
|
||||||
|
const double tan_offset_x = ((tan_right + tan_left) - tan_width) / 2;
|
||||||
|
const double tan_offset_y = (-(tan_up + tan_down) - tan_height) / 2;
|
||||||
|
|
||||||
|
struct xrt_normalized_rect transform = {
|
||||||
|
.x = (float)tan_offset_x,
|
||||||
|
.y = (float)tan_offset_y,
|
||||||
|
.w = (float)tan_width,
|
||||||
|
.h = (float)tan_height,
|
||||||
|
};
|
||||||
|
|
||||||
|
*out_rect = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
static XRT_CHECK_RESULT VkResult
|
||||||
|
create_and_fill_in_distortion_buffer_for_view(struct vk_bundle *vk,
|
||||||
|
struct xrt_device *xdev,
|
||||||
|
struct render_buffer *r_buffer,
|
||||||
|
struct render_buffer *g_buffer,
|
||||||
|
struct render_buffer *b_buffer,
|
||||||
|
uint32_t view,
|
||||||
|
bool pre_rotate)
|
||||||
|
{
|
||||||
|
VkBufferUsageFlags usage_flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||||
|
VkResult ret;
|
||||||
|
|
||||||
|
struct xrt_matrix_2x2 rot = xdev->hmd->views[view].rot;
|
||||||
|
|
||||||
|
const struct xrt_matrix_2x2 rotation_90_cw = {{
|
||||||
|
.vecs =
|
||||||
|
{
|
||||||
|
{0, 1},
|
||||||
|
{-1, 0},
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
|
||||||
|
if (pre_rotate) {
|
||||||
|
m_mat2x2_multiply(&rot, &rotation_90_cw, &rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDeviceSize size = sizeof(struct texture);
|
||||||
|
|
||||||
|
ret = render_buffer_init(vk, r_buffer, usage_flags, properties, size);
|
||||||
|
CG(vk, ret, "render_buffer_init", err_buffers);
|
||||||
|
ret = render_buffer_init(vk, g_buffer, usage_flags, properties, size);
|
||||||
|
CG(vk, ret, "render_buffer_init", err_buffers);
|
||||||
|
ret = render_buffer_init(vk, b_buffer, usage_flags, properties, size);
|
||||||
|
CG(vk, ret, "render_buffer_init", err_buffers);
|
||||||
|
|
||||||
|
ret = render_buffer_map(vk, r_buffer);
|
||||||
|
CG(vk, ret, "render_buffer_map", err_buffers);
|
||||||
|
ret = render_buffer_map(vk, g_buffer);
|
||||||
|
CG(vk, ret, "render_buffer_map", err_buffers);
|
||||||
|
ret = render_buffer_map(vk, b_buffer);
|
||||||
|
CG(vk, ret, "render_buffer_map", err_buffers);
|
||||||
|
|
||||||
|
struct texture *r = r_buffer->mapped;
|
||||||
|
struct texture *g = g_buffer->mapped;
|
||||||
|
struct texture *b = b_buffer->mapped;
|
||||||
|
|
||||||
|
const double dim_minus_one_f64 = COMP_DISTORTION_IMAGE_DIMENSIONS - 1;
|
||||||
|
|
||||||
|
for (int row = 0; row < COMP_DISTORTION_IMAGE_DIMENSIONS; row++) {
|
||||||
|
// This goes from 0 to 1.0 inclusive.
|
||||||
|
float v = (float)(row / dim_minus_one_f64);
|
||||||
|
|
||||||
|
for (int col = 0; col < COMP_DISTORTION_IMAGE_DIMENSIONS; col++) {
|
||||||
|
// This goes from 0 to 1.0 inclusive.
|
||||||
|
float u = (float)(col / dim_minus_one_f64);
|
||||||
|
|
||||||
|
// These need to go from -0.5 to 0.5 for the rotation
|
||||||
|
struct xrt_vec2 uv = {u - 0.5f, v - 0.5f};
|
||||||
|
m_mat2x2_transform_vec2(&rot, &uv, &uv);
|
||||||
|
uv.x += 0.5f;
|
||||||
|
uv.y += 0.5f;
|
||||||
|
|
||||||
|
struct xrt_uv_triplet result;
|
||||||
|
xrt_device_compute_distortion(xdev, view, uv.x, uv.y, &result);
|
||||||
|
|
||||||
|
r->pixels[row][col] = result.r;
|
||||||
|
g->pixels[row][col] = result.g;
|
||||||
|
b->pixels[row][col] = result.b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_buffer_unmap(vk, r_buffer);
|
||||||
|
render_buffer_unmap(vk, g_buffer);
|
||||||
|
render_buffer_unmap(vk, b_buffer);
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
err_buffers:
|
||||||
|
render_buffer_close(vk, r_buffer);
|
||||||
|
render_buffer_close(vk, g_buffer);
|
||||||
|
render_buffer_close(vk, b_buffer);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
render_distortion_buffer_init(struct render_resources *r,
|
||||||
|
struct vk_bundle *vk,
|
||||||
|
struct xrt_device *xdev,
|
||||||
|
bool pre_rotate)
|
||||||
|
{
|
||||||
|
struct render_buffer bufs[COMP_DISTORTION_NUM_IMAGES];
|
||||||
|
VkDeviceMemory device_memories[COMP_DISTORTION_NUM_IMAGES];
|
||||||
|
VkImage images[COMP_DISTORTION_NUM_IMAGES];
|
||||||
|
VkImageView image_views[COMP_DISTORTION_NUM_IMAGES];
|
||||||
|
VkCommandBuffer upload_buffer = VK_NULL_HANDLE;
|
||||||
|
VkResult ret;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basics
|
||||||
|
*/
|
||||||
|
|
||||||
|
static_assert(COMP_DISTORTION_NUM_IMAGES == 6, "Wrong number of distortion images!");
|
||||||
|
|
||||||
|
calc_uv_to_tanangle(xdev, 0, &r->distortion.uv_to_tanangle[0]);
|
||||||
|
calc_uv_to_tanangle(xdev, 1, &r->distortion.uv_to_tanangle[1]);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buffers with data to upload.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = create_and_fill_in_distortion_buffer_for_view(vk, xdev, &bufs[0], &bufs[2], &bufs[4], 0, pre_rotate);
|
||||||
|
CG(vk, ret, "create_and_fill_in_distortion_buffer_for_view", err_resources);
|
||||||
|
|
||||||
|
ret = create_and_fill_in_distortion_buffer_for_view(vk, xdev, &bufs[1], &bufs[3], &bufs[5], 1, pre_rotate);
|
||||||
|
CG(vk, ret, "create_and_fill_in_distortion_buffer_for_view", err_resources);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command submission.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct vk_cmd_pool *pool = &r->distortion_pool;
|
||||||
|
|
||||||
|
vk_cmd_pool_lock(pool);
|
||||||
|
|
||||||
|
ret = vk_cmd_pool_create_and_begin_cmd_buffer_locked(vk, pool, 0, &upload_buffer);
|
||||||
|
CG(vk, ret, "vk_cmd_pool_create_and_begin_cmd_buffer_locked", err_unlock);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
||||||
|
ret = create_and_queue_upload_locked( //
|
||||||
|
vk, // vk_bundle
|
||||||
|
pool, // pool
|
||||||
|
upload_buffer, // cmd
|
||||||
|
bufs[i].buffer, // src_buffer
|
||||||
|
&device_memories[i], // out_image_device_memory
|
||||||
|
&images[i], // out_image
|
||||||
|
&image_views[i]); // out_image_view
|
||||||
|
CG(vk, ret, "create_and_queue_upload_locked", err_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked(vk, pool, upload_buffer);
|
||||||
|
CG(vk, ret, "vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked", err_cmd);
|
||||||
|
|
||||||
|
vk_cmd_pool_unlock(pool);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write results.
|
||||||
|
*/
|
||||||
|
|
||||||
|
r->distortion.pre_rotated = pre_rotate;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
||||||
|
r->distortion.device_memories[i] = device_memories[i];
|
||||||
|
r->distortion.images[i] = images[i];
|
||||||
|
r->distortion.image_views[i] = image_views[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tidy
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
||||||
|
render_buffer_close(vk, &bufs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
err_cmd:
|
||||||
|
vk->vkFreeCommandBuffers(vk->device, pool->pool, 1, &upload_buffer);
|
||||||
|
|
||||||
|
err_unlock:
|
||||||
|
vk_cmd_pool_unlock(pool);
|
||||||
|
|
||||||
|
err_resources:
|
||||||
|
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
||||||
|
D(ImageView, image_views[i]);
|
||||||
|
D(Image, images[i]);
|
||||||
|
DF(Memory, device_memories[i]);
|
||||||
|
render_buffer_close(vk, &bufs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 'Exported' functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
render_distortion_images_close(struct render_resources *r)
|
||||||
|
{
|
||||||
|
struct vk_bundle *vk = r->vk;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(r->distortion.image_views); i++) {
|
||||||
|
D(ImageView, r->distortion.image_views[i]);
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(r->distortion.images); i++) {
|
||||||
|
D(Image, r->distortion.images[i]);
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(r->distortion.device_memories); i++) {
|
||||||
|
DF(Memory, r->distortion.device_memories[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
render_distortion_images_ensure(struct render_resources *r,
|
||||||
|
struct vk_bundle *vk,
|
||||||
|
struct xrt_device *xdev,
|
||||||
|
bool pre_rotate)
|
||||||
|
{
|
||||||
|
if (r->distortion.image_views[0] == VK_NULL_HANDLE || pre_rotate != r->distortion.pre_rotated) {
|
||||||
|
render_distortion_images_close(r);
|
||||||
|
return render_distortion_buffer_init(r, vk, xdev, pre_rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -411,11 +411,17 @@ render_resources_close(struct render_resources *r);
|
||||||
* Creates or recreates the compute distortion textures if necessary.
|
* Creates or recreates the compute distortion textures if necessary.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
render_ensure_distortion_buffer(struct render_resources *r,
|
render_distortion_images_ensure(struct render_resources *r,
|
||||||
struct vk_bundle *vk,
|
struct vk_bundle *vk,
|
||||||
struct xrt_device *xdev,
|
struct xrt_device *xdev,
|
||||||
bool pre_rotate);
|
bool pre_rotate);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Free distortion images.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
render_distortion_images_close(struct render_resources *r);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Ensure that the scratch image is created and has the given extent.
|
* Ensure that the scratch image is created and has the given extent.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -411,291 +411,12 @@ create_compute_distortion_pipeline(struct vk_bundle *vk,
|
||||||
out_compute_pipeline); // out_compute_pipeline
|
out_compute_pipeline); // out_compute_pipeline
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult
|
|
||||||
create_distortion_image_and_view(struct vk_bundle *vk,
|
|
||||||
VkExtent2D extent,
|
|
||||||
VkDeviceMemory *out_device_memory,
|
|
||||||
VkImage *out_image,
|
|
||||||
VkImageView *out_image_view)
|
|
||||||
{
|
|
||||||
VkFormat format = VK_FORMAT_R32G32_SFLOAT;
|
|
||||||
VkImage image = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory device_memory = VK_NULL_HANDLE;
|
|
||||||
VkImageView image_view = VK_NULL_HANDLE;
|
|
||||||
VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
VkResult ret;
|
|
||||||
|
|
||||||
ret = vk_create_image_simple( //
|
|
||||||
vk, // vk_bundle
|
|
||||||
extent, // extent
|
|
||||||
format, // format
|
|
||||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
|
|
||||||
&device_memory, // out_device_memory
|
|
||||||
&image); // out_image
|
|
||||||
if (ret != VK_SUCCESS) {
|
|
||||||
VK_ERROR(vk, "vk_create_image_simple: %s", vk_result_string(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkImageSubresourceRange subresource_range = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = vk_create_view( //
|
|
||||||
vk, // vk_bundle
|
|
||||||
image, // image
|
|
||||||
view_type, // type
|
|
||||||
format, // format
|
|
||||||
subresource_range, // subresource_range
|
|
||||||
&image_view); // out_image_view
|
|
||||||
if (ret != VK_SUCCESS) {
|
|
||||||
VK_ERROR(vk, "vk_create_view: %s", vk_result_string(ret));
|
|
||||||
D(Image, image);
|
|
||||||
DF(Memory, device_memory);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_device_memory = device_memory;
|
|
||||||
*out_image = image;
|
|
||||||
*out_image_view = image_view;
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
queue_upload_for_first_level_and_layer_locked(
|
|
||||||
struct vk_bundle *vk, VkCommandBuffer cmd, VkBuffer src, VkImage dst, VkExtent2D extent)
|
|
||||||
{
|
|
||||||
VkImageSubresourceRange subresource_range = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk_cmd_image_barrier_gpu_locked( //
|
|
||||||
vk, //
|
|
||||||
cmd, //
|
|
||||||
dst, //
|
|
||||||
0, //
|
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT, //
|
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED, //
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //
|
|
||||||
subresource_range); //
|
|
||||||
|
|
||||||
VkImageSubresourceLayers subresource_layers = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.mipLevel = 0,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkBufferImageCopy region = {
|
|
||||||
.bufferOffset = 0,
|
|
||||||
.bufferRowLength = 0,
|
|
||||||
.bufferImageHeight = 0,
|
|
||||||
.imageSubresource = subresource_layers,
|
|
||||||
.imageOffset = {0, 0, 0},
|
|
||||||
.imageExtent = {extent.width, extent.height, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
vk->vkCmdCopyBufferToImage( //
|
|
||||||
cmd, // commandBuffer
|
|
||||||
src, // srcBuffer
|
|
||||||
dst, // dstImage
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // dstImageLayout
|
|
||||||
1, // regionCount
|
|
||||||
®ion); // pRegions
|
|
||||||
|
|
||||||
vk_cmd_image_barrier_gpu_locked( //
|
|
||||||
vk, //
|
|
||||||
cmd, //
|
|
||||||
dst, //
|
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT, //
|
|
||||||
VK_ACCESS_SHADER_READ_BIT, //
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, //
|
|
||||||
subresource_range); //
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkResult
|
|
||||||
create_and_queue_upload_locked(struct vk_bundle *vk,
|
|
||||||
struct vk_cmd_pool *pool,
|
|
||||||
VkCommandBuffer cmd,
|
|
||||||
VkBuffer src_buffer,
|
|
||||||
VkDeviceMemory *out_image_device_memory,
|
|
||||||
VkImage *out_image,
|
|
||||||
VkImageView *out_image_view)
|
|
||||||
{
|
|
||||||
VkExtent2D extent = {COMP_DISTORTION_IMAGE_DIMENSIONS, COMP_DISTORTION_IMAGE_DIMENSIONS};
|
|
||||||
VkDeviceMemory device_memory = VK_NULL_HANDLE;
|
|
||||||
VkImage image = VK_NULL_HANDLE;
|
|
||||||
VkImageView image_view = VK_NULL_HANDLE;
|
|
||||||
VkResult ret;
|
|
||||||
|
|
||||||
ret = create_distortion_image_and_view( //
|
|
||||||
vk, // vk_bundle
|
|
||||||
extent, // extent
|
|
||||||
&device_memory, // out_device_memory
|
|
||||||
&image, // out_image
|
|
||||||
&image_view); // out_image_view
|
|
||||||
if (ret != VK_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_upload_for_first_level_and_layer_locked( //
|
|
||||||
vk, // vk_bundle
|
|
||||||
cmd, // cmd
|
|
||||||
src_buffer, // src
|
|
||||||
image, // dst
|
|
||||||
extent); // extent
|
|
||||||
|
|
||||||
*out_image_device_memory = device_memory;
|
|
||||||
*out_image = image;
|
|
||||||
*out_image_view = image_view;
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Helper struct to make code easier to read.
|
|
||||||
*/
|
|
||||||
struct texture
|
|
||||||
{
|
|
||||||
struct xrt_vec2 pixels[COMP_DISTORTION_IMAGE_DIMENSIONS][COMP_DISTORTION_IMAGE_DIMENSIONS];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tan_angles_transforms
|
|
||||||
{
|
|
||||||
struct xrt_vec2 offset;
|
|
||||||
struct xrt_vec2 scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
calc_uv_to_tanangle(struct xrt_device *xdev, uint32_t view, struct xrt_normalized_rect *out_rect)
|
|
||||||
{
|
|
||||||
const struct xrt_fov fov = xdev->hmd->distortion.fov[view];
|
|
||||||
|
|
||||||
const double tan_left = tan(fov.angle_left);
|
|
||||||
const double tan_right = tan(fov.angle_right);
|
|
||||||
|
|
||||||
const double tan_down = tan(fov.angle_down);
|
|
||||||
const double tan_up = tan(fov.angle_up);
|
|
||||||
|
|
||||||
const double tan_width = tan_right - tan_left;
|
|
||||||
const double tan_height = tan_up - tan_down;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I do not know why we have to calculate the offsets like this, but
|
*
|
||||||
* this one is the one that seems to work with what is currently in the
|
* Mock image.
|
||||||
* calc timewarp matrix function and the distortion shader. It works
|
*
|
||||||
* with Index (unbalanced left and right angles) and WMR (unbalanced up
|
|
||||||
* and down angles) so here it is. In so far it matches what the gfx
|
|
||||||
* and non-timewarp compute pipeline produces.
|
|
||||||
*/
|
*/
|
||||||
const double tan_offset_x = ((tan_right + tan_left) - tan_width) / 2;
|
|
||||||
const double tan_offset_y = (-(tan_up + tan_down) - tan_height) / 2;
|
|
||||||
|
|
||||||
struct xrt_normalized_rect transform = {
|
|
||||||
.x = (float)tan_offset_x,
|
|
||||||
.y = (float)tan_offset_y,
|
|
||||||
.w = (float)tan_width,
|
|
||||||
.h = (float)tan_height,
|
|
||||||
};
|
|
||||||
|
|
||||||
*out_rect = transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
static XRT_CHECK_RESULT VkResult
|
|
||||||
create_and_fill_in_distortion_buffer_for_view(struct vk_bundle *vk,
|
|
||||||
struct xrt_device *xdev,
|
|
||||||
struct render_buffer *r_buffer,
|
|
||||||
struct render_buffer *g_buffer,
|
|
||||||
struct render_buffer *b_buffer,
|
|
||||||
uint32_t view,
|
|
||||||
bool pre_rotate)
|
|
||||||
{
|
|
||||||
VkBufferUsageFlags usage_flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
||||||
VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
|
||||||
VkResult ret;
|
|
||||||
|
|
||||||
struct xrt_matrix_2x2 rot = xdev->hmd->views[view].rot;
|
|
||||||
|
|
||||||
const struct xrt_matrix_2x2 rotation_90_cw = {{
|
|
||||||
.vecs =
|
|
||||||
{
|
|
||||||
{0, 1},
|
|
||||||
{-1, 0},
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
|
|
||||||
if (pre_rotate) {
|
|
||||||
m_mat2x2_multiply(&rot, &rotation_90_cw, &rot);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDeviceSize size = sizeof(struct texture);
|
|
||||||
|
|
||||||
ret = render_buffer_init(vk, r_buffer, usage_flags, properties, size);
|
|
||||||
CG(vk, ret, "render_buffer_init", err_buffers);
|
|
||||||
ret = render_buffer_init(vk, g_buffer, usage_flags, properties, size);
|
|
||||||
CG(vk, ret, "render_buffer_init", err_buffers);
|
|
||||||
ret = render_buffer_init(vk, b_buffer, usage_flags, properties, size);
|
|
||||||
CG(vk, ret, "render_buffer_init", err_buffers);
|
|
||||||
|
|
||||||
ret = render_buffer_map(vk, r_buffer);
|
|
||||||
CG(vk, ret, "render_buffer_map", err_buffers);
|
|
||||||
ret = render_buffer_map(vk, g_buffer);
|
|
||||||
CG(vk, ret, "render_buffer_map", err_buffers);
|
|
||||||
ret = render_buffer_map(vk, b_buffer);
|
|
||||||
CG(vk, ret, "render_buffer_map", err_buffers);
|
|
||||||
|
|
||||||
struct texture *r = r_buffer->mapped;
|
|
||||||
struct texture *g = g_buffer->mapped;
|
|
||||||
struct texture *b = b_buffer->mapped;
|
|
||||||
|
|
||||||
const double dim_minus_one_f64 = COMP_DISTORTION_IMAGE_DIMENSIONS - 1;
|
|
||||||
|
|
||||||
for (int row = 0; row < COMP_DISTORTION_IMAGE_DIMENSIONS; row++) {
|
|
||||||
// This goes from 0 to 1.0 inclusive.
|
|
||||||
float v = (float)(row / dim_minus_one_f64);
|
|
||||||
|
|
||||||
for (int col = 0; col < COMP_DISTORTION_IMAGE_DIMENSIONS; col++) {
|
|
||||||
// This goes from 0 to 1.0 inclusive.
|
|
||||||
float u = (float)(col / dim_minus_one_f64);
|
|
||||||
|
|
||||||
// These need to go from -0.5 to 0.5 for the rotation
|
|
||||||
struct xrt_vec2 uv = {u - 0.5f, v - 0.5f};
|
|
||||||
m_mat2x2_transform_vec2(&rot, &uv, &uv);
|
|
||||||
uv.x += 0.5f;
|
|
||||||
uv.y += 0.5f;
|
|
||||||
|
|
||||||
struct xrt_uv_triplet result;
|
|
||||||
xrt_device_compute_distortion(xdev, view, uv.x, uv.y, &result);
|
|
||||||
|
|
||||||
r->pixels[row][col] = result.r;
|
|
||||||
g->pixels[row][col] = result.g;
|
|
||||||
b->pixels[row][col] = result.b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render_buffer_unmap(vk, r_buffer);
|
|
||||||
render_buffer_unmap(vk, g_buffer);
|
|
||||||
render_buffer_unmap(vk, b_buffer);
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
|
||||||
|
|
||||||
err_buffers:
|
|
||||||
render_buffer_close(vk, r_buffer);
|
|
||||||
render_buffer_close(vk, g_buffer);
|
|
||||||
render_buffer_close(vk, b_buffer);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkResult
|
static VkResult
|
||||||
prepare_mock_image_locked(struct vk_bundle *vk, VkCommandBuffer cmd, VkImage dst)
|
prepare_mock_image_locked(struct vk_bundle *vk, VkCommandBuffer cmd, VkImage dst)
|
||||||
|
@ -1200,140 +921,6 @@ render_resources_init(struct render_resources *r,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
render_distortion_buffer_init(struct render_resources *r,
|
|
||||||
struct vk_bundle *vk,
|
|
||||||
struct xrt_device *xdev,
|
|
||||||
bool pre_rotate)
|
|
||||||
{
|
|
||||||
struct render_buffer bufs[COMP_DISTORTION_NUM_IMAGES];
|
|
||||||
VkDeviceMemory device_memories[COMP_DISTORTION_NUM_IMAGES];
|
|
||||||
VkImage images[COMP_DISTORTION_NUM_IMAGES];
|
|
||||||
VkImageView image_views[COMP_DISTORTION_NUM_IMAGES];
|
|
||||||
VkCommandBuffer upload_buffer = VK_NULL_HANDLE;
|
|
||||||
VkResult ret;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Basics
|
|
||||||
*/
|
|
||||||
|
|
||||||
static_assert(COMP_DISTORTION_NUM_IMAGES == 6, "Wrong number of distortion images!");
|
|
||||||
|
|
||||||
calc_uv_to_tanangle(xdev, 0, &r->distortion.uv_to_tanangle[0]);
|
|
||||||
calc_uv_to_tanangle(xdev, 1, &r->distortion.uv_to_tanangle[1]);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Buffers with data to upload.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = create_and_fill_in_distortion_buffer_for_view(vk, xdev, &bufs[0], &bufs[2], &bufs[4], 0, pre_rotate);
|
|
||||||
CG(vk, ret, "create_and_fill_in_distortion_buffer_for_view", err_resources);
|
|
||||||
|
|
||||||
ret = create_and_fill_in_distortion_buffer_for_view(vk, xdev, &bufs[1], &bufs[3], &bufs[5], 1, pre_rotate);
|
|
||||||
CG(vk, ret, "create_and_fill_in_distortion_buffer_for_view", err_resources);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Command submission.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct vk_cmd_pool *pool = &r->distortion_pool;
|
|
||||||
|
|
||||||
vk_cmd_pool_lock(pool);
|
|
||||||
|
|
||||||
ret = vk_cmd_pool_create_and_begin_cmd_buffer_locked(vk, pool, 0, &upload_buffer);
|
|
||||||
CG(vk, ret, "vk_cmd_pool_create_and_begin_cmd_buffer_locked", err_unlock);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
|
||||||
ret = create_and_queue_upload_locked( //
|
|
||||||
vk, // vk_bundle
|
|
||||||
pool, // pool
|
|
||||||
upload_buffer, // cmd
|
|
||||||
bufs[i].buffer, // src_buffer
|
|
||||||
&device_memories[i], // out_image_device_memory
|
|
||||||
&images[i], // out_image
|
|
||||||
&image_views[i]); // out_image_view
|
|
||||||
CG(vk, ret, "create_and_queue_upload_locked", err_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked(vk, pool, upload_buffer);
|
|
||||||
CG(vk, ret, "vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked", err_cmd);
|
|
||||||
|
|
||||||
vk_cmd_pool_unlock(pool);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write results.
|
|
||||||
*/
|
|
||||||
|
|
||||||
r->distortion.pre_rotated = pre_rotate;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
|
||||||
r->distortion.device_memories[i] = device_memories[i];
|
|
||||||
r->distortion.images[i] = images[i];
|
|
||||||
r->distortion.image_views[i] = image_views[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tidy
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
|
||||||
render_buffer_close(vk, &bufs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
|
||||||
err_cmd:
|
|
||||||
vk->vkFreeCommandBuffers(vk->device, pool->pool, 1, &upload_buffer);
|
|
||||||
|
|
||||||
err_unlock:
|
|
||||||
vk_cmd_pool_unlock(pool);
|
|
||||||
|
|
||||||
err_resources:
|
|
||||||
for (uint32_t i = 0; i < COMP_DISTORTION_NUM_IMAGES; i++) {
|
|
||||||
D(ImageView, image_views[i]);
|
|
||||||
D(Image, images[i]);
|
|
||||||
DF(Memory, device_memories[i]);
|
|
||||||
render_buffer_close(vk, &bufs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
render_distortion_buffer_close(struct render_resources *r)
|
|
||||||
{
|
|
||||||
struct vk_bundle *vk = r->vk;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(r->distortion.image_views); i++) {
|
|
||||||
D(ImageView, r->distortion.image_views[i]);
|
|
||||||
}
|
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(r->distortion.images); i++) {
|
|
||||||
D(Image, r->distortion.images[i]);
|
|
||||||
}
|
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(r->distortion.device_memories); i++) {
|
|
||||||
DF(Memory, r->distortion.device_memories[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
render_ensure_distortion_buffer(struct render_resources *r,
|
|
||||||
struct vk_bundle *vk,
|
|
||||||
struct xrt_device *xdev,
|
|
||||||
bool pre_rotate)
|
|
||||||
{
|
|
||||||
if (r->distortion.image_views[0] == VK_NULL_HANDLE || pre_rotate != r->distortion.pre_rotated) {
|
|
||||||
render_distortion_buffer_close(r);
|
|
||||||
return render_distortion_buffer_init(r, vk, xdev, pre_rotate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
render_ensure_scratch_image(struct render_resources *r, VkExtent2D extent)
|
render_ensure_scratch_image(struct render_resources *r, VkExtent2D extent)
|
||||||
{
|
{
|
||||||
|
@ -1403,7 +990,7 @@ render_resources_close(struct render_resources *r)
|
||||||
|
|
||||||
D(Sampler, r->compute.default_sampler);
|
D(Sampler, r->compute.default_sampler);
|
||||||
|
|
||||||
render_distortion_buffer_close(r);
|
render_distortion_images_close(r);
|
||||||
render_buffer_close(vk, &r->compute.clear.ubo);
|
render_buffer_close(vk, &r->compute.clear.ubo);
|
||||||
render_buffer_close(vk, &r->compute.layer.ubo);
|
render_buffer_close(vk, &r->compute.layer.ubo);
|
||||||
render_buffer_close(vk, &r->compute.distortion.ubo);
|
render_buffer_close(vk, &r->compute.distortion.ubo);
|
||||||
|
|
Loading…
Reference in a new issue