2022-03-27 21:22:24 +00:00
|
|
|
// Copyright 2019-2022, Collabora, Ltd.
|
2020-10-05 22:30:31 +00:00
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief The NEW compositor rendering code header.
|
|
|
|
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
2021-11-03 17:45:39 +00:00
|
|
|
* @ingroup comp_render
|
2020-10-05 22:30:31 +00:00
|
|
|
*/
|
|
|
|
|
2022-03-27 21:22:24 +00:00
|
|
|
#include "render/render_interfaces.h"
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Common helpers
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define C(c) \
|
|
|
|
do { \
|
|
|
|
VkResult ret = c; \
|
|
|
|
if (ret != VK_SUCCESS) { \
|
|
|
|
return false; \
|
|
|
|
} \
|
2020-10-05 22:30:31 +00:00
|
|
|
} while (false)
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define D(TYPE, thing) \
|
|
|
|
if (thing != VK_NULL_HANDLE) { \
|
|
|
|
vk->vkDestroy##TYPE(vk->device, thing, NULL); \
|
|
|
|
thing = VK_NULL_HANDLE; \
|
2020-10-05 22:30:31 +00:00
|
|
|
}
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define DD(pool, thing) \
|
|
|
|
if (thing != VK_NULL_HANDLE) { \
|
|
|
|
free_descriptor_set(vk, pool, thing); \
|
|
|
|
thing = VK_NULL_HANDLE; \
|
2020-10-05 22:30:31 +00:00
|
|
|
}
|
|
|
|
|
2021-11-02 13:54:16 +00:00
|
|
|
/*!
|
2022-03-27 21:10:25 +00:00
|
|
|
* Get the @ref vk_bundle from @ref render_gfx_target_resources.
|
2021-11-02 13:54:16 +00:00
|
|
|
*/
|
|
|
|
static inline struct vk_bundle *
|
2022-03-27 21:10:25 +00:00
|
|
|
vk_from_rtr(struct render_gfx_target_resources *rtr)
|
2021-11-02 13:54:16 +00:00
|
|
|
{
|
2021-11-03 13:28:15 +00:00
|
|
|
return rtr->r->vk;
|
2021-11-02 13:54:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2022-03-27 21:10:25 +00:00
|
|
|
* Get the @ref vk_bundle from @ref render_gfx.
|
2021-11-02 13:54:16 +00:00
|
|
|
*/
|
|
|
|
static inline struct vk_bundle *
|
2022-03-27 21:10:25 +00:00
|
|
|
vk_from_rr(struct render_gfx *rr)
|
2021-11-02 13:54:16 +00:00
|
|
|
{
|
2021-11-02 18:37:07 +00:00
|
|
|
return rr->r->vk;
|
2021-11-02 13:54:16 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 22:30:31 +00:00
|
|
|
static VkResult
|
2021-01-14 14:13:48 +00:00
|
|
|
create_external_render_pass(struct vk_bundle *vk, VkFormat format, VkRenderPass *out_render_pass)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
|
|
|
VkResult ret;
|
|
|
|
|
|
|
|
VkAttachmentDescription attachments[1] = {
|
|
|
|
{
|
|
|
|
.format = format,
|
|
|
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
|
|
|
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
|
|
|
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
|
|
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkAttachmentReference color_reference = {
|
|
|
|
.attachment = 0,
|
|
|
|
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkSubpassDescription subpasses[1] = {
|
|
|
|
{
|
|
|
|
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
|
.inputAttachmentCount = 0,
|
|
|
|
.pInputAttachments = NULL,
|
|
|
|
.colorAttachmentCount = 1,
|
|
|
|
.pColorAttachments = &color_reference,
|
|
|
|
.pResolveAttachments = NULL,
|
|
|
|
.pDepthStencilAttachment = NULL,
|
|
|
|
.preserveAttachmentCount = 0,
|
|
|
|
.pPreserveAttachments = NULL,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkSubpassDependency dependencies[1] = {
|
|
|
|
{
|
|
|
|
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
|
|
|
.dstSubpass = 0,
|
|
|
|
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
.srcAccessMask = 0,
|
2021-01-14 14:13:48 +00:00
|
|
|
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
2020-10-05 22:30:31 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkRenderPassCreateInfo render_pass_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
|
|
|
.attachmentCount = ARRAY_SIZE(attachments),
|
|
|
|
.pAttachments = attachments,
|
|
|
|
.subpassCount = ARRAY_SIZE(subpasses),
|
|
|
|
.pSubpasses = subpasses,
|
|
|
|
.dependencyCount = ARRAY_SIZE(dependencies),
|
|
|
|
.pDependencies = dependencies,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkRenderPass render_pass = VK_NULL_HANDLE;
|
|
|
|
ret = vk->vkCreateRenderPass(vk->device, //
|
|
|
|
&render_pass_info, //
|
|
|
|
NULL, //
|
|
|
|
&render_pass); //
|
|
|
|
if (ret != VK_SUCCESS) {
|
2021-01-14 14:13:48 +00:00
|
|
|
VK_ERROR(vk, "vkCreateRenderPass failed: %s", vk_result_string(ret));
|
2020-10-05 22:30:31 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_render_pass = render_pass;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VkResult
|
|
|
|
create_framebuffer(struct vk_bundle *vk,
|
|
|
|
VkImageView image_view,
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
uint32_t width,
|
|
|
|
uint32_t height,
|
|
|
|
VkFramebuffer *out_external_framebuffer)
|
|
|
|
{
|
|
|
|
VkResult ret;
|
|
|
|
|
|
|
|
VkImageView attachments[1] = {image_view};
|
|
|
|
|
|
|
|
VkFramebufferCreateInfo frame_buffer_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
|
|
|
.renderPass = render_pass,
|
|
|
|
.attachmentCount = ARRAY_SIZE(attachments),
|
|
|
|
.pAttachments = attachments,
|
|
|
|
.width = width,
|
|
|
|
.height = height,
|
|
|
|
.layers = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
|
|
|
ret = vk->vkCreateFramebuffer(vk->device, //
|
|
|
|
&frame_buffer_info, //
|
|
|
|
NULL, //
|
|
|
|
&framebuffer); //
|
|
|
|
if (ret != VK_SUCCESS) {
|
2021-01-14 14:13:48 +00:00
|
|
|
VK_ERROR(vk, "vkCreateFramebuffer failed: %s", vk_result_string(ret));
|
2020-10-05 22:30:31 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_external_framebuffer = framebuffer;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
begin_render_pass(struct vk_bundle *vk,
|
|
|
|
VkCommandBuffer command_buffer,
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
VkFramebuffer framebuffer,
|
|
|
|
uint32_t width,
|
|
|
|
uint32_t height)
|
|
|
|
{
|
|
|
|
VkClearValue clear_color[1] = {{
|
|
|
|
.color = {.float32 = {0.0f, 0.0f, 0.0f, 0.0f}},
|
|
|
|
}};
|
|
|
|
|
|
|
|
VkRenderPassBeginInfo render_pass_begin_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
|
|
|
.renderPass = render_pass,
|
|
|
|
.framebuffer = framebuffer,
|
|
|
|
.renderArea =
|
|
|
|
{
|
|
|
|
.offset =
|
|
|
|
{
|
|
|
|
.x = 0,
|
|
|
|
.y = 0,
|
|
|
|
},
|
|
|
|
.extent =
|
|
|
|
{
|
|
|
|
.width = width,
|
|
|
|
.height = height,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.clearValueCount = ARRAY_SIZE(clear_color),
|
|
|
|
.pClearValues = clear_color,
|
|
|
|
};
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
vk->vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
2020-10-05 22:30:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Mesh
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VkResult
|
|
|
|
create_mesh_pipeline(struct vk_bundle *vk,
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
VkPipelineLayout pipeline_layout,
|
|
|
|
VkPipelineCache pipeline_cache,
|
|
|
|
uint32_t src_binding,
|
2021-11-08 23:03:03 +00:00
|
|
|
uint32_t mesh_index_count_total,
|
2020-10-05 22:30:31 +00:00
|
|
|
uint32_t mesh_stride,
|
|
|
|
VkShaderModule mesh_vert,
|
|
|
|
VkShaderModule mesh_frag,
|
|
|
|
VkPipeline *out_mesh_pipeline)
|
|
|
|
{
|
|
|
|
VkResult ret;
|
|
|
|
|
|
|
|
// Might be changed to line for debugging.
|
|
|
|
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
|
|
|
|
|
|
|
|
// Do we use triangle strips or triangles with indices.
|
|
|
|
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
2021-11-08 23:03:03 +00:00
|
|
|
if (mesh_index_count_total > 0) {
|
2020-10-05 22:30:31 +00:00
|
|
|
topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_state = {
|
2021-01-14 14:13:48 +00:00
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
2020-10-05 22:30:31 +00:00
|
|
|
.topology = topology,
|
|
|
|
.primitiveRestartEnable = VK_FALSE,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineRasterizationStateCreateInfo rasterization_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
|
|
|
.depthClampEnable = VK_FALSE,
|
|
|
|
.rasterizerDiscardEnable = VK_FALSE,
|
|
|
|
.polygonMode = polygonMode,
|
|
|
|
.cullMode = VK_CULL_MODE_BACK_BIT,
|
|
|
|
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
|
|
|
.lineWidth = 1.0f,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineColorBlendAttachmentState blend_attachment_state = {
|
|
|
|
.blendEnable = VK_FALSE,
|
|
|
|
.colorWriteMask = 0xf,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineColorBlendStateCreateInfo color_blend_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
|
|
|
.attachmentCount = 1,
|
|
|
|
.pAttachments = &blend_attachment_state,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
|
|
|
.depthTestEnable = VK_TRUE,
|
|
|
|
.depthWriteEnable = VK_TRUE,
|
|
|
|
.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL,
|
|
|
|
.front =
|
|
|
|
{
|
|
|
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
|
|
|
},
|
|
|
|
.back =
|
|
|
|
{
|
|
|
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineViewportStateCreateInfo viewport_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
|
|
|
.viewportCount = 1,
|
|
|
|
.scissorCount = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineMultisampleStateCreateInfo multisample_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
|
|
|
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkDynamicState dynamic_states[] = {
|
|
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
|
|
VK_DYNAMIC_STATE_SCISSOR,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineDynamicStateCreateInfo dynamic_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
|
|
|
.dynamicStateCount = ARRAY_SIZE(dynamic_states),
|
|
|
|
.pDynamicStates = dynamic_states,
|
|
|
|
};
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
VkVertexInputAttributeDescription vertex_input_attribute_descriptions[2] = {
|
|
|
|
{
|
|
|
|
.binding = src_binding,
|
|
|
|
.location = 0,
|
|
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
|
|
.offset = 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.binding = src_binding,
|
|
|
|
.location = 1,
|
|
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
|
|
.offset = 16,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription vertex_input_binding_description[1] = {
|
|
|
|
{
|
|
|
|
.binding = src_binding,
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
|
|
.stride = mesh_stride,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertex_input_state = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
|
|
.vertexAttributeDescriptionCount = ARRAY_SIZE(vertex_input_attribute_descriptions),
|
|
|
|
.pVertexAttributeDescriptions = vertex_input_attribute_descriptions,
|
|
|
|
.vertexBindingDescriptionCount = ARRAY_SIZE(vertex_input_binding_description),
|
|
|
|
.pVertexBindingDescriptions = vertex_input_binding_description,
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {
|
|
|
|
{
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
.module = mesh_vert,
|
|
|
|
.pName = "main",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
.module = mesh_frag,
|
|
|
|
.pName = "main",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
|
|
|
.stageCount = ARRAY_SIZE(shader_stages),
|
|
|
|
.pStages = shader_stages,
|
|
|
|
.pVertexInputState = &vertex_input_state,
|
|
|
|
.pInputAssemblyState = &input_assembly_state,
|
|
|
|
.pViewportState = &viewport_state,
|
|
|
|
.pRasterizationState = &rasterization_state,
|
|
|
|
.pMultisampleState = &multisample_state,
|
|
|
|
.pDepthStencilState = &depth_stencil_state,
|
|
|
|
.pColorBlendState = &color_blend_state,
|
|
|
|
.pDynamicState = &dynamic_state,
|
|
|
|
.layout = pipeline_layout,
|
|
|
|
.renderPass = render_pass,
|
|
|
|
.basePipelineHandle = VK_NULL_HANDLE,
|
|
|
|
.basePipelineIndex = -1,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
|
|
|
ret = vk->vkCreateGraphicsPipelines(vk->device, //
|
|
|
|
pipeline_cache, //
|
|
|
|
1, //
|
|
|
|
&pipeline_info, //
|
|
|
|
NULL, //
|
|
|
|
&pipeline); //
|
|
|
|
if (ret != VK_SUCCESS) {
|
2021-01-14 14:13:48 +00:00
|
|
|
VK_DEBUG(vk, "vkCreateGraphicsPipelines failed: %s", vk_result_string(ret));
|
2020-10-05 22:30:31 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_mesh_pipeline = pipeline;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_mesh_discriptor_set(struct vk_bundle *vk,
|
|
|
|
uint32_t src_binding,
|
|
|
|
VkSampler sampler,
|
|
|
|
VkImageView image_view,
|
|
|
|
uint32_t ubo_binding,
|
|
|
|
VkBuffer buffer,
|
|
|
|
VkDeviceSize size,
|
|
|
|
VkDescriptorSet descriptor_set)
|
|
|
|
{
|
|
|
|
VkDescriptorImageInfo image_info = {
|
|
|
|
.sampler = sampler,
|
|
|
|
.imageView = image_view,
|
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkDescriptorBufferInfo buffer_info = {
|
|
|
|
.buffer = buffer,
|
|
|
|
.offset = 0,
|
|
|
|
.range = size,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkWriteDescriptorSet write_descriptor_sets[2] = {
|
|
|
|
{
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
|
|
.dstSet = descriptor_set,
|
|
|
|
.dstBinding = src_binding,
|
|
|
|
.descriptorCount = 1,
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
.pImageInfo = &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,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
vk->vkUpdateDescriptorSets(vk->device, //
|
|
|
|
ARRAY_SIZE(write_descriptor_sets), // descriptorWriteCount
|
|
|
|
write_descriptor_sets, // pDescriptorWrites
|
|
|
|
0, // descriptorCopyCount
|
|
|
|
NULL); // pDescriptorCopies
|
2020-10-05 22:30:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-09-23 19:11:53 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* 'Exported' target resourecs functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_target_resources_init(struct render_gfx_target_resources *rtr,
|
|
|
|
struct render_resources *r,
|
|
|
|
VkImageView target,
|
|
|
|
struct render_gfx_target_data *data)
|
2021-09-23 19:11:53 +00:00
|
|
|
{
|
2021-11-02 18:37:07 +00:00
|
|
|
struct vk_bundle *vk = r->vk;
|
2021-11-03 13:28:15 +00:00
|
|
|
rtr->r = r;
|
2021-09-23 19:11:53 +00:00
|
|
|
|
|
|
|
assert(data->is_external);
|
|
|
|
|
2021-11-03 13:28:15 +00:00
|
|
|
rtr->data = *data;
|
2021-09-23 19:11:53 +00:00
|
|
|
|
|
|
|
C(create_external_render_pass( //
|
|
|
|
vk, // vk_bundle
|
|
|
|
data->format, // target_format
|
2021-11-03 13:28:15 +00:00
|
|
|
&rtr->render_pass)); // out_render_pass
|
2021-09-23 19:11:53 +00:00
|
|
|
|
|
|
|
C(create_mesh_pipeline(vk, // vk_bundle
|
2021-11-03 13:28:15 +00:00
|
|
|
rtr->render_pass, // render_pass
|
2021-09-23 19:11:53 +00:00
|
|
|
r->mesh.pipeline_layout, // pipeline_layout
|
|
|
|
r->pipeline_cache, // pipeline_cache
|
|
|
|
r->mesh.src_binding, // src_binding
|
2021-11-08 23:03:03 +00:00
|
|
|
r->mesh.index_count_total, // mesh_index_count_total
|
2021-09-23 19:11:53 +00:00
|
|
|
r->mesh.stride, // mesh_stride
|
2021-11-02 18:37:07 +00:00
|
|
|
r->shaders->mesh_vert, // mesh_vert
|
|
|
|
r->shaders->mesh_frag, // mesh_frag
|
2021-11-03 13:28:15 +00:00
|
|
|
&rtr->mesh.pipeline)); // out_mesh_pipeline
|
2021-09-23 19:11:53 +00:00
|
|
|
|
|
|
|
C(create_framebuffer(vk, // vk_bundle,
|
|
|
|
target, // image_view,
|
2021-11-03 13:28:15 +00:00
|
|
|
rtr->render_pass, // render_pass,
|
2021-09-23 19:11:53 +00:00
|
|
|
data->width, // width,
|
|
|
|
data->height, // height,
|
2021-11-03 13:28:15 +00:00
|
|
|
&rtr->framebuffer)); // out_external_framebuffer
|
2021-09-23 19:11:53 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_target_resources_close(struct render_gfx_target_resources *rtr)
|
2021-09-23 19:11:53 +00:00
|
|
|
{
|
2021-11-03 13:28:15 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rtr(rtr);
|
2021-09-23 19:11:53 +00:00
|
|
|
|
2021-11-03 13:28:15 +00:00
|
|
|
D(RenderPass, rtr->render_pass);
|
|
|
|
D(Pipeline, rtr->mesh.pipeline);
|
|
|
|
D(Framebuffer, rtr->framebuffer);
|
2021-09-23 19:11:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-05 22:30:31 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* 'Exported' rendering functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_init(struct render_gfx *rr, struct render_resources *r)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-11-02 18:37:07 +00:00
|
|
|
struct vk_bundle *vk = r->vk;
|
2020-10-05 22:30:31 +00:00
|
|
|
rr->r = r;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Per rendering.
|
|
|
|
*/
|
|
|
|
|
2021-11-10 13:09:51 +00:00
|
|
|
C(vk_create_command_buffer(vk, &rr->cmd));
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Mesh per view
|
|
|
|
*/
|
|
|
|
|
2021-11-10 13:09:51 +00:00
|
|
|
C(vk_create_descriptor_set( //
|
2021-09-29 16:35:05 +00:00
|
|
|
vk, // vk_bundle
|
|
|
|
r->mesh.descriptor_pool, // descriptor_pool
|
|
|
|
r->mesh.descriptor_set_layout, // descriptor_set_layout
|
|
|
|
&rr->views[0].mesh.descriptor_set)); // descriptor_set
|
2020-10-05 22:30:31 +00:00
|
|
|
|
2021-11-10 13:09:51 +00:00
|
|
|
C(vk_create_descriptor_set( //
|
2021-09-29 16:35:05 +00:00
|
|
|
vk, // vk_bundle
|
|
|
|
r->mesh.descriptor_pool, // descriptor_pool
|
|
|
|
r->mesh.descriptor_set_layout, // descriptor_set_layout
|
|
|
|
&rr->views[1].mesh.descriptor_set)); // descriptor_set
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-08 13:34:57 +00:00
|
|
|
bool
|
|
|
|
render_gfx_begin(struct render_gfx *rr)
|
|
|
|
{
|
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
|
|
|
|
|
|
|
os_mutex_lock(&vk->cmd_pool_mutex);
|
|
|
|
VkResult ret = vk_begin_command_buffer(vk, rr->cmd);
|
|
|
|
if (ret != VK_SUCCESS) {
|
|
|
|
os_mutex_unlock(&vk->cmd_pool_mutex);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-04-23 21:16:20 +00:00
|
|
|
vk->vkCmdResetQueryPool( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
rr->r->query_pool, // queryPool
|
|
|
|
0, // firstQuery
|
|
|
|
2); // queryCount
|
|
|
|
|
|
|
|
vk->vkCmdWriteTimestamp( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // pipelineStage
|
|
|
|
rr->r->query_pool, // queryPool
|
|
|
|
0); // query
|
|
|
|
|
2022-04-08 13:34:57 +00:00
|
|
|
// Yes we leave the mutex locked.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
render_gfx_end(struct render_gfx *rr)
|
2021-09-23 19:11:53 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2021-09-23 19:11:53 +00:00
|
|
|
|
2022-04-23 21:16:20 +00:00
|
|
|
vk->vkCmdWriteTimestamp( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // pipelineStage
|
|
|
|
rr->r->query_pool, // queryPool
|
|
|
|
1); // query
|
|
|
|
|
2022-04-08 13:34:57 +00:00
|
|
|
VkResult ret = vk_end_command_buffer(vk, rr->cmd);
|
|
|
|
os_mutex_unlock(&vk->cmd_pool_mutex);
|
|
|
|
if (ret != VK_SUCCESS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2021-09-23 19:11:53 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 22:30:31 +00:00
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_close(struct render_gfx *rr)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2022-03-27 21:10:25 +00:00
|
|
|
struct render_resources *r = rr->r;
|
2020-10-05 22:30:31 +00:00
|
|
|
|
2021-11-10 13:09:51 +00:00
|
|
|
vk_destroy_command_buffer(vk, rr->cmd);
|
2021-11-03 23:10:40 +00:00
|
|
|
rr->cmd = VK_NULL_HANDLE;
|
|
|
|
|
2021-09-29 16:35:05 +00:00
|
|
|
// Reclaimed by vkResetDescriptorPool.
|
|
|
|
rr->views[0].mesh.descriptor_set = VK_NULL_HANDLE;
|
|
|
|
rr->views[1].mesh.descriptor_set = VK_NULL_HANDLE;
|
|
|
|
|
|
|
|
vk->vkResetDescriptorPool( //
|
|
|
|
vk->device, //
|
|
|
|
r->mesh.descriptor_pool, //
|
|
|
|
0); //
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
U_ZERO(rr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* 'Exported' draw functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_begin_target(struct render_gfx *rr, struct render_gfx_target_resources *rtr)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2021-01-14 14:13:48 +00:00
|
|
|
|
2021-11-03 13:28:15 +00:00
|
|
|
assert(rr->rtr == NULL);
|
|
|
|
rr->rtr = rtr;
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
// This is shared across both views.
|
2021-09-23 19:11:53 +00:00
|
|
|
begin_render_pass(vk, //
|
|
|
|
rr->cmd, //
|
2021-11-03 13:28:15 +00:00
|
|
|
rr->rtr->render_pass, //
|
|
|
|
rr->rtr->framebuffer, //
|
|
|
|
rr->rtr->data.width, //
|
|
|
|
rr->rtr->data.height); //
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_end_target(struct render_gfx *rr)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2020-10-05 22:30:31 +00:00
|
|
|
|
2021-11-03 13:28:15 +00:00
|
|
|
assert(rr->rtr != NULL);
|
|
|
|
rr->rtr = NULL;
|
2020-10-05 22:30:31 +00:00
|
|
|
|
2021-09-23 19:11:53 +00:00
|
|
|
// Stop the [shared] render pass.
|
2020-10-05 22:30:31 +00:00
|
|
|
vk->vkCmdEndRenderPass(rr->cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_begin_view(struct render_gfx *rr, uint32_t view, struct render_viewport_data *viewport_data)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2020-10-05 22:30:31 +00:00
|
|
|
|
2021-09-23 19:11:53 +00:00
|
|
|
// We currently only support two views.
|
2020-10-05 22:30:31 +00:00
|
|
|
assert(view == 0 || view == 1);
|
2021-11-03 13:28:15 +00:00
|
|
|
assert(rr->rtr != NULL);
|
2021-09-23 19:11:53 +00:00
|
|
|
|
|
|
|
rr->current_view = view;
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Viewport
|
|
|
|
*/
|
|
|
|
|
|
|
|
VkViewport viewport = {
|
2022-04-30 13:44:24 +00:00
|
|
|
.x = (float)viewport_data->x,
|
|
|
|
.y = (float)viewport_data->y,
|
|
|
|
.width = (float)viewport_data->w,
|
|
|
|
.height = (float)viewport_data->h,
|
2020-10-05 22:30:31 +00:00
|
|
|
.minDepth = 0.0f,
|
|
|
|
.maxDepth = 1.0f,
|
|
|
|
};
|
|
|
|
|
|
|
|
vk->vkCmdSetViewport(rr->cmd, // commandBuffer
|
|
|
|
0, // firstViewport
|
|
|
|
1, // viewportCount
|
|
|
|
&viewport); // pViewports
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Scissor
|
|
|
|
*/
|
|
|
|
|
|
|
|
VkRect2D scissor = {
|
|
|
|
.offset =
|
|
|
|
{
|
|
|
|
.x = viewport_data->x,
|
|
|
|
.y = viewport_data->y,
|
|
|
|
},
|
|
|
|
.extent =
|
|
|
|
{
|
|
|
|
.width = viewport_data->w,
|
|
|
|
.height = viewport_data->h,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
vk->vkCmdSetScissor(rr->cmd, // commandBuffer
|
|
|
|
0, // firstScissor
|
|
|
|
1, // scissorCount
|
|
|
|
&scissor); // pScissors
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_end_view(struct render_gfx *rr)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-09-23 19:11:53 +00:00
|
|
|
//! Must have a current target.
|
2021-11-03 13:28:15 +00:00
|
|
|
assert(rr->rtr != NULL);
|
2020-10-05 22:30:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_distortion(struct render_gfx *rr)
|
2020-10-05 22:30:31 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2022-03-27 21:10:25 +00:00
|
|
|
struct render_resources *r = rr->r;
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
uint32_t view = rr->current_view;
|
2022-03-27 21:10:25 +00:00
|
|
|
struct render_gfx_view *v = &rr->views[view];
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Descriptors and pipeline.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VkDescriptorSet descriptor_sets[1] = {v->mesh.descriptor_set};
|
|
|
|
vk->vkCmdBindDescriptorSets( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
|
|
|
|
r->mesh.pipeline_layout, // layout
|
|
|
|
0, // firstSet
|
|
|
|
ARRAY_SIZE(descriptor_sets), // descriptorSetCount
|
|
|
|
descriptor_sets, // pDescriptorSets
|
|
|
|
0, // dynamicOffsetCount
|
|
|
|
NULL); // pDynamicOffsets
|
|
|
|
|
|
|
|
vk->vkCmdBindPipeline( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
|
2021-11-03 13:28:15 +00:00
|
|
|
rr->rtr->mesh.pipeline); // pipeline
|
2020-10-05 22:30:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Vertex buffer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VkBuffer buffers[1] = {r->mesh.vbo.buffer};
|
|
|
|
VkDeviceSize offsets[1] = {0};
|
|
|
|
assert(ARRAY_SIZE(buffers) == ARRAY_SIZE(offsets));
|
|
|
|
|
|
|
|
vk->vkCmdBindVertexBuffers( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
0, // firstBinding
|
|
|
|
ARRAY_SIZE(buffers), // bindingCount
|
|
|
|
buffers, // pBuffers
|
|
|
|
offsets); // pOffsets
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Draw with indices or not?
|
|
|
|
*/
|
|
|
|
|
2021-11-08 21:02:03 +00:00
|
|
|
if (r->mesh.index_count_total > 0) {
|
2020-10-05 22:30:31 +00:00
|
|
|
vk->vkCmdBindIndexBuffer( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
r->mesh.ibo.buffer, // buffer
|
|
|
|
0, // offset
|
|
|
|
VK_INDEX_TYPE_UINT32); // indexType
|
|
|
|
|
2021-11-08 21:02:03 +00:00
|
|
|
vk->vkCmdDrawIndexed( //
|
|
|
|
rr->cmd, // commandBuffer
|
|
|
|
r->mesh.index_counts[view], // indexCount
|
|
|
|
1, // instanceCount
|
|
|
|
r->mesh.index_offsets[view], // firstIndex
|
|
|
|
0, // vertexOffset
|
|
|
|
0); // firstInstance
|
2020-10-05 22:30:31 +00:00
|
|
|
} else {
|
|
|
|
vk->vkCmdDraw( //
|
|
|
|
rr->cmd, // commandBuffer
|
2021-11-08 21:02:03 +00:00
|
|
|
r->mesh.vertex_count, // vertexCount
|
2020-10-05 22:30:31 +00:00
|
|
|
1, // instanceCount
|
|
|
|
0, // firstVertex
|
|
|
|
0); // firstInstance
|
|
|
|
}
|
|
|
|
}
|
2021-04-15 20:25:39 +00:00
|
|
|
|
|
|
|
void
|
2022-03-27 21:10:25 +00:00
|
|
|
render_gfx_update_distortion(struct render_gfx *rr,
|
|
|
|
uint32_t view_index,
|
|
|
|
VkSampler sampler,
|
|
|
|
VkImageView image_view,
|
|
|
|
struct render_gfx_mesh_ubo_data *data)
|
2021-04-15 20:25:39 +00:00
|
|
|
{
|
2021-11-02 13:54:16 +00:00
|
|
|
struct vk_bundle *vk = vk_from_rr(rr);
|
2022-03-27 21:10:25 +00:00
|
|
|
struct render_resources *r = rr->r;
|
|
|
|
struct render_gfx_view *v = &rr->views[view_index];
|
2021-04-15 20:25:39 +00:00
|
|
|
|
2022-03-27 21:10:25 +00:00
|
|
|
render_buffer_write(vk, &r->mesh.ubos[view_index], data, sizeof(struct render_gfx_mesh_ubo_data));
|
2021-09-29 16:35:05 +00:00
|
|
|
|
|
|
|
update_mesh_discriptor_set( //
|
|
|
|
vk, // vk_bundle
|
|
|
|
r->mesh.src_binding, // src_binding
|
|
|
|
sampler, // sampler
|
|
|
|
image_view, // image_view
|
|
|
|
r->mesh.ubo_binding, // ubo_binding
|
|
|
|
r->mesh.ubos[view_index].buffer, // buffer
|
|
|
|
VK_WHOLE_SIZE, // size
|
|
|
|
v->mesh.descriptor_set); // descriptor_set
|
2021-04-15 20:25:39 +00:00
|
|
|
}
|