diff --git a/data/shaders/offscreen/mirror.frag.spv b/data/shaders/offscreen/mirror.frag.spv index 6ef79328..0f9710bb 100644 Binary files a/data/shaders/offscreen/mirror.frag.spv and b/data/shaders/offscreen/mirror.frag.spv differ diff --git a/data/shaders/offscreen/mirror.vert b/data/shaders/offscreen/mirror.vert index 7526b4e5..7e4bb2d8 100644 --- a/data/shaders/offscreen/mirror.vert +++ b/data/shaders/offscreen/mirror.vert @@ -16,6 +16,11 @@ layout (binding = 0) uniform UBO layout (location = 0) out vec2 outUV; layout (location = 1) out vec4 outPos; +out gl_PerVertex +{ + vec4 gl_Position; +}; + void main() { outUV = inUV; diff --git a/data/shaders/offscreen/mirror.vert.spv b/data/shaders/offscreen/mirror.vert.spv index d8839953..e7b7d46e 100644 Binary files a/data/shaders/offscreen/mirror.vert.spv and b/data/shaders/offscreen/mirror.vert.spv differ diff --git a/data/shaders/offscreen/offscreen.frag.spv b/data/shaders/offscreen/offscreen.frag.spv index b266f832..672e1f82 100644 Binary files a/data/shaders/offscreen/offscreen.frag.spv and b/data/shaders/offscreen/offscreen.frag.spv differ diff --git a/data/shaders/offscreen/offscreen.vert b/data/shaders/offscreen/offscreen.vert index 0322e2c8..5f802b0d 100644 --- a/data/shaders/offscreen/offscreen.vert +++ b/data/shaders/offscreen/offscreen.vert @@ -19,6 +19,11 @@ layout (location = 1) out vec3 outColor; layout (location = 2) out vec3 outEyePos; layout (location = 3) out vec3 outLightVec; +out gl_PerVertex +{ + vec4 gl_Position; +}; + void main() { outNormal = inNormal; diff --git a/data/shaders/offscreen/offscreen.vert.spv b/data/shaders/offscreen/offscreen.vert.spv index 4d051c82..05e10191 100644 Binary files a/data/shaders/offscreen/offscreen.vert.spv and b/data/shaders/offscreen/offscreen.vert.spv differ diff --git a/data/shaders/offscreen/quad.frag.spv b/data/shaders/offscreen/quad.frag.spv index 7b84c35a..38044a2e 100644 Binary files a/data/shaders/offscreen/quad.frag.spv and b/data/shaders/offscreen/quad.frag.spv differ diff --git a/data/shaders/offscreen/quad.vert b/data/shaders/offscreen/quad.vert index fe704c9c..f6d023e8 100644 --- a/data/shaders/offscreen/quad.vert +++ b/data/shaders/offscreen/quad.vert @@ -14,6 +14,11 @@ layout (binding = 0) uniform UBO layout (location = 0) out vec2 outUV; +out gl_PerVertex +{ + vec4 gl_Position; +}; + void main() { outUV = inUV; diff --git a/data/shaders/offscreen/quad.vert.spv b/data/shaders/offscreen/quad.vert.spv index 023de7eb..dbaf4b66 100644 Binary files a/data/shaders/offscreen/quad.vert.spv and b/data/shaders/offscreen/quad.vert.spv differ diff --git a/offscreen/offscreen.cpp b/offscreen/offscreen.cpp index 5ee3c16b..21ce01ef 100644 --- a/offscreen/offscreen.cpp +++ b/offscreen/offscreen.cpp @@ -109,7 +109,7 @@ public: int32_t width, height; VkFramebuffer frameBuffer; FrameBufferAttachment color, depth; - // Texture target for framebugger blut + // Texture target for offscreen framebuffer vkTools::VulkanTexture textureTarget; } offScreenFrameBuf; @@ -122,6 +122,7 @@ public: zoom = -6.5f; rotation = { -11.25f, 45.0f, 0.0f }; timerSpeed *= 0.25f; + enableTextOverlay = true; title = "Vulkan Example - Offscreen rendering"; } @@ -175,12 +176,8 @@ public: // the offscreen framebuffer void prepareTextureTarget(uint32_t width, uint32_t height, VkFormat format) { - createSetupCommandBuffer(); - + // Get device properties for the requested texture format VkFormatProperties formatProperties; - VkResult err; - - // Get device properites for the requested texture format vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProperties); // Check if blit destination is supported for the requested format // Only try for optimal tiling, linear tiling usually won't support blit as destination anyway @@ -205,27 +202,30 @@ public: VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); VkMemoryRequirements memReqs; - err = vkCreateImage(device, &imageCreateInfo, nullptr, &offScreenFrameBuf.textureTarget.image); - assert(!err); + VK_CHECK_RESULT(vkCreateImage(device, &imageCreateInfo, nullptr, &offScreenFrameBuf.textureTarget.image)); vkGetImageMemoryRequirements(device, offScreenFrameBuf.textureTarget.image, &memReqs); memAllocInfo.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAllocInfo.memoryTypeIndex); - err = vkAllocateMemory(device, &memAllocInfo, nullptr, &offScreenFrameBuf.textureTarget.deviceMemory); - assert(!err); - err = vkBindImageMemory(device, offScreenFrameBuf.textureTarget.image, offScreenFrameBuf.textureTarget.deviceMemory, 0); - assert(!err); + memAllocInfo.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &offScreenFrameBuf.textureTarget.deviceMemory)); + VK_CHECK_RESULT(vkBindImageMemory(device, offScreenFrameBuf.textureTarget.image, offScreenFrameBuf.textureTarget.deviceMemory, 0)); + + // Get a primary command buffer for submitting image layout transition + VkCommandBuffer layoutCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); // Image memory barrier // Set initial layout for the offscreen texture transfer destination // Will be transformed while updating the texture offScreenFrameBuf.textureTarget.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; vkTools::setImageLayout( - setupCmdBuffer, + layoutCmd, offScreenFrameBuf.textureTarget.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, offScreenFrameBuf.textureTarget.imageLayout); + // Submit the command buffer to apply the image memory barrier + VulkanExampleBase::flushCommandBuffer(layoutCmd, queue, true); + // Create sampler VkSamplerCreateInfo sampler = vkTools::initializers::samplerCreateInfo(); sampler.magFilter = TEX_FILTER; @@ -240,23 +240,18 @@ public: sampler.minLod = 0.0f; sampler.maxLod = 0.0f; sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - err = vkCreateSampler(device, &sampler, nullptr, &offScreenFrameBuf.textureTarget.sampler); - assert(!err); + VK_CHECK_RESULT(vkCreateSampler(device, &sampler, nullptr, &offScreenFrameBuf.textureTarget.sampler)); // Create image view VkImageViewCreateInfo view = {}; view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view.pNext = NULL; - view.image = VK_NULL_HANDLE; view.viewType = VK_IMAGE_VIEW_TYPE_2D; view.format = format; view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; view.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; view.image = offScreenFrameBuf.textureTarget.image; - err = vkCreateImageView(device, &view, nullptr, &offScreenFrameBuf.textureTarget.view); - assert(!err); - - flushSetupCommandBuffer(); + VK_CHECK_RESULT(vkCreateImageView(device, &view, nullptr, &offScreenFrameBuf.textureTarget.view)); } // Prepare a new framebuffer for offscreen rendering @@ -264,9 +259,6 @@ public: // blitted to our render target void prepareOffscreenFramebuffer() { - - createSetupCommandBuffer(); - offScreenFrameBuf.width = FB_DIM; offScreenFrameBuf.height = FB_DIM; @@ -277,8 +269,6 @@ public: VkBool32 validDepthFormat = vkTools::getSupportedDepthFormat(physicalDevice, &fbDepthFormat); assert(validDepthFormat); - VkResult err; - // Color attachment VkImageCreateInfo image = vkTools::initializers::imageCreateInfo(); image.imageType = VK_IMAGE_TYPE_2D; @@ -307,27 +297,25 @@ public: colorImageView.subresourceRange.baseArrayLayer = 0; colorImageView.subresourceRange.layerCount = 1; - err = vkCreateImage(device, &image, nullptr, &offScreenFrameBuf.color.image); - assert(!err); + VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &offScreenFrameBuf.color.image)); vkGetImageMemoryRequirements(device, offScreenFrameBuf.color.image, &memReqs); memAlloc.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAlloc.memoryTypeIndex); - err = vkAllocateMemory(device, &memAlloc, nullptr, &offScreenFrameBuf.color.mem); - assert(!err); + memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &offScreenFrameBuf.color.mem)); + VK_CHECK_RESULT(vkBindImageMemory(device, offScreenFrameBuf.color.image, offScreenFrameBuf.color.mem, 0)); - err = vkBindImageMemory(device, offScreenFrameBuf.color.image, offScreenFrameBuf.color.mem, 0); - assert(!err); + // Get a primary command buffer for submitting image layout transitions for the framebuffer attachments + VkCommandBuffer layoutCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); vkTools::setImageLayout( - setupCmdBuffer, + layoutCmd, offScreenFrameBuf.color.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); colorImageView.image = offScreenFrameBuf.color.image; - err = vkCreateImageView(device, &colorImageView, nullptr, &offScreenFrameBuf.color.view); - assert(!err); + VK_CHECK_RESULT(vkCreateImageView(device, &colorImageView, nullptr, &offScreenFrameBuf.color.view)); // Depth stencil attachment image.format = fbDepthFormat; @@ -344,29 +332,25 @@ public: depthStencilView.subresourceRange.baseArrayLayer = 0; depthStencilView.subresourceRange.layerCount = 1; - err = vkCreateImage(device, &image, nullptr, &offScreenFrameBuf.depth.image); - assert(!err); + VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &offScreenFrameBuf.depth.image)); vkGetImageMemoryRequirements(device, offScreenFrameBuf.depth.image, &memReqs); memAlloc.allocationSize = memReqs.size; - getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAlloc.memoryTypeIndex); - err = vkAllocateMemory(device, &memAlloc, nullptr, &offScreenFrameBuf.depth.mem); - assert(!err); - - err = vkBindImageMemory(device, offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.mem, 0); - assert(!err); + memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &offScreenFrameBuf.depth.mem)); + VK_CHECK_RESULT(vkBindImageMemory(device, offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.mem, 0)); vkTools::setImageLayout( - setupCmdBuffer, + layoutCmd, offScreenFrameBuf.depth.image, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - depthStencilView.image = offScreenFrameBuf.depth.image; - err = vkCreateImageView(device, &depthStencilView, nullptr, &offScreenFrameBuf.depth.view); - assert(!err); + // Submit the command buffer to apply the image memory barrier + VulkanExampleBase::flushCommandBuffer(layoutCmd, queue, true); - flushSetupCommandBuffer(); + depthStencilView.image = offScreenFrameBuf.depth.image; + VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &offScreenFrameBuf.depth.view)); VkImageView attachments[2]; attachments[0] = offScreenFrameBuf.color.view; @@ -380,8 +364,7 @@ public: fbufCreateInfo.height = offScreenFrameBuf.height; fbufCreateInfo.layers = 1; - err = vkCreateFramebuffer(device, &fbufCreateInfo, nullptr, &offScreenFrameBuf.frameBuffer); - assert(!err); + VK_CHECK_RESULT(vkCreateFramebuffer(device, &fbufCreateInfo, nullptr, &offScreenFrameBuf.frameBuffer)); } void createOffscreenCommandBuffer() @@ -390,8 +373,7 @@ public: cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); - VkResult vkRes = vkAllocateCommandBuffers(device, &cmd, &offScreenCmdBuffer); - assert(!vkRes); + VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmd, &offScreenCmdBuffer)); } // The command buffer to copy for rendering @@ -400,8 +382,6 @@ public: // and gets resubmitted void buildOffscreenCommandBuffer() { - VkResult err; - VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); VkClearValue clearValues[2]; @@ -416,23 +396,14 @@ public: renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; - err = vkBeginCommandBuffer(offScreenCmdBuffer, &cmdBufInfo); - assert(!err); + VK_CHECK_RESULT(vkBeginCommandBuffer(offScreenCmdBuffer, &cmdBufInfo)); vkCmdBeginRenderPass(offScreenCmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = vkTools::initializers::viewport( - (float)offScreenFrameBuf.width, - (float)offScreenFrameBuf.height, - 0.0f, - 1.0f); + VkViewport viewport = vkTools::initializers::viewport((float)offScreenFrameBuf.width, (float)offScreenFrameBuf.height, 0.0f, 1.0f); vkCmdSetViewport(offScreenCmdBuffer, 0, 1, &viewport); - VkRect2D scissor = vkTools::initializers::rect2D( - offScreenFrameBuf.width, - offScreenFrameBuf.height, - 0, - 0); + VkRect2D scissor = vkTools::initializers::rect2D(offScreenFrameBuf.width, offScreenFrameBuf.height, 0, 0); vkCmdSetScissor(offScreenCmdBuffer, 0, 1, &scissor); VkDeviceSize offsets[1] = { 0 }; @@ -516,8 +487,17 @@ public: VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - err = vkEndCommandBuffer(offScreenCmdBuffer); - assert(!err); + VK_CHECK_RESULT(vkEndCommandBuffer(offScreenCmdBuffer)); + } + + void reBuildCommandBuffers() + { + if (!checkCommandBuffers()) + { + destroyCommandBuffers(); + createCommandBuffers(); + } + buildCommandBuffers(); } void buildCommandBuffers() @@ -537,30 +517,19 @@ public: renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; - VkResult err; - for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; - err = vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo); - assert(!err); + VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = vkTools::initializers::viewport( - (float)width, - (float)height, - 0.0f, - 1.0f); + VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); - VkRect2D scissor = vkTools::initializers::rect2D( - width, - height, - 0, - 0); + VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); VkDeviceSize offsets[1] = { 0 }; @@ -595,42 +564,10 @@ public: vkCmdEndRenderPass(drawCmdBuffers[i]); - err = vkEndCommandBuffer(drawCmdBuffers[i]); - assert(!err); + VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } } - void draw() - { - VkResult err; - - // Get next image in the swap chain (back/front buffer) - err = swapChain.acquireNextImage(semaphores.presentComplete, ¤tBuffer); - assert(!err); - - submitPostPresentBarrier(swapChain.buffers[currentBuffer].image); - - // Gather command buffers to be sumitted to the queue - std::vector submitCmdBuffers = { - offScreenCmdBuffer, - drawCmdBuffers[currentBuffer], - }; - submitInfo.commandBufferCount = submitCmdBuffers.size(); - submitInfo.pCommandBuffers = submitCmdBuffers.data(); - - // Submit to queue - err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); - assert(!err); - - submitPrePresentBarrier(swapChain.buffers[currentBuffer].image); - - err = swapChain.queuePresent(queue, currentBuffer, semaphores.renderComplete); - assert(!err); - - err = vkQueueWaitIdle(queue); - assert(!err); - } - void loadMeshes() { loadMesh(getAssetPath() + "models/plane.obj", &meshes.plane, vertexLayout, 0.4f); @@ -746,8 +683,7 @@ public: poolSizes.data(), 5); - VkResult vkRes = vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool); - assert(!vkRes); + VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); } void setupDescriptorSetLayout() @@ -777,20 +713,17 @@ public: setLayoutBindings.data(), setLayoutBindings.size()); - VkResult err = vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout); - assert(!err); + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = vkTools::initializers::pipelineLayoutCreateInfo( &descriptorSetLayout, 1); - err = vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.quad); - assert(!err); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.quad)); // Offscreen pipeline layout - err = vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.offscreen); - assert(!err); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.offscreen)); } void setupDescriptorSet() @@ -802,8 +735,7 @@ public: &descriptorSetLayout, 1); - VkResult vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.mirror); - assert(!vkRes); + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.mirror)); // Image descriptor for the offscreen mirror texture VkDescriptorImageInfo texDescriptorMirror = @@ -845,8 +777,7 @@ public: // Model // No texture - vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.model); - assert(!vkRes); + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.model)); std::vector modelWriteDescriptorSets = { @@ -860,8 +791,7 @@ public: vkUpdateDescriptorSets(device, modelWriteDescriptorSets.size(), modelWriteDescriptorSets.data(), 0, NULL); // Offscreen - vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.offscreen); - assert(!vkRes); + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.offscreen)); std::vector offScreenWriteDescriptorSets = { @@ -875,8 +805,7 @@ public: vkUpdateDescriptorSets(device, offScreenWriteDescriptorSets.size(), offScreenWriteDescriptorSets.data(), 0, NULL); // Debug quad - vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.debugQuad); - assert(!vkRes); + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.debugQuad)); std::vector debugQuadWriteDescriptorSets = { @@ -969,15 +898,13 @@ public: pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); - VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.debug); - assert(!err); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.debug)); // Mirror shaderStages[0] = loadShader(getAssetPath() + "shaders/offscreen/mirror.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/offscreen/mirror.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.mirror); - assert(!err); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.mirror)); // Solid shading pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/offscreen/offscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); @@ -985,8 +912,7 @@ public: pipelineCreateInfo.layout = pipelineLayouts.offscreen; - err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.shaded); - assert(!err); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.shaded)); } // Prepare and initialize uniform buffer containing shader uniforms @@ -995,6 +921,7 @@ public: // Mesh vertex shader uniform buffer block createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(ubos.vsShared), nullptr, &uniformData.vsShared.buffer, @@ -1004,6 +931,7 @@ public: // Mirror plane vertex shader uniform buffer block createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(ubos.vsShared), nullptr, &uniformData.vsMirror.buffer, @@ -1013,6 +941,7 @@ public: // Offscreen vertex shader uniform buffer block createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(ubos.vsShared), nullptr, &uniformData.vsOffScreen.buffer, @@ -1022,6 +951,7 @@ public: // Debug quad vertex shader uniform buffer block createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(ubos.vsShared), nullptr, &uniformData.vsDebugQuad.buffer, @@ -1038,7 +968,7 @@ public: ubos.vsShared.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.1f, 256.0f); glm::mat4 viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom)); - ubos.vsShared.model = viewMatrix * glm::translate(glm::mat4(), glm::vec3(0, 0, 0)); + ubos.vsShared.model = viewMatrix * glm::translate(glm::mat4(), cameraPos); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); @@ -1046,28 +976,25 @@ public: ubos.vsShared.model = glm::translate(ubos.vsShared.model, meshPos); uint8_t *pData; - VkResult err = vkMapMemory(device, uniformData.vsShared.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData); - assert(!err); + VK_CHECK_RESULT(vkMapMemory(device, uniformData.vsShared.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData)); memcpy(pData, &ubos.vsShared, sizeof(ubos.vsShared)); vkUnmapMemory(device, uniformData.vsShared.memory); // Mirror - ubos.vsShared.model = viewMatrix * glm::translate(glm::mat4(), glm::vec3(0, 0, 0)); + ubos.vsShared.model = viewMatrix * glm::translate(glm::mat4(), cameraPos); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); - err = vkMapMemory(device, uniformData.vsMirror.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData); - assert(!err); + VK_CHECK_RESULT(vkMapMemory(device, uniformData.vsMirror.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData)); memcpy(pData, &ubos.vsShared, sizeof(ubos.vsShared)); vkUnmapMemory(device, uniformData.vsMirror.memory); // Debug quad - ubos.vsShared.projection = glm::ortho(0.0f, 4.0f, 0.0f, 4.0f*(float)height / (float)width, -1.0f, 1.0f); + ubos.vsShared.projection = glm::ortho(4.0f, 0.0f, 0.0f, 4.0f*(float)height / (float)width, -1.0f, 1.0f); ubos.vsShared.model = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, 0.0f)); - err = vkMapMemory(device, uniformData.vsDebugQuad.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData); - assert(!err); + VK_CHECK_RESULT(vkMapMemory(device, uniformData.vsDebugQuad.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData)); memcpy(pData, &ubos.vsShared, sizeof(ubos.vsShared)); vkUnmapMemory(device, uniformData.vsDebugQuad.memory); } @@ -1077,7 +1004,7 @@ public: ubos.vsShared.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.1f, 256.0f); glm::mat4 viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom)); - ubos.vsShared.model = viewMatrix * glm::translate(glm::mat4(), glm::vec3(0, 0, 0)); + ubos.vsShared.model = viewMatrix * glm::translate(glm::mat4(), cameraPos); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); ubos.vsShared.model = glm::rotate(ubos.vsShared.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); @@ -1086,12 +1013,30 @@ public: ubos.vsShared.model = glm::translate(ubos.vsShared.model, meshPos); uint8_t *pData; - VkResult err = vkMapMemory(device, uniformData.vsOffScreen.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData); - assert(!err); + VK_CHECK_RESULT(vkMapMemory(device, uniformData.vsOffScreen.memory, 0, sizeof(ubos.vsShared), 0, (void **)&pData)); memcpy(pData, &ubos.vsShared, sizeof(ubos.vsShared)); vkUnmapMemory(device, uniformData.vsOffScreen.memory); } + void draw() + { + VulkanExampleBase::prepareFrame(); + + // Submit offscreen rendering command buffer + // todo : use event to ensure that offscreen result is finished bfore render command buffer is started + std::vector submitCmdBuffers = { + offScreenCmdBuffer, + drawCmdBuffers[currentBuffer], + }; + submitCmdBuffers.push_back(drawCmdBuffers[currentBuffer]); + submitInfo.commandBufferCount = submitCmdBuffers.size(); + submitInfo.pCommandBuffers = submitCmdBuffers.data(); + + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); + + VulkanExampleBase::submitFrame(); + } + void prepare() { VulkanExampleBase::prepare(); @@ -1131,6 +1076,32 @@ public: updateUniformBuffers(); updateUniformBufferOffscreen(); } + + virtual void keyPressed(uint32_t keyCode) + { + switch (keyCode) + { + case 0x44: + case GAMEPAD_BUTTON_A: + toggleDebugDisplay(); + break; + } + } + + virtual void getOverlayText(VulkanTextOverlay *textOverlay) + { +#if defined(__ANDROID__) + textOverlay->addText("Press \"Button A\" to display offscreen target", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); +#else + textOverlay->addText("Press \"d\" to display offscreen target", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); +#endif + } + + void toggleDebugDisplay() + { + debugDisplay = !debugDisplay; + reBuildCommandBuffers(); + } }; VulkanExample *vulkanExample;