mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 04:36:07 +00:00
c/layers: Implement equirect1 rendering.
Add equirect1 boilerplate, shader files, ubo and pipeline.
This commit is contained in:
parent
dc45a201db
commit
4995854d06
|
@ -6,6 +6,8 @@ spirv_shaders(SHADER_HEADERS
|
|||
shaders/mesh.vert
|
||||
shaders/layer.frag
|
||||
shaders/layer.vert
|
||||
shaders/equirect1.vert
|
||||
shaders/equirect1.frag
|
||||
shaders/equirect2.vert
|
||||
shaders/equirect2.frag
|
||||
)
|
||||
|
|
|
@ -141,6 +141,9 @@ struct comp_shaders
|
|||
VkShaderModule mesh_vert;
|
||||
VkShaderModule mesh_frag;
|
||||
|
||||
VkShaderModule equirect1_vert;
|
||||
VkShaderModule equirect1_frag;
|
||||
|
||||
VkShaderModule equirect2_vert;
|
||||
VkShaderModule equirect2_frag;
|
||||
|
||||
|
|
|
@ -83,6 +83,31 @@ _init_ubos(struct comp_render_layer *self)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_init_equirect1_ubo(struct comp_render_layer *self)
|
||||
{
|
||||
VkBufferUsageFlags usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
VkMemoryPropertyFlags properties =
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||
|
||||
if (!vk_buffer_init(self->vk, sizeof(struct layer_transformation),
|
||||
usage, properties, &self->equirect1_ubo.handle,
|
||||
&self->equirect1_ubo.memory))
|
||||
return false;
|
||||
|
||||
VkResult res = self->vk->vkMapMemory(
|
||||
self->vk->device, self->equirect1_ubo.memory, 0, VK_WHOLE_SIZE, 0,
|
||||
&self->equirect1_ubo.data);
|
||||
vk_check_error("vkMapMemory", res, false);
|
||||
|
||||
memcpy(self->equirect1_ubo.data, &self->equirect1_data,
|
||||
sizeof(struct layer_equirect1_data));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_init_equirect2_ubo(struct comp_render_layer *self)
|
||||
{
|
||||
|
@ -187,6 +212,22 @@ comp_layer_update_descriptors(struct comp_render_layer *self,
|
|||
sampler, image_view);
|
||||
}
|
||||
|
||||
void
|
||||
comp_layer_update_equirect1_descriptor(struct comp_render_layer *self,
|
||||
struct xrt_layer_equirect1_data *data)
|
||||
{
|
||||
_update_descriptor_equirect(self, self->descriptor_equirect,
|
||||
self->equirect1_ubo.handle);
|
||||
|
||||
self->equirect1_data = (struct layer_equirect1_data){
|
||||
.radius = data->radius,
|
||||
.scale = data->scale,
|
||||
.bias = data->bias,
|
||||
};
|
||||
memcpy(self->equirect1_ubo.data, &self->equirect1_data,
|
||||
sizeof(struct layer_equirect1_data));
|
||||
}
|
||||
|
||||
void
|
||||
comp_layer_update_equirect2_descriptor(struct comp_render_layer *self,
|
||||
struct xrt_layer_equirect2_data *data)
|
||||
|
@ -236,6 +277,9 @@ _init(struct comp_render_layer *self,
|
|||
if (!_init_ubos(self))
|
||||
return false;
|
||||
|
||||
if (!_init_equirect1_ubo(self))
|
||||
return false;
|
||||
|
||||
if (!_init_equirect2_ubo(self))
|
||||
return false;
|
||||
|
||||
|
@ -301,16 +345,17 @@ comp_layer_draw(struct comp_render_layer *self,
|
|||
break;
|
||||
case XRT_LAYER_QUAD:
|
||||
case XRT_LAYER_CYLINDER:
|
||||
case XRT_LAYER_EQUIRECT1:
|
||||
case XRT_LAYER_EQUIRECT2: _update_mvp_matrix(self, eye, vp); break;
|
||||
case XRT_LAYER_STEREO_PROJECTION_DEPTH:
|
||||
case XRT_LAYER_CUBE:
|
||||
case XRT_LAYER_EQUIRECT1:
|
||||
// Should never end up here.
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
if (self->type == XRT_LAYER_EQUIRECT2) {
|
||||
if (self->type == XRT_LAYER_EQUIRECT1 ||
|
||||
self->type == XRT_LAYER_EQUIRECT2) {
|
||||
const VkDescriptorSet sets[2] = {
|
||||
self->descriptor_sets[eye],
|
||||
self->descriptor_equirect,
|
||||
|
@ -478,6 +523,7 @@ comp_layer_destroy(struct comp_render_layer *self)
|
|||
for (uint32_t eye = 0; eye < 2; eye++)
|
||||
vk_buffer_destroy(&self->transformation_ubos[eye], self->vk);
|
||||
|
||||
vk_buffer_destroy(&self->equirect1_ubo, self->vk);
|
||||
vk_buffer_destroy(&self->equirect2_ubo, self->vk);
|
||||
|
||||
self->vk->vkDestroyDescriptorPool(self->vk->device,
|
||||
|
|
|
@ -20,6 +20,13 @@ struct layer_transformation
|
|||
bool flip_y;
|
||||
};
|
||||
|
||||
struct layer_equirect1_data
|
||||
{
|
||||
struct xrt_vec2 scale;
|
||||
struct xrt_vec2 bias;
|
||||
float radius;
|
||||
};
|
||||
|
||||
struct layer_equirect2_data
|
||||
{
|
||||
float radius;
|
||||
|
@ -41,6 +48,9 @@ struct comp_render_layer
|
|||
struct layer_transformation transformation[2];
|
||||
struct vk_buffer transformation_ubos[2];
|
||||
|
||||
struct layer_equirect1_data equirect1_data;
|
||||
struct vk_buffer equirect1_ubo;
|
||||
|
||||
struct layer_equirect2_data equirect2_data;
|
||||
struct vk_buffer equirect2_ubo;
|
||||
|
||||
|
@ -104,6 +114,10 @@ bool
|
|||
comp_layer_update_cylinder_vertex_buffer(struct comp_render_layer *self,
|
||||
float central_angle);
|
||||
|
||||
void
|
||||
comp_layer_update_equirect1_descriptor(struct comp_render_layer *self,
|
||||
struct xrt_layer_equirect1_data *data);
|
||||
|
||||
void
|
||||
comp_layer_update_equirect2_descriptor(struct comp_render_layer *self,
|
||||
struct xrt_layer_equirect2_data *data);
|
||||
|
|
|
@ -412,6 +412,11 @@ _render_eye(struct comp_layer_renderer *self,
|
|||
comp_layer_draw(self->layers[i], eye, pipeline,
|
||||
pipeline_layout, cmd_buffer,
|
||||
vertex_buffer, &vp_inv, &vp_inv);
|
||||
} else if (self->layers[i]->type == XRT_LAYER_EQUIRECT1) {
|
||||
pipeline = self->pipeline_equirect1;
|
||||
comp_layer_draw(self->layers[i], eye, pipeline,
|
||||
pipeline_layout, cmd_buffer,
|
||||
vertex_buffer, &vp_inv, &vp_inv);
|
||||
} else {
|
||||
comp_layer_draw(self->layers[i], eye, pipeline,
|
||||
pipeline_layout, cmd_buffer,
|
||||
|
@ -553,6 +558,11 @@ _init(struct comp_layer_renderer *self,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_init_graphics_pipeline(self, s->equirect1_vert, s->equirect1_frag,
|
||||
true, &self->pipeline_equirect1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_init_graphics_pipeline(self, s->equirect2_vert, s->equirect2_frag,
|
||||
true, &self->pipeline_equirect2)) {
|
||||
return false;
|
||||
|
@ -696,6 +706,7 @@ comp_layer_renderer_destroy(struct comp_layer_renderer *self)
|
|||
NULL);
|
||||
vk->vkDestroyPipeline(vk->device, self->pipeline_unpremultiplied_alpha,
|
||||
NULL);
|
||||
vk->vkDestroyPipeline(vk->device, self->pipeline_equirect1, NULL);
|
||||
vk->vkDestroyPipeline(vk->device, self->pipeline_equirect2, NULL);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(self->shader_modules); i++)
|
||||
|
|
|
@ -39,6 +39,7 @@ struct comp_layer_renderer
|
|||
VkShaderModule shader_modules[2];
|
||||
VkPipeline pipeline_premultiplied_alpha;
|
||||
VkPipeline pipeline_unpremultiplied_alpha;
|
||||
VkPipeline pipeline_equirect1;
|
||||
VkPipeline pipeline_equirect2;
|
||||
VkDescriptorSetLayout descriptor_set_layout;
|
||||
VkDescriptorSetLayout descriptor_set_layout_equirect;
|
||||
|
|
|
@ -601,8 +601,7 @@ comp_renderer_set_equirect1_layer(struct comp_renderer *r,
|
|||
get_image_view(image, data->flags,
|
||||
data->equirect1.sub.array_index));
|
||||
|
||||
// TODO!
|
||||
// comp_layer_update_equirect1_descriptor(l, &data->equirect1);
|
||||
comp_layer_update_equirect1_descriptor(l, &data->equirect1);
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
l->transformation[i].offset = data->equirect1.sub.rect.offset;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "shaders/layer.frag.h"
|
||||
#include "shaders/layer.vert.h"
|
||||
#include "shaders/equirect1.frag.h"
|
||||
#include "shaders/equirect1.vert.h"
|
||||
#include "shaders/equirect2.frag.h"
|
||||
#include "shaders/equirect2.vert.h"
|
||||
#include "shaders/mesh.frag.h"
|
||||
|
@ -89,6 +91,15 @@ comp_shaders_load(struct vk_bundle *vk, struct comp_shaders *s)
|
|||
sizeof(shaders_mesh_frag), // size
|
||||
&s->mesh_frag)); // out
|
||||
|
||||
C(shader_load(vk, // vk_bundle
|
||||
shaders_equirect1_vert, // data
|
||||
sizeof(shaders_equirect1_vert), // size
|
||||
&s->equirect1_vert)); // out
|
||||
C(shader_load(vk, // vk_bundle
|
||||
shaders_equirect1_frag, // data
|
||||
sizeof(shaders_equirect1_frag), // size
|
||||
&s->equirect1_frag)); // out
|
||||
|
||||
C(shader_load(vk, // vk_bundle
|
||||
shaders_equirect2_vert, // data
|
||||
sizeof(shaders_equirect2_vert), // size
|
||||
|
@ -123,6 +134,8 @@ comp_shaders_close(struct vk_bundle *vk, struct comp_shaders *s)
|
|||
{
|
||||
D(mesh_vert);
|
||||
D(mesh_frag);
|
||||
D(equirect1_vert);
|
||||
D(equirect1_frag);
|
||||
D(equirect2_vert);
|
||||
D(equirect2_frag);
|
||||
D(layer_vert);
|
||||
|
|
48
src/xrt/compositor/shaders/equirect1.frag
Normal file
48
src/xrt/compositor/shaders/equirect1.frag
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2020 Collabora Ltd.
|
||||
// Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#version 460
|
||||
|
||||
layout (location = 0) in vec2 uv;
|
||||
|
||||
layout (set = 0, binding = 0, std140) uniform Transformation {
|
||||
mat4 mvp;
|
||||
ivec2 offset;
|
||||
ivec2 extent;
|
||||
bool flip_y;
|
||||
} ubo;
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D image;
|
||||
|
||||
layout (set = 1, binding = 0, std140) uniform Equirect {
|
||||
vec2 scale;
|
||||
vec2 bias;
|
||||
float radius;
|
||||
} equirect;
|
||||
|
||||
layout (location = 0) out vec4 out_color;
|
||||
|
||||
const float PI = 3.1416;
|
||||
|
||||
void main ()
|
||||
{
|
||||
vec2 uv_sub = vec2(ubo.offset) + uv * vec2(ubo.extent);
|
||||
uv_sub /= textureSize(image, 0);
|
||||
|
||||
vec2 frag_coord = vec2(uv_sub) * 2 - 1;
|
||||
|
||||
vec4 view_dir = normalize(ubo.mvp * vec4(frag_coord.x, -frag_coord.y, 1, 1));
|
||||
|
||||
float lat = atan(view_dir.x, -view_dir.z) / (2 * PI);
|
||||
float lon = acos(view_dir.y) / PI;
|
||||
|
||||
lat *= equirect.scale.x;
|
||||
lon *= equirect.scale.y;
|
||||
|
||||
lat += equirect.bias.x;
|
||||
lon += equirect.bias.y;
|
||||
|
||||
out_color = texture(image, vec2(lat, lon));
|
||||
}
|
||||
|
39
src/xrt/compositor/shaders/equirect1.vert
Normal file
39
src/xrt/compositor/shaders/equirect1.vert
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2020 Collabora Ltd.
|
||||
// Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#version 460
|
||||
|
||||
layout (binding = 0, std140) uniform Transformation {
|
||||
mat4 mvp;
|
||||
ivec2 offset;
|
||||
ivec2 extent;
|
||||
bool flip_y;
|
||||
} transformation;
|
||||
|
||||
layout (location = 0) in vec3 position;
|
||||
layout (location = 1) in vec2 uv;
|
||||
|
||||
layout (location = 0) out vec2 out_uv;
|
||||
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
const mat4 mvp = mat4(
|
||||
2, 0, 0, 0,
|
||||
0, 2, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
);
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4 (position, 1.0f);
|
||||
gl_Position.y = -gl_Position.y;
|
||||
out_uv = uv;
|
||||
|
||||
if (transformation.flip_y) {
|
||||
out_uv.y = 1.0 - out_uv.y;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ shader_srcs = [
|
|||
'mesh.vert',
|
||||
'layer.vert',
|
||||
'layer.frag',
|
||||
'equirect1.vert',
|
||||
'equirect1.frag',
|
||||
'equirect2.vert',
|
||||
'equirect2.frag'
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue