52 #include <QVulkanFunctions>
59 static float vertexData[] = {
60 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
61 -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
62 0.5f, -0.5f, 0.0f, 0.0f, 1.0f
65 static const int UNIFORM_DATA_SIZE = 16 *
sizeof(float);
67 static inline VkDeviceSize aligned(VkDeviceSize
v, VkDeviceSize byteAlign)
69 return (
v + byteAlign - 1) & ~(byteAlign - 1);
76 const QList<int> counts =
w->supportedSampleCounts();
77 qDebug() <<
"Supported sample counts:" << counts;
78 for (
int s = 16;
s >= 4;
s /= 2) {
80 qDebug(
"Requesting sample count %d",
s);
93 return VK_NULL_HANDLE;
98 VkShaderModuleCreateInfo shaderInfo;
99 memset(&shaderInfo, 0,
sizeof(shaderInfo));
100 shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
101 shaderInfo.codeSize = blob.
size();
102 shaderInfo.pCode =
reinterpret_cast<const uint32_t *
>(blob.
constData());
103 VkShaderModule shaderModule;
104 VkResult err =
m_devFuncs->vkCreateShaderModule(
m_window->device(), &shaderInfo,
nullptr, &shaderModule);
105 if (err != VK_SUCCESS) {
106 qWarning(
"Failed to create shader module: %d", err);
107 return VK_NULL_HANDLE;
136 const int concurrentFrameCount =
m_window->concurrentFrameCount();
137 const VkPhysicalDeviceLimits *pdevLimits = &
m_window->physicalDeviceProperties()->limits;
138 const VkDeviceSize uniAlign = pdevLimits->minUniformBufferOffsetAlignment;
139 qDebug(
"uniform buffer offset alignment is %u", (
uint) uniAlign);
140 VkBufferCreateInfo bufInfo;
141 memset(&bufInfo, 0,
sizeof(bufInfo));
142 bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
144 const VkDeviceSize vertexAllocSize = aligned(
sizeof(vertexData), uniAlign);
145 const VkDeviceSize uniformAllocSize = aligned(UNIFORM_DATA_SIZE, uniAlign);
146 bufInfo.size = vertexAllocSize + concurrentFrameCount * uniformAllocSize;
147 bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
149 VkResult err =
m_devFuncs->vkCreateBuffer(dev, &bufInfo,
nullptr, &
m_buf);
150 if (err != VK_SUCCESS)
151 qFatal(
"Failed to create buffer: %d", err);
153 VkMemoryRequirements memReq;
156 VkMemoryAllocateInfo memAllocInfo = {
157 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
164 if (err != VK_SUCCESS)
165 qFatal(
"Failed to allocate memory: %d", err);
168 if (err != VK_SUCCESS)
169 qFatal(
"Failed to bind buffer memory: %d", err);
172 err =
m_devFuncs->vkMapMemory(dev,
m_bufMem, 0, memReq.size, 0,
reinterpret_cast<void **
>(&
p));
173 if (err != VK_SUCCESS)
174 qFatal(
"Failed to map memory: %d", err);
175 memcpy(
p, vertexData,
sizeof(vertexData));
178 for (
int i = 0;
i < concurrentFrameCount; ++
i) {
179 const VkDeviceSize
offset = vertexAllocSize +
i * uniformAllocSize;
180 memcpy(
p +
offset,
ident.constData(), 16 *
sizeof(
float));
187 VkVertexInputBindingDescription vertexBindingDesc = {
190 VK_VERTEX_INPUT_RATE_VERTEX
192 VkVertexInputAttributeDescription vertexAttrDesc[] = {
196 VK_FORMAT_R32G32_SFLOAT,
202 VK_FORMAT_R32G32B32_SFLOAT,
207 VkPipelineVertexInputStateCreateInfo vertexInputInfo;
208 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
209 vertexInputInfo.pNext =
nullptr;
210 vertexInputInfo.flags = 0;
211 vertexInputInfo.vertexBindingDescriptionCount = 1;
212 vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDesc;
213 vertexInputInfo.vertexAttributeDescriptionCount = 2;
214 vertexInputInfo.pVertexAttributeDescriptions = vertexAttrDesc;
217 VkDescriptorPoolSize descPoolSizes = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount) };
218 VkDescriptorPoolCreateInfo descPoolInfo;
219 memset(&descPoolInfo, 0,
sizeof(descPoolInfo));
220 descPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
221 descPoolInfo.maxSets = concurrentFrameCount;
222 descPoolInfo.poolSizeCount = 1;
223 descPoolInfo.pPoolSizes = &descPoolSizes;
225 if (err != VK_SUCCESS)
226 qFatal(
"Failed to create descriptor pool: %d", err);
228 VkDescriptorSetLayoutBinding layoutBinding = {
230 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
232 VK_SHADER_STAGE_VERTEX_BIT,
235 VkDescriptorSetLayoutCreateInfo descLayoutInfo = {
236 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
243 if (err != VK_SUCCESS)
244 qFatal(
"Failed to create descriptor set layout: %d", err);
246 for (
int i = 0;
i < concurrentFrameCount; ++
i) {
247 VkDescriptorSetAllocateInfo descSetAllocInfo = {
248 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
255 if (err != VK_SUCCESS)
256 qFatal(
"Failed to allocate descriptor set: %d", err);
258 VkWriteDescriptorSet descWrite;
259 memset(&descWrite, 0,
sizeof(descWrite));
260 descWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
262 descWrite.descriptorCount = 1;
263 descWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
265 m_devFuncs->vkUpdateDescriptorSets(dev, 1, &descWrite, 0,
nullptr);
269 VkPipelineCacheCreateInfo pipelineCacheInfo;
270 memset(&pipelineCacheInfo, 0,
sizeof(pipelineCacheInfo));
271 pipelineCacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
273 if (err != VK_SUCCESS)
274 qFatal(
"Failed to create pipeline cache: %d", err);
277 VkPipelineLayoutCreateInfo pipelineLayoutInfo;
278 memset(&pipelineLayoutInfo, 0,
sizeof(pipelineLayoutInfo));
279 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
280 pipelineLayoutInfo.setLayoutCount = 1;
283 if (err != VK_SUCCESS)
284 qFatal(
"Failed to create pipeline layout: %d", err);
291 VkGraphicsPipelineCreateInfo pipelineInfo;
292 memset(&pipelineInfo, 0,
sizeof(pipelineInfo));
293 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
295 VkPipelineShaderStageCreateInfo shaderStages[2] = {
297 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
300 VK_SHADER_STAGE_VERTEX_BIT,
306 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
309 VK_SHADER_STAGE_FRAGMENT_BIT,
315 pipelineInfo.stageCount = 2;
316 pipelineInfo.pStages = shaderStages;
318 pipelineInfo.pVertexInputState = &vertexInputInfo;
320 VkPipelineInputAssemblyStateCreateInfo ia;
321 memset(&ia, 0,
sizeof(ia));
322 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
323 ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
324 pipelineInfo.pInputAssemblyState = &ia;
328 VkPipelineViewportStateCreateInfo vp;
329 memset(&vp, 0,
sizeof(vp));
330 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
331 vp.viewportCount = 1;
333 pipelineInfo.pViewportState = &vp;
335 VkPipelineRasterizationStateCreateInfo rs;
336 memset(&rs, 0,
sizeof(rs));
337 rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
338 rs.polygonMode = VK_POLYGON_MODE_FILL;
339 rs.cullMode = VK_CULL_MODE_NONE;
340 rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
342 pipelineInfo.pRasterizationState = &rs;
344 VkPipelineMultisampleStateCreateInfo
ms;
345 memset(&
ms, 0,
sizeof(
ms));
346 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
348 ms.rasterizationSamples =
m_window->sampleCountFlagBits();
349 pipelineInfo.pMultisampleState = &
ms;
351 VkPipelineDepthStencilStateCreateInfo ds;
352 memset(&ds, 0,
sizeof(ds));
353 ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
354 ds.depthTestEnable = VK_TRUE;
355 ds.depthWriteEnable = VK_TRUE;
356 ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
357 pipelineInfo.pDepthStencilState = &ds;
359 VkPipelineColorBlendStateCreateInfo
cb;
360 memset(&
cb, 0,
sizeof(
cb));
361 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
363 VkPipelineColorBlendAttachmentState att;
364 memset(&att, 0,
sizeof(att));
365 att.colorWriteMask = 0xF;
366 cb.attachmentCount = 1;
367 cb.pAttachments = &att;
368 pipelineInfo.pColorBlendState = &
cb;
370 VkDynamicState dynEnable[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
371 VkPipelineDynamicStateCreateInfo dyn;
372 memset(&dyn, 0,
sizeof(dyn));
373 dyn.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
374 dyn.dynamicStateCount =
sizeof(dynEnable) /
sizeof(VkDynamicState);
375 dyn.pDynamicStates = dynEnable;
376 pipelineInfo.pDynamicState = &dyn;
379 pipelineInfo.renderPass =
m_window->defaultRenderPass();
382 if (err != VK_SUCCESS)
383 qFatal(
"Failed to create graphics pipeline: %d", err);
385 if (vertShaderModule)
386 m_devFuncs->vkDestroyShaderModule(dev, vertShaderModule,
nullptr);
387 if (fragShaderModule)
388 m_devFuncs->vkDestroyShaderModule(dev, fragShaderModule,
nullptr);
393 qDebug(
"initSwapChainResources");
404 qDebug(
"releaseSwapChainResources");
409 qDebug(
"releaseResources");
440 m_buf = VK_NULL_HANDLE;
452 VkCommandBuffer
cb =
m_window->currentCommandBuffer();
455 VkClearColorValue clearColor = {{ 0, 0, 0, 1 }};
456 VkClearDepthStencilValue clearDS = { 1, 0 };
457 VkClearValue clearValues[3];
458 memset(clearValues, 0,
sizeof(clearValues));
459 clearValues[0].color = clearValues[2].color = clearColor;
460 clearValues[1].depthStencil = clearDS;
462 VkRenderPassBeginInfo rpBeginInfo;
463 memset(&rpBeginInfo, 0,
sizeof(rpBeginInfo));
464 rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
465 rpBeginInfo.renderPass =
m_window->defaultRenderPass();
466 rpBeginInfo.framebuffer =
m_window->currentFramebuffer();
467 rpBeginInfo.renderArea.extent.width = sz.
width();
468 rpBeginInfo.renderArea.extent.height = sz.
height();
469 rpBeginInfo.clearValueCount =
m_window->sampleCountFlagBits() > VK_SAMPLE_COUNT_1_BIT ? 3 : 2;
470 rpBeginInfo.pClearValues = clearValues;
472 m_devFuncs->vkCmdBeginRenderPass(
cmdBuf, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
476 UNIFORM_DATA_SIZE, 0,
reinterpret_cast<void **
>(&
p));
477 if (err != VK_SUCCESS)
478 qFatal(
"Failed to map memory: %d", err);
481 memcpy(
p,
m.constData(), 16 *
sizeof(
float));
490 VkDeviceSize vbOffset = 0;
502 scissor.offset.x = scissor.offset.y = 0;
503 scissor.extent.width =
viewport.width;
504 scissor.extent.height =
viewport.height;
small capitals from c petite p scientific i
[1]
The QByteArray class provides an array of bytes.
qsizetype size() const noexcept
const char * constData() const noexcept
The QFile class provides an interface for reading from and writing to files.
bool open(OpenMode flags) override
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
void rotate(float angle, const QVector3D &vector)
void perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane)
void translate(const QVector3D &vector)
The QSize class defines the size of a two-dimensional object using integer point precision.
constexpr int height() const noexcept
constexpr int width() const noexcept
The QString class provides a Unicode character string.
The QVulkanWindow class is a convenience subclass of QWindow to perform Vulkan rendering.
QVulkanDeviceFunctions * m_devFuncs
VkPipelineLayout m_pipelineLayout
VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]
VkDescriptorPool m_descPool
void initSwapChainResources() override
void releaseSwapChainResources() override
void releaseResources() override
VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]
void initResources() override
void startNextFrame() override
TriangleRenderer(QVulkanWindow *w, bool msaa=false)
VkDescriptorSetLayout m_descSetLayout
VkPipelineCache m_pipelineCache
VkShaderModule createShader(const QString &name)
std::chrono::milliseconds ms
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr offset
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
view viewport() -> scroll(dx, dy, deviceRect)
bool contains(const AT &t) const noexcept