Quake II RTX doxygen  1.0 dev
uniform_buffer.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2018 Christoph Schied
3 Copyright (C) 2019, NVIDIA CORPORATION. All rights reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include "vkpt.h"
21 
22 #include <assert.h>
23 
26 static VkDescriptorPool desc_pool_ubo;
27 static size_t ubo_alignment = 0;
28 
29 VkResult
31 {
32  VkDescriptorSetLayoutBinding ubo_layout_bindings[2] = { 0 };
33 
34  ubo_layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
35  ubo_layout_bindings[0].descriptorCount = 1;
36  ubo_layout_bindings[0].binding = GLOBAL_UBO_BINDING_IDX;
37  ubo_layout_bindings[0].stageFlags = VK_SHADER_STAGE_ALL;
38 
39  ubo_layout_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
40  ubo_layout_bindings[1].descriptorCount = 1;
41  ubo_layout_bindings[1].binding = GLOBAL_INSTANCE_BUFFER_BINDING_IDX;
42  ubo_layout_bindings[1].stageFlags = VK_SHADER_STAGE_ALL;
43 
44  VkDescriptorSetLayoutCreateInfo layout_info = {
45  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
46  .bindingCount = LENGTH(ubo_layout_bindings),
47  .pBindings = ubo_layout_bindings,
48  };
49 
50  _VK(vkCreateDescriptorSetLayout(qvk.device, &layout_info, NULL, &qvk.desc_set_layout_ubo));
51 
52  const VkMemoryPropertyFlags host_memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
53  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
54 
55  const VkMemoryPropertyFlags device_memory_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
56 
57  VkPhysicalDeviceProperties properties;
58  vkGetPhysicalDeviceProperties(qvk.physical_device, &properties);
59  ubo_alignment = properties.limits.minUniformBufferOffsetAlignment;
60 
61  const size_t buffer_size = align(sizeof(QVKUniformBuffer_t), ubo_alignment) + sizeof(QVKInstanceBuffer_t);
62  for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
63  buffer_create(host_uniform_buffers + i, buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, host_memory_flags);
64 
65  buffer_create(&device_uniform_buffer, buffer_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
66  device_memory_flags);
67 
68  VkDescriptorPoolSize pool_size = {
69  .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
70  .descriptorCount = MAX_FRAMES_IN_FLIGHT,
71  };
72 
73  VkDescriptorPoolCreateInfo pool_info = {
74  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
75  .poolSizeCount = 1,
76  .pPoolSizes = &pool_size,
77  .maxSets = MAX_FRAMES_IN_FLIGHT,
78  };
79 
80  _VK(vkCreateDescriptorPool(qvk.device, &pool_info, NULL, &desc_pool_ubo));
81 
82  VkDescriptorSetAllocateInfo descriptor_set_alloc_info = {
83  .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
84  .descriptorPool = desc_pool_ubo,
85  .descriptorSetCount = 1,
86  .pSetLayouts = &qvk.desc_set_layout_ubo,
87  };
88 
89  _VK(vkAllocateDescriptorSets(qvk.device, &descriptor_set_alloc_info, &qvk.desc_set_ubo));
90 
91  VkDescriptorBufferInfo buf_info = {
92  .buffer = device_uniform_buffer.buffer,
93  .offset = 0,
94  .range = sizeof(QVKUniformBuffer_t),
95  };
96 
97  VkDescriptorBufferInfo buf1_info = {
98  .buffer = device_uniform_buffer.buffer,
99  .offset = align(sizeof(QVKUniformBuffer_t), ubo_alignment),
100  .range = sizeof(QVKInstanceBuffer_t),
101  };
102 
103  VkWriteDescriptorSet writes[2] = { 0 };
104 
105  writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
106  writes[0].dstSet = qvk.desc_set_ubo,
107  writes[0].dstBinding = GLOBAL_UBO_BINDING_IDX,
108  writes[0].dstArrayElement = 0,
109  writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
110  writes[0].descriptorCount = 1,
111  writes[0].pBufferInfo = &buf_info,
112 
113  writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
114  writes[1].dstSet = qvk.desc_set_ubo,
115  writes[1].dstBinding = GLOBAL_INSTANCE_BUFFER_BINDING_IDX,
116  writes[1].dstArrayElement = 0,
117  writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
118  writes[1].descriptorCount = 1,
119  writes[1].pBufferInfo = &buf1_info,
120 
121  vkUpdateDescriptorSets(qvk.device, LENGTH(writes), writes, 0, NULL);
122 
123  return VK_SUCCESS;
124 }
125 
126 VkResult
128 {
129  vkDestroyDescriptorPool(qvk.device, desc_pool_ubo, NULL);
130  vkDestroyDescriptorSetLayout(qvk.device, qvk.desc_set_layout_ubo, NULL);
131  desc_pool_ubo = VK_NULL_HANDLE;
132  qvk.desc_set_layout_ubo = VK_NULL_HANDLE;
133 
134  for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
137 
138  return VK_SUCCESS;
139 }
140 
141 VkResult
142 vkpt_uniform_buffer_update(VkCommandBuffer command_buffer)
143 {
145  assert(ubo);
146  assert(ubo->memory != VK_NULL_HANDLE);
147  assert(ubo->buffer != VK_NULL_HANDLE);
149 
150  QVKUniformBuffer_t *mapped_ubo = buffer_map(ubo);
151  assert(mapped_ubo);
152  memcpy(mapped_ubo, &vkpt_refdef.uniform_buffer, sizeof(QVKUniformBuffer_t));
153 
154  const size_t offset = align(sizeof(QVKUniformBuffer_t), ubo_alignment);
155  memcpy((uint8_t*)mapped_ubo + offset, &vkpt_refdef.uniform_instance_buffer, sizeof(QVKInstanceBuffer_t));
156 
157  buffer_unmap(ubo);
158  mapped_ubo = NULL;
159 
160  VkBufferCopy copy = { 0 };
161  copy.size = align(sizeof(QVKUniformBuffer_t), ubo_alignment) + sizeof(QVKInstanceBuffer_t);
162  vkCmdCopyBuffer(command_buffer, ubo->buffer, device_uniform_buffer.buffer, 1, &copy);
163 
164  VkBufferMemoryBarrier barrier = {
165  .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
166  .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
167  .dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
168  .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
169  .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
170  .buffer = device_uniform_buffer.buffer,
171  .size = copy.size
172  };
173 
174  vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
175  0, 0, NULL, 1, &barrier, 0, NULL);
176 
177  return VK_SUCCESS;
178 }
179 
180 
181 // vim: shiftwidth=4 noexpandtab tabstop=4 cindent
QVK_s::desc_set_ubo
VkDescriptorSet desc_set_ubo
Definition: vkpt.h:226
desc_pool_ubo
static VkDescriptorPool desc_pool_ubo
Definition: uniform_buffer.c:26
QVKUniformBuffer_s
Definition: global_ubo.h:247
MAX_FRAMES_IN_FLIGHT
#define MAX_FRAMES_IN_FLIGHT
Definition: vkpt.h:140
QVK_s::device
VkDevice device
Definition: vkpt.h:172
vkpt_uniform_buffer_update
VkResult vkpt_uniform_buffer_update(VkCommandBuffer command_buffer)
Definition: uniform_buffer.c:142
align
static size_t align(size_t x, size_t alignment)
Definition: vk_util.h:143
vkpt_refdef
vkpt_refdef_t vkpt_refdef
Definition: main.c:372
GLOBAL_INSTANCE_BUFFER_BINDING_IDX
#define GLOBAL_INSTANCE_BUFFER_BINDING_IDX
Definition: global_ubo.h:26
QVKInstanceBuffer_s
Definition: global_ubo.h:253
buffer_unmap
void buffer_unmap(BufferResource_t *buf)
Definition: vk_util.c:159
QVK_s::current_frame_index
uint32_t current_frame_index
Definition: vkpt.h:219
vkpt.h
vkpt_uniform_buffer_destroy
VkResult vkpt_uniform_buffer_destroy()
Definition: uniform_buffer.c:127
buffer_destroy
VkResult buffer_destroy(BufferResource_t *buf)
Definition: vk_util.c:132
QVK_s::physical_device
VkPhysicalDevice physical_device
Definition: vkpt.h:163
_VK
#define _VK(...)
Definition: vkpt.h:65
GLOBAL_UBO_BINDING_IDX
#define GLOBAL_UBO_BINDING_IDX
Definition: global_ubo.h:25
BufferResource_s::buffer
VkBuffer buffer
Definition: vk_util.h:34
ubo_alignment
static size_t ubo_alignment
Definition: uniform_buffer.c:27
LENGTH
#define LENGTH(a)
Definition: tent.c:228
QVKUniformBuffer_t
struct QVKUniformBuffer_s QVKUniformBuffer_t
device_uniform_buffer
static BufferResource_t device_uniform_buffer
Definition: uniform_buffer.c:25
host_uniform_buffers
static BufferResource_t host_uniform_buffers[MAX_FRAMES_IN_FLIGHT]
Definition: uniform_buffer.c:24
QVKInstanceBuffer_t
struct QVKInstanceBuffer_s QVKInstanceBuffer_t
qvk
QVK_t qvk
Definition: main.c:377
BufferResource_s
Definition: vk_util.h:33
vkpt_refdef_s::uniform_instance_buffer
QVKInstanceBuffer_t uniform_instance_buffer
Definition: vkpt.h:395
buffer_create
VkResult buffer_create(BufferResource_t *buf, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags mem_properties)
Definition: vk_util.c:57
QVK_s::desc_set_layout_ubo
VkDescriptorSetLayout desc_set_layout_ubo
Definition: vkpt.h:225
buffer_map
void * buffer_map(BufferResource_t *buf)
Definition: vk_util.c:147
vkpt_refdef_s::uniform_buffer
QVKUniformBuffer_t uniform_buffer
Definition: vkpt.h:394
vkpt_uniform_buffer_create
VkResult vkpt_uniform_buffer_create()
Definition: uniform_buffer.c:30
BufferResource_s::memory
VkDeviceMemory memory
Definition: vk_util.h:35