mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-23 07:01:55 +00:00
720 lines
23 KiB
C
720 lines
23 KiB
C
// Copyright 2019-2022, Collabora, Ltd.
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
/*!
|
|
* @file
|
|
* @brief The compositor compute based rendering code.
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
* @ingroup comp_render
|
|
*/
|
|
|
|
#include "math/m_api.h"
|
|
#include "math/m_matrix_4x4_f64.h"
|
|
|
|
#include "render/render_interface.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
/*
|
|
*
|
|
* Defines
|
|
*
|
|
*/
|
|
|
|
#define C(c) \
|
|
do { \
|
|
VkResult ret = c; \
|
|
if (ret != VK_SUCCESS) { \
|
|
return false; \
|
|
} \
|
|
} while (false)
|
|
|
|
#define D(TYPE, thing) \
|
|
if (thing != VK_NULL_HANDLE) { \
|
|
vk->vkDestroy##TYPE(vk, vk->device, thing, NULL); \
|
|
thing = VK_NULL_HANDLE; \
|
|
}
|
|
|
|
#define DD(pool, thing) \
|
|
if (thing != VK_NULL_HANDLE) { \
|
|
free_descriptor_set(vk, pool, thing); \
|
|
thing = VK_NULL_HANDLE; \
|
|
}
|
|
|
|
|
|
/*
|
|
*
|
|
* Helper functions.
|
|
*
|
|
*/
|
|
|
|
/*!
|
|
* Get the @ref vk_bundle from @ref render_compute.
|
|
*/
|
|
static inline struct vk_bundle *
|
|
vk_from_crc(struct render_compute *crc)
|
|
{
|
|
return crc->r->vk;
|
|
}
|
|
|
|
/*
|
|
* For dispatching compute to the view, calculate the number of groups.
|
|
*/
|
|
static void
|
|
calc_dispatch_dims(const struct render_viewport_data views[2], uint32_t *out_w, uint32_t *out_h)
|
|
{
|
|
#define IMAX(a, b) ((a) > (b) ? (a) : (b))
|
|
uint32_t w = IMAX(views[0].w, views[1].w);
|
|
uint32_t h = IMAX(views[0].h, views[1].h);
|
|
#undef IMAX
|
|
|
|
// Power of two divide and round up.
|
|
#define P2_DIVIDE_ROUND_UP(v, div) ((v + (div - 1)) / div)
|
|
w = P2_DIVIDE_ROUND_UP(w, 8);
|
|
h = P2_DIVIDE_ROUND_UP(h, 8);
|
|
#undef P2_DIVIDE_ROUND_UP
|
|
|
|
*out_w = w;
|
|
*out_h = h;
|
|
}
|
|
|
|
|
|
/*
|
|
*
|
|
* Vulkan helpers.
|
|
*
|
|
*/
|
|
|
|
XRT_MAYBE_UNUSED static void
|
|
update_compute_discriptor_set(struct vk_bundle *vk,
|
|
uint32_t src_binding,
|
|
VkSampler src_samplers[2],
|
|
VkImageView src_image_views[2],
|
|
uint32_t distortion_binding,
|
|
VkSampler distortion_samplers[6],
|
|
VkImageView distortion_image_views[6],
|
|
uint32_t target_binding,
|
|
VkImageView target_image_view,
|
|
uint32_t ubo_binding,
|
|
VkBuffer ubo_buffer,
|
|
VkDeviceSize ubo_size,
|
|
VkDescriptorSet descriptor_set)
|
|
{
|
|
VkDescriptorImageInfo src_image_info[2] = {
|
|
{
|
|
.sampler = src_samplers[0],
|
|
.imageView = src_image_views[0],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
{
|
|
.sampler = src_samplers[1],
|
|
.imageView = src_image_views[1],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
};
|
|
|
|
VkDescriptorImageInfo distortion_image_info[6] = {
|
|
{
|
|
.sampler = distortion_samplers[0],
|
|
.imageView = distortion_image_views[0],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
{
|
|
.sampler = distortion_samplers[1],
|
|
.imageView = distortion_image_views[1],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
{
|
|
.sampler = distortion_samplers[2],
|
|
.imageView = distortion_image_views[2],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
{
|
|
.sampler = distortion_samplers[3],
|
|
.imageView = distortion_image_views[3],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
{
|
|
.sampler = distortion_samplers[4],
|
|
.imageView = distortion_image_views[4],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
{
|
|
.sampler = distortion_samplers[5],
|
|
.imageView = distortion_image_views[5],
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
},
|
|
};
|
|
|
|
VkDescriptorImageInfo target_image_info = {
|
|
.imageView = target_image_view,
|
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
};
|
|
|
|
VkDescriptorBufferInfo buffer_info = {
|
|
.buffer = ubo_buffer,
|
|
.offset = 0,
|
|
.range = ubo_size,
|
|
};
|
|
|
|
VkWriteDescriptorSet write_descriptor_sets[4] = {
|
|
{
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.dstSet = descriptor_set,
|
|
.dstBinding = src_binding,
|
|
.descriptorCount = ARRAY_SIZE(src_image_info),
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
.pImageInfo = src_image_info,
|
|
},
|
|
{
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.dstSet = descriptor_set,
|
|
.dstBinding = distortion_binding,
|
|
.descriptorCount = ARRAY_SIZE(distortion_image_info),
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
.pImageInfo = distortion_image_info,
|
|
},
|
|
{
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.dstSet = descriptor_set,
|
|
.dstBinding = target_binding,
|
|
.descriptorCount = 1,
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
.pImageInfo = &target_image_info,
|
|
},
|
|
{
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.dstSet = descriptor_set,
|
|
.dstBinding = ubo_binding,
|
|
.descriptorCount = 1,
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
.pBufferInfo = &buffer_info,
|
|
},
|
|
};
|
|
|
|
vk->vkUpdateDescriptorSets( //
|
|
vk->device, //
|
|
ARRAY_SIZE(write_descriptor_sets), // descriptorWriteCount
|
|
write_descriptor_sets, // pDescriptorWrites
|
|
0, // descriptorCopyCount
|
|
NULL); // pDescriptorCopies
|
|
}
|
|
|
|
XRT_MAYBE_UNUSED static void
|
|
update_compute_discriptor_set_target(struct vk_bundle *vk,
|
|
uint32_t target_binding,
|
|
VkImageView target_image_view,
|
|
uint32_t ubo_binding,
|
|
VkBuffer ubo_buffer,
|
|
VkDeviceSize ubo_size,
|
|
VkDescriptorSet descriptor_set)
|
|
{
|
|
VkDescriptorImageInfo target_image_info = {
|
|
.imageView = target_image_view,
|
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
};
|
|
|
|
VkDescriptorBufferInfo buffer_info = {
|
|
.buffer = ubo_buffer,
|
|
.offset = 0,
|
|
.range = ubo_size,
|
|
};
|
|
|
|
VkWriteDescriptorSet write_descriptor_sets[2] = {
|
|
{
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.dstSet = descriptor_set,
|
|
.dstBinding = target_binding,
|
|
.descriptorCount = 1,
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
.pImageInfo = &target_image_info,
|
|
},
|
|
{
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
.dstSet = descriptor_set,
|
|
.dstBinding = ubo_binding,
|
|
.descriptorCount = 1,
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
.pBufferInfo = &buffer_info,
|
|
},
|
|
};
|
|
|
|
vk->vkUpdateDescriptorSets( //
|
|
vk->device, //
|
|
ARRAY_SIZE(write_descriptor_sets), // descriptorWriteCount
|
|
write_descriptor_sets, // pDescriptorWrites
|
|
0, // descriptorCopyCount
|
|
NULL); // pDescriptorCopies
|
|
}
|
|
|
|
|
|
/*
|
|
*
|
|
* 'Exported' functions.
|
|
*
|
|
*/
|
|
|
|
bool
|
|
render_compute_init(struct render_compute *crc, struct render_resources *r)
|
|
{
|
|
assert(crc->r == NULL);
|
|
|
|
struct vk_bundle *vk = r->vk;
|
|
crc->r = r;
|
|
|
|
C(vk_create_command_buffer(vk, &crc->cmd));
|
|
|
|
C(vk_create_descriptor_set( //
|
|
vk, //
|
|
r->compute.descriptor_pool, // descriptor_pool
|
|
r->compute.descriptor_set_layout, // descriptor_set_layout
|
|
&crc->descriptor_set)); // descriptor_set
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
render_compute_begin(struct render_compute *crc)
|
|
{
|
|
struct vk_bundle *vk = vk_from_crc(crc);
|
|
|
|
os_mutex_lock(&vk->cmd_pool_mutex);
|
|
VkResult ret = vk_begin_command_buffer(vk, crc->cmd);
|
|
if (ret != VK_SUCCESS) {
|
|
os_mutex_unlock(&vk->cmd_pool_mutex);
|
|
return false;
|
|
}
|
|
|
|
vk->vkCmdResetQueryPool( //
|
|
crc->cmd, // commandBuffer
|
|
crc->r->query_pool, // queryPool
|
|
0, // firstQuery
|
|
2); // queryCount
|
|
|
|
vk->vkCmdWriteTimestamp( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // pipelineStage
|
|
crc->r->query_pool, // queryPool
|
|
0); // query
|
|
|
|
// Yes we leave the mutex locked.
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
render_compute_end(struct render_compute *crc)
|
|
{
|
|
struct vk_bundle *vk = vk_from_crc(crc);
|
|
|
|
vk->vkCmdWriteTimestamp( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // pipelineStage
|
|
crc->r->query_pool, // queryPool
|
|
1); // query
|
|
|
|
VkResult ret = vk_end_command_buffer(vk, crc->cmd);
|
|
os_mutex_unlock(&vk->cmd_pool_mutex);
|
|
if (ret != VK_SUCCESS) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
render_compute_close(struct render_compute *crc)
|
|
{
|
|
assert(crc->r != NULL);
|
|
|
|
struct vk_bundle *vk = vk_from_crc(crc);
|
|
|
|
vk_destroy_command_buffer(vk, crc->cmd);
|
|
|
|
// Reclaimed by vkResetDescriptorPool.
|
|
crc->descriptor_set = VK_NULL_HANDLE;
|
|
|
|
vk->vkResetDescriptorPool(vk->device, crc->r->compute.descriptor_pool, 0);
|
|
|
|
crc->r = NULL;
|
|
}
|
|
|
|
void
|
|
render_compute_projection_timewarp(struct render_compute *crc,
|
|
VkSampler src_samplers[2],
|
|
VkImageView src_image_views[2],
|
|
const struct xrt_normalized_rect src_norm_rects[2],
|
|
const struct xrt_pose src_poses[2],
|
|
const struct xrt_fov src_fovs[2],
|
|
const struct xrt_pose new_poses[2],
|
|
VkImage target_image,
|
|
VkImageView target_image_view,
|
|
const struct render_viewport_data views[2])
|
|
{
|
|
assert(crc->r != NULL);
|
|
|
|
struct vk_bundle *vk = vk_from_crc(crc);
|
|
struct render_resources *r = crc->r;
|
|
|
|
|
|
/*
|
|
* UBO
|
|
*/
|
|
|
|
struct xrt_matrix_4x4 time_warp_matrix[2];
|
|
render_calc_time_warp_matrix( //
|
|
&src_poses[0], //
|
|
&src_fovs[0], //
|
|
&new_poses[0], //
|
|
&time_warp_matrix[0]); //
|
|
render_calc_time_warp_matrix( //
|
|
&src_poses[1], //
|
|
&src_fovs[1], //
|
|
&new_poses[1], //
|
|
&time_warp_matrix[1]); //
|
|
|
|
struct render_compute_distortion_ubo_data *data =
|
|
(struct render_compute_distortion_ubo_data *)r->compute.ubo.mapped;
|
|
data->views[0] = views[0];
|
|
data->views[1] = views[1];
|
|
data->pre_transforms[0] = r->distortion.uv_to_tanangle[0];
|
|
data->pre_transforms[1] = r->distortion.uv_to_tanangle[1];
|
|
data->transforms[0] = time_warp_matrix[0];
|
|
data->transforms[1] = time_warp_matrix[1];
|
|
data->post_transforms[0] = src_norm_rects[0];
|
|
data->post_transforms[1] = src_norm_rects[1];
|
|
|
|
|
|
/*
|
|
* Source, target and distortion images.
|
|
*/
|
|
|
|
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, //
|
|
crc->cmd, //
|
|
target_image, //
|
|
0, //
|
|
VK_ACCESS_SHADER_WRITE_BIT, //
|
|
VK_IMAGE_LAYOUT_UNDEFINED, //
|
|
VK_IMAGE_LAYOUT_GENERAL, //
|
|
subresource_range); //
|
|
|
|
VkSampler sampler = r->compute.default_sampler;
|
|
VkSampler distortion_samplers[6] = {
|
|
sampler, sampler, sampler, sampler, sampler, sampler,
|
|
};
|
|
|
|
update_compute_discriptor_set( //
|
|
vk, //
|
|
r->compute.src_binding, //
|
|
src_samplers, //
|
|
src_image_views, //
|
|
r->compute.distortion_binding, //
|
|
distortion_samplers, //
|
|
r->distortion.image_views, //
|
|
r->compute.target_binding, //
|
|
target_image_view, //
|
|
r->compute.ubo_binding, //
|
|
r->compute.ubo.buffer, //
|
|
VK_WHOLE_SIZE, //
|
|
crc->descriptor_set); //
|
|
|
|
vk->vkCmdBindPipeline( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
|
|
r->compute.distortion_timewarp_pipeline); // pipeline
|
|
|
|
vk->vkCmdBindDescriptorSets( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
|
|
r->compute.pipeline_layout, // layout
|
|
0, // firstSet
|
|
1, // descriptorSetCount
|
|
&crc->descriptor_set, // pDescriptorSets
|
|
0, // dynamicOffsetCount
|
|
NULL); // pDynamicOffsets
|
|
|
|
|
|
uint32_t w = 0, h = 0;
|
|
calc_dispatch_dims(views, &w, &h);
|
|
assert(w != 0 && h != 0);
|
|
|
|
vk->vkCmdDispatch( //
|
|
crc->cmd, // commandBuffer
|
|
w, // groupCountX
|
|
h, // groupCountY
|
|
2); // groupCountZ
|
|
|
|
VkImageMemoryBarrier memoryBarrier = {
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
|
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.image = target_image,
|
|
.subresourceRange = subresource_range,
|
|
};
|
|
|
|
vk->vkCmdPipelineBarrier( //
|
|
crc->cmd, //
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, //
|
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, //
|
|
0, //
|
|
0, //
|
|
NULL, //
|
|
0, //
|
|
NULL, //
|
|
1, //
|
|
&memoryBarrier); //
|
|
}
|
|
|
|
void
|
|
render_compute_projection(struct render_compute *crc,
|
|
VkSampler src_samplers[2],
|
|
VkImageView src_image_views[2],
|
|
const struct xrt_normalized_rect src_norm_rects[2],
|
|
VkImage target_image,
|
|
VkImageView target_image_view,
|
|
const struct render_viewport_data views[2])
|
|
{
|
|
assert(crc->r != NULL);
|
|
|
|
struct vk_bundle *vk = vk_from_crc(crc);
|
|
struct render_resources *r = crc->r;
|
|
|
|
|
|
/*
|
|
* UBO
|
|
*/
|
|
|
|
struct render_compute_distortion_ubo_data *data =
|
|
(struct render_compute_distortion_ubo_data *)r->compute.ubo.mapped;
|
|
data->views[0] = views[0];
|
|
data->views[1] = views[1];
|
|
data->post_transforms[0] = src_norm_rects[0];
|
|
data->post_transforms[1] = src_norm_rects[1];
|
|
|
|
|
|
/*
|
|
* Source, target and distortion images.
|
|
*/
|
|
|
|
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, //
|
|
crc->cmd, //
|
|
target_image, //
|
|
0, //
|
|
VK_ACCESS_SHADER_WRITE_BIT, //
|
|
VK_IMAGE_LAYOUT_UNDEFINED, //
|
|
VK_IMAGE_LAYOUT_GENERAL, //
|
|
subresource_range); //
|
|
|
|
VkSampler sampler = r->compute.default_sampler;
|
|
VkSampler distortion_samplers[6] = {
|
|
sampler, sampler, sampler, sampler, sampler, sampler,
|
|
};
|
|
|
|
update_compute_discriptor_set( //
|
|
vk, //
|
|
r->compute.src_binding, //
|
|
src_samplers, //
|
|
src_image_views, //
|
|
r->compute.distortion_binding, //
|
|
distortion_samplers, //
|
|
r->distortion.image_views, //
|
|
r->compute.target_binding, //
|
|
target_image_view, //
|
|
r->compute.ubo_binding, //
|
|
r->compute.ubo.buffer, //
|
|
VK_WHOLE_SIZE, //
|
|
crc->descriptor_set); //
|
|
|
|
vk->vkCmdBindPipeline( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
|
|
r->compute.distortion_pipeline); // pipeline
|
|
|
|
vk->vkCmdBindDescriptorSets( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
|
|
r->compute.pipeline_layout, // layout
|
|
0, // firstSet
|
|
1, // descriptorSetCount
|
|
&crc->descriptor_set, // pDescriptorSets
|
|
0, // dynamicOffsetCount
|
|
NULL); // pDynamicOffsets
|
|
|
|
|
|
uint32_t w = 0, h = 0;
|
|
calc_dispatch_dims(views, &w, &h);
|
|
assert(w != 0 && h != 0);
|
|
|
|
vk->vkCmdDispatch( //
|
|
crc->cmd, // commandBuffer
|
|
w, // groupCountX
|
|
h, // groupCountY
|
|
2); // groupCountZ
|
|
|
|
VkImageMemoryBarrier memoryBarrier = {
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
|
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.image = target_image,
|
|
.subresourceRange = subresource_range,
|
|
};
|
|
|
|
vk->vkCmdPipelineBarrier( //
|
|
crc->cmd, //
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, //
|
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, //
|
|
0, //
|
|
0, //
|
|
NULL, //
|
|
0, //
|
|
NULL, //
|
|
1, //
|
|
&memoryBarrier); //
|
|
}
|
|
|
|
void
|
|
render_compute_clear(struct render_compute *crc, //
|
|
VkImage target_image, //
|
|
VkImageView target_image_view, //
|
|
const struct render_viewport_data views[2]) //
|
|
{
|
|
assert(crc->r != NULL);
|
|
|
|
struct vk_bundle *vk = vk_from_crc(crc);
|
|
struct render_resources *r = crc->r;
|
|
|
|
|
|
/*
|
|
* UBO
|
|
*/
|
|
|
|
// Calculate transforms.
|
|
struct xrt_matrix_4x4 transforms[2];
|
|
for (uint32_t i = 0; i < 2; i++) {
|
|
math_matrix_4x4_identity(&transforms[i]);
|
|
}
|
|
|
|
struct render_compute_distortion_ubo_data *data =
|
|
(struct render_compute_distortion_ubo_data *)r->compute.ubo.mapped;
|
|
data->views[0] = views[0];
|
|
data->views[1] = views[1];
|
|
|
|
|
|
/*
|
|
* Source, target and distortion images.
|
|
*/
|
|
|
|
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, //
|
|
crc->cmd, //
|
|
target_image, //
|
|
0, //
|
|
VK_ACCESS_SHADER_WRITE_BIT, //
|
|
VK_IMAGE_LAYOUT_UNDEFINED, //
|
|
VK_IMAGE_LAYOUT_GENERAL, //
|
|
subresource_range); //
|
|
|
|
VkSampler sampler = r->compute.default_sampler;
|
|
VkSampler src_samplers[2] = {sampler, sampler};
|
|
VkImageView src_image_views[2] = {r->scratch.color.image_view, r->scratch.color.image_view};
|
|
VkSampler distortion_samplers[6] = {sampler, sampler, sampler, sampler, sampler, sampler};
|
|
|
|
update_compute_discriptor_set( //
|
|
vk, // vk_bundle
|
|
r->compute.src_binding, // src_binding
|
|
src_samplers, // src_samplers[2]
|
|
src_image_views, // src_image_views[2]
|
|
r->compute.distortion_binding, // distortion_binding
|
|
distortion_samplers, // distortion_samplers[6]
|
|
r->distortion.image_views, // distortion_image_views[6]
|
|
r->compute.target_binding, // target_binding
|
|
target_image_view, // target_image_view
|
|
r->compute.ubo_binding, // ubo_binding
|
|
r->compute.ubo.buffer, // ubo_buffer
|
|
VK_WHOLE_SIZE, // ubo_size
|
|
crc->descriptor_set); // descriptor_set
|
|
|
|
vk->vkCmdBindPipeline( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
|
|
r->compute.clear_pipeline); // pipeline
|
|
|
|
vk->vkCmdBindDescriptorSets( //
|
|
crc->cmd, // commandBuffer
|
|
VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
|
|
r->compute.pipeline_layout, // layout
|
|
0, // firstSet
|
|
1, // descriptorSetCount
|
|
&crc->descriptor_set, // pDescriptorSets
|
|
0, // dynamicOffsetCount
|
|
NULL); // pDynamicOffsets
|
|
|
|
|
|
uint32_t w = 0, h = 0;
|
|
calc_dispatch_dims(views, &w, &h);
|
|
assert(w != 0 && h != 0);
|
|
|
|
vk->vkCmdDispatch( //
|
|
crc->cmd, // commandBuffer
|
|
w, // groupCountX
|
|
h, // groupCountY
|
|
2); // groupCountZ
|
|
|
|
VkImageMemoryBarrier memoryBarrier = {
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
|
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
|
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
.image = target_image,
|
|
.subresourceRange = subresource_range,
|
|
};
|
|
|
|
vk->vkCmdPipelineBarrier( //
|
|
crc->cmd, //
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, //
|
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, //
|
|
0, //
|
|
0, //
|
|
NULL, //
|
|
0, //
|
|
NULL, //
|
|
1, //
|
|
&memoryBarrier); //
|
|
}
|