c/main: Refactor shader loading to own file

This commit is contained in:
Jakob Bornecrantz 2020-10-09 17:14:17 +01:00
parent 438a8e71f9
commit 32fd9398fe
9 changed files with 191 additions and 105 deletions

View file

@ -20,6 +20,7 @@ set(MAIN_SOURCE_FILES
main/comp_renderer.h
main/comp_settings.c
main/comp_settings.h
main/comp_shaders.c
main/comp_swapchain.c
main/comp_vk_swapchain.c
main/comp_vk_swapchain.h

View file

@ -81,6 +81,9 @@ compositor_destroy(struct xrt_compositor *xc)
c->r = NULL;
}
// As long as vk_bundle is valid it's safe to call this function.
comp_shaders_close(&c->vk, &c->shaders);
if (c->window != NULL) {
vk_swapchain_cleanup(&c->window->swapchain);
c->window->destroy(c->window);
@ -1134,6 +1137,12 @@ err_destroy:
return false;
}
static bool
compositor_init_shaders(struct comp_compositor *c)
{
return comp_shaders_load(&c->vk, &c->shaders);
}
static bool
compositor_init_renderer(struct comp_compositor *c)
{
@ -1211,6 +1220,7 @@ xrt_gfx_provider_create_native(struct xrt_device *xdev)
!compositor_init_window_pre_vulkan(c) ||
!compositor_init_vulkan(c) ||
!compositor_init_window_post_vulkan(c) ||
!compositor_init_shaders(c) ||
!compositor_init_swapchain(c) ||
!compositor_init_renderer(c)) {
COMP_DEBUG(c, "Failed to init compositor %p", (void *)c);

View file

@ -132,6 +132,14 @@ enum comp_state
COMP_STATE_FOCUSED = 4,
};
struct comp_shaders
{
VkShaderModule mesh_vert;
VkShaderModule mesh_frag;
VkShaderModule layer_vert;
VkShaderModule layer_frag;
};
/*!
* Main compositor struct tying everything in the compositor together.
*
@ -160,6 +168,9 @@ struct comp_compositor
//! Vulkan bundle of things.
struct vk_bundle vk;
//! Vulkan shaders that the compositor uses.
struct comp_shaders shaders;
//! Timestamp of last-rendered (immersive) frame.
int64_t last_frame_time_ns;
@ -298,6 +309,18 @@ comp_swapchain_import(struct xrt_compositor *xc,
void
comp_swapchain_really_destroy(struct comp_swapchain *sc);
/*!
* Loads all of the shaders that the compositor uses.
*/
bool
comp_shaders_load(struct vk_bundle *vk, struct comp_shaders *s);
/*!
* Loads all of the shaders that the compositor uses.
*/
void
comp_shaders_close(struct vk_bundle *vk, struct comp_shaders *s);
/*!
* Spew level logging.
*

View file

@ -18,15 +18,6 @@
#include "comp_distortion.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wnewline-eof"
#include "shaders/mesh.frag.h"
#include "shaders/mesh.vert.h"
#pragma GCC diagnostic pop
/*
*
@ -56,6 +47,7 @@ comp_distortion_init_pipeline_layout(struct comp_distortion *d);
static void
comp_distortion_init_pipeline(struct comp_distortion *d,
struct comp_shaders *s,
VkRenderPass render_pass,
VkPipelineCache pipeline_cache);
@ -125,41 +117,6 @@ _buffer_setup_descriptor(struct vk_bundle *vk,
}
/*
*
* Shader functions.
*
*/
static VkPipelineShaderStageCreateInfo
_shader_load(struct vk_bundle *vk,
const uint32_t *code,
size_t size,
VkShaderStageFlagBits flags)
{
VkResult ret;
VkShaderModuleCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = size,
.pCode = code,
};
VkShaderModule module;
ret = vk->vkCreateShaderModule(vk->device, &info, NULL, &module);
if (ret != VK_SUCCESS) {
VK_DEBUG(vk, "vkCreateShaderModule failed %u", ret);
}
return (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = flags,
.module = module,
.pName = "main",
};
}
/*
*
* Functions.
@ -208,7 +165,8 @@ comp_distortion_init(struct comp_distortion *d,
comp_distortion_update_uniform_buffer_warp(d, c);
comp_distortion_init_descriptor_set_layout(d);
comp_distortion_init_pipeline_layout(d);
comp_distortion_init_pipeline(d, render_pass, pipeline_cache);
comp_distortion_init_pipeline(d, &c->shaders, render_pass,
pipeline_cache);
comp_distortion_init_descriptor_sets(d, descriptor_pool);
}
@ -241,6 +199,7 @@ comp_distortion_destroy(struct comp_distortion *d)
static void
comp_distortion_init_pipeline(struct comp_distortion *d,
struct comp_shaders *s,
VkRenderPass render_pass,
VkPipelineCache pipeline_cache)
{
@ -356,22 +315,19 @@ comp_distortion_init_pipeline(struct comp_distortion *d,
vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
// clang-format on
const uint32_t *vertex_shader_code = NULL;
size_t vertex_shader_size = 0;
const uint32_t *fragment_shader_code = NULL;
size_t fragment_shader_size = 0;
vertex_shader_code = shaders_mesh_vert;
vertex_shader_size = sizeof(shaders_mesh_vert);
fragment_shader_code = shaders_mesh_frag;
fragment_shader_size = sizeof(shaders_mesh_frag);
VkPipelineShaderStageCreateInfo shader_stages[2] = {
_shader_load(d->vk, vertex_shader_code, vertex_shader_size,
VK_SHADER_STAGE_VERTEX_BIT),
_shader_load(d->vk, fragment_shader_code, fragment_shader_size,
VK_SHADER_STAGE_FRAGMENT_BIT),
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
.module = s->mesh_vert,
.pName = "main",
},
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = s->mesh_frag,
.pName = "main",
},
};
VkGraphicsPipelineCreateInfo pipeline_info = {
@ -397,9 +353,6 @@ comp_distortion_init_pipeline(struct comp_distortion *d,
if (ret != VK_SUCCESS) {
VK_DEBUG(d->vk, "vkCreateGraphicsPipelines failed %u!", ret);
}
vk->vkDestroyShaderModule(vk->device, shader_stages[0].module, NULL);
vk->vkDestroyShaderModule(vk->device, shader_stages[1].module, NULL);
}
static VkWriteDescriptorSet

View file

@ -12,9 +12,6 @@
#include "comp_layer_renderer.h"
#include "shaders/layer.frag.h"
#include "shaders/layer.vert.h"
#include <stdio.h>
#include <math.h>
@ -163,36 +160,9 @@ struct __attribute__((__packed__)) comp_pipeline_config
const VkPipelineRasterizationStateCreateInfo *rasterization_state;
};
static VkPipelineShaderStageCreateInfo
_shader_load(struct vk_bundle *vk,
const uint32_t *code,
size_t size,
VkShaderStageFlagBits flags)
{
VkResult ret;
VkShaderModuleCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = size,
.pCode = code,
};
VkShaderModule module;
ret = vk->vkCreateShaderModule(vk->device, &info, NULL, &module);
if (ret != VK_SUCCESS) {
VK_DEBUG(vk, "vkCreateShaderModule failed %u", ret);
}
return (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = flags,
.module = module,
.pName = "main",
};
}
static bool
_init_graphics_pipeline(struct comp_layer_renderer *self,
struct comp_shaders *s,
bool premultiplied_alpha,
VkPipeline *pipeline)
{
@ -245,10 +215,18 @@ _init_graphics_pipeline(struct comp_layer_renderer *self,
};
VkPipelineShaderStageCreateInfo shader_stages[2] = {
_shader_load(vk, shaders_layer_vert, sizeof(shaders_layer_vert),
VK_SHADER_STAGE_VERTEX_BIT),
_shader_load(vk, shaders_layer_frag, sizeof(shaders_layer_frag),
VK_SHADER_STAGE_FRAGMENT_BIT),
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
.module = s->layer_vert,
.pName = "main",
},
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = s->layer_frag,
.pName = "main",
},
};
VkGraphicsPipelineCreateInfo pipeline_info = {
@ -325,9 +303,6 @@ _init_graphics_pipeline(struct comp_layer_renderer *self,
vk_check_error("vkCreateGraphicsPipelines", res, false);
vk->vkDestroyShaderModule(vk->device, shader_stages[0].module, NULL);
vk->vkDestroyShaderModule(vk->device, shader_stages[1].module, NULL);
return true;
}
@ -478,6 +453,7 @@ comp_layer_renderer_destroy_layers(struct comp_layer_renderer *self)
static bool
_init(struct comp_layer_renderer *self,
struct comp_shaders *s,
struct vk_bundle *vk,
VkExtent2D extent,
VkFormat format)
@ -517,10 +493,10 @@ _init(struct comp_layer_renderer *self,
return false;
if (!_init_pipeline_cache(self))
return false;
if (!_init_graphics_pipeline(self, false,
if (!_init_graphics_pipeline(self, s, false,
&self->pipeline_premultiplied_alpha))
return false;
if (!_init_graphics_pipeline(self, true,
if (!_init_graphics_pipeline(self, s, true,
&self->pipeline_unpremultiplied_alpha))
return false;
if (!_init_vertex_buffer(self))
@ -531,12 +507,13 @@ _init(struct comp_layer_renderer *self,
struct comp_layer_renderer *
comp_layer_renderer_create(struct vk_bundle *vk,
struct comp_shaders *s,
VkExtent2D extent,
VkFormat format)
{
struct comp_layer_renderer *r =
U_TYPED_CALLOC(struct comp_layer_renderer);
_init(r, vk, extent, format);
_init(r, s, vk, extent, format);
return r;
}

View file

@ -61,6 +61,7 @@ struct comp_layer_renderer
struct comp_layer_renderer *
comp_layer_renderer_create(struct vk_bundle *vk,
struct comp_shaders *s,
VkExtent2D extent,
VkFormat format);

View file

@ -459,7 +459,8 @@ renderer_init(struct comp_renderer *r)
.height = r->c->xdev->hmd->screens[0].h_pixels,
};
r->lr = comp_layer_renderer_create(vk, extent, VK_FORMAT_B8G8R8A8_SRGB);
r->lr = comp_layer_renderer_create(vk, &r->c->shaders, extent,
VK_FORMAT_B8G8R8A8_SRGB);
for (uint32_t i = 0; i < 2; i++) {
comp_distortion_update_descriptor_set(

View file

@ -0,0 +1,119 @@
// Copyright 2019-2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Shader loading code.
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup comp_main
*/
#include "main/comp_compositor.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wnewline-eof"
#include "shaders/layer.frag.h"
#include "shaders/layer.vert.h"
#include "shaders/mesh.frag.h"
#include "shaders/mesh.vert.h"
#pragma GCC diagnostic pop
/*
*
* Functions.
*
*/
static VkResult
shader_load(struct vk_bundle *vk,
const uint32_t *code,
size_t size,
VkShaderModule *out_module)
{
VkResult ret;
VkShaderModuleCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = size,
.pCode = code,
};
VkShaderModule module;
ret = vk->vkCreateShaderModule(vk->device, //
&info, //
NULL, //
&module); //
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkCreateShaderModule failed: %s",
vk_result_string(ret));
return ret;
}
*out_module = module;
return VK_SUCCESS;
}
#define C(c) \
do { \
VkResult ret = c; \
if (ret != VK_SUCCESS) { \
comp_shaders_close(vk, s); \
return false; \
} \
} while (false)
bool
comp_shaders_load(struct vk_bundle *vk, struct comp_shaders *s)
{
C(shader_load(vk, // vk_bundle
shaders_mesh_vert, // data
sizeof(shaders_mesh_vert), // size
&s->mesh_vert)); // out
C(shader_load(vk, // vk_bundle
shaders_mesh_frag, // data
sizeof(shaders_mesh_frag), // size
&s->mesh_frag)); // out
C(shader_load(vk, // vk_bundle
shaders_layer_vert, // data
sizeof(shaders_layer_vert), // size
&s->layer_vert)); // out
C(shader_load(vk, // vk_bundle
shaders_layer_frag, // data
sizeof(shaders_layer_frag), // size
&s->layer_frag)); // out
VK_DEBUG(vk, "Shaders loaded!");
return true;
}
#define D(shader) \
if (s->shader != VK_NULL_HANDLE) { \
vk->vkDestroyShaderModule(vk->device, s->shader, NULL); \
s->shader = VK_NULL_HANDLE; \
}
void
comp_shaders_close(struct vk_bundle *vk, struct comp_shaders *s)
{
D(mesh_vert);
D(mesh_frag);
D(layer_vert);
D(layer_frag);
VK_DEBUG(vk, "Shaders destroyed!");
}

View file

@ -22,6 +22,7 @@ compositor_srcs = [
'main/comp_renderer.h',
'main/comp_settings.c',
'main/comp_settings.h',
'main/comp_shaders.c',
'main/comp_swapchain.c',
'main/comp_vk_swapchain.c',
'main/comp_vk_swapchain.h',