monado/src/xrt/compositor/render/comp_resources.c

334 lines
9.8 KiB
C
Raw Normal View History

// Copyright 2019-2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Shared resources for rendering.
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup comp_main
*/
#include "main/comp_compositor.h"
#include "render/comp_render.h"
#include <stdio.h>
#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->device, thing, NULL); \
thing = VK_NULL_HANDLE; \
}
static VkResult
create_pipeline_cache(struct vk_bundle *vk, VkPipelineCache *out_pipeline_cache)
{
VkResult ret;
VkPipelineCacheCreateInfo pipeline_cache_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
};
VkPipelineCache pipeline_cache;
ret = vk->vkCreatePipelineCache(vk->device, //
&pipeline_cache_info, //
NULL, //
&pipeline_cache); //
if (ret != VK_SUCCESS) {
COMP_ERROR(vk, "vkCreatePipelineCache failed: %s",
vk_result_string(ret));
return ret;
}
*out_pipeline_cache = pipeline_cache;
return VK_SUCCESS;
}
static VkResult
create_pipeline_layout(struct vk_bundle *vk,
VkDescriptorSetLayout descriptor_set_layout,
VkPipelineLayout *out_pipeline_layout)
{
VkResult ret;
VkPipelineLayoutCreateInfo pipeline_layout_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &descriptor_set_layout,
};
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
ret = vk->vkCreatePipelineLayout(vk->device, //
&pipeline_layout_info, //
NULL, //
&pipeline_layout); //
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkCreatePipelineLayout failed: %s",
vk_result_string(ret));
return ret;
}
*out_pipeline_layout = pipeline_layout;
return VK_SUCCESS;
}
static VkResult
create_descriptor_pool(struct vk_bundle *vk,
uint32_t num_uniform_per_desc,
uint32_t num_sampler_per_desc,
uint32_t num_descs,
VkDescriptorPool *out_descriptor_pool)
{
VkResult ret;
VkDescriptorPoolSize pool_sizes[2] = {
{
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = num_uniform_per_desc * num_descs,
},
{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = num_sampler_per_desc * num_descs,
},
};
VkDescriptorPoolCreateInfo descriptor_pool_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
.maxSets = num_descs,
.poolSizeCount = ARRAY_SIZE(pool_sizes),
.pPoolSizes = pool_sizes,
};
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
ret = vk->vkCreateDescriptorPool(vk->device, //
&descriptor_pool_info, //
NULL, //
&descriptor_pool); //
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkCreateRenderPass failed: %s",
vk_result_string(ret));
return ret;
}
*out_descriptor_pool = descriptor_pool;
return VK_SUCCESS;
}
/*
*
* Mesh
*
*/
static VkResult
create_mesh_descriptor_set_layout(
struct vk_bundle *vk,
uint32_t src_binding,
uint32_t ubo_binding,
VkDescriptorSetLayout *out_descriptor_set_layout)
{
VkResult ret;
VkDescriptorSetLayoutBinding set_layout_bindings[2] = {
{
.binding = src_binding,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
{
.binding = ubo_binding,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
},
};
VkDescriptorSetLayoutCreateInfo set_layout_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = ARRAY_SIZE(set_layout_bindings),
.pBindings = set_layout_bindings,
};
VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
ret = vk->vkCreateDescriptorSetLayout(vk->device, //
&set_layout_info, //
NULL, //
&descriptor_set_layout); //
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkCreateDescriptorSetLayout failed: %s",
vk_result_string(ret));
return ret;
}
*out_descriptor_set_layout = descriptor_set_layout;
return VK_SUCCESS;
}
static bool
init_mesh_vertex_buffers(struct vk_bundle *vk,
struct comp_buffer *vbo,
struct comp_buffer *ibo,
uint32_t num_vertices,
uint32_t stride,
void *vertices,
uint32_t num_indices,
void *indices)
{
// Using the same flags for all vbos.
VkBufferUsageFlags vbo_usage_flags = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
VkBufferUsageFlags ibo_usage_flags = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
VkMemoryPropertyFlags memory_property_flags =
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
// Distortion vbo and ibo sizes.
VkDeviceSize vbo_size = stride * num_vertices;
VkDeviceSize ibo_size = sizeof(int) * num_indices;
// Don't create vbo if size is zero.
if (vbo_size == 0) {
return true;
}
C(comp_buffer_init(vk, // vk_bundle
vbo, // buffer
vbo_usage_flags, // usage_flags
memory_property_flags, // memory_property_flags
vbo_size)); // size
C(comp_buffer_write(vk, // vk_bundle
vbo, // buffer
vertices, // data
vbo_size)); // size
// Don't create index buffer if size is zero.
if (ibo_size == 0) {
return true;
}
C(comp_buffer_init(vk, // vk_bundle
ibo, // buffer
ibo_usage_flags, // usage_flags
memory_property_flags, // memory_property_flags
ibo_size)); // size
C(comp_buffer_write(vk, // vk_bundle
ibo, // buffer
indices, // data
ibo_size)); // size
return true;
}
/*
*
* 'Exported' renderer functions.
*
*/
bool
comp_resources_init(struct comp_compositor *c, struct comp_resources *r)
{
struct vk_bundle *vk = &c->vk;
struct xrt_device *xdev = c->xdev;
/*
* Constants
*/
r->mesh.src_binding = 0;
r->mesh.ubo_binding = 1;
struct xrt_hmd_parts *parts = xdev->hmd;
r->mesh.num_vertices = parts->distortion.mesh.num_vertices;
r->mesh.stride = parts->distortion.mesh.stride;
r->mesh.num_indices[0] = parts->distortion.mesh.num_indices[0];
r->mesh.num_indices[1] = parts->distortion.mesh.num_indices[1];
r->mesh.total_num_indices = parts->distortion.mesh.total_num_indices;
r->mesh.offset_indices[0] = parts->distortion.mesh.offset_indices[0];
r->mesh.offset_indices[1] = parts->distortion.mesh.offset_indices[1];
/*
* Shared
*/
C(create_pipeline_cache(vk, &r->pipeline_cache));
/*
* Mesh static.
*/
C(create_descriptor_pool(
vk, // vk_bundle
1, // num_uniform_per_desc
1, // num_sampler_per_desc
16 * 2, // num_descs
&r->mesh_descriptor_pool)); // out_descriptor_pool
C(create_mesh_descriptor_set_layout(
vk, // vk_bundle
r->mesh.src_binding, // src_binding
r->mesh.ubo_binding, // ubo_binding
&r->mesh.descriptor_set_layout)); // out_mesh_descriptor_set_layout
C(create_pipeline_layout(
vk, // vk_bundle
r->mesh.descriptor_set_layout, // descriptor_set_layout
&r->mesh.pipeline_layout)); // out_pipeline_layout
if (!init_mesh_vertex_buffers(vk, //
&r->mesh.vbo, //
&r->mesh.ibo, //
r->mesh.num_vertices, //
r->mesh.stride, //
parts->distortion.mesh.vertices, //
r->mesh.total_num_indices, //
parts->distortion.mesh.indices)) { //
return false;
}
/*
* Done
*/
U_LOG_I("New renderer initialized!");
return true;
}
void
comp_resources_close(struct comp_compositor *c, struct comp_resources *r)
{
struct vk_bundle *vk = &c->vk;
D(DescriptorSetLayout, r->mesh.descriptor_set_layout);
D(PipelineLayout, r->mesh.pipeline_layout);
D(PipelineCache, r->pipeline_cache);
D(DescriptorPool, r->mesh_descriptor_pool);
comp_buffer_close(vk, &r->mesh.vbo);
comp_buffer_close(vk, &r->mesh.ibo);
}