void vkeGameRendererDynamic::initTerrainCommand(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = dc->getDefaultQueue(); uint32_t cmdID = 1021; VkResult rslt; for (uint32_t i = 0; i < 2; ++i){ if (m_terrain_command[i] != VK_NULL_HANDLE){ vkFreeCommandBuffers(device->getVKDevice(), queue->getCommandPool(), 1, &m_terrain_command[i]); m_terrain_command[i] = VK_NULL_HANDLE; } { VkCommandBufferAllocateInfo cmdBufInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmdBufInfo.commandBufferCount = 1; cmdBufInfo.commandPool = queue->getCommandPool(); cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; rslt = vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, &m_terrain_command[i]); VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; rslt = vkBeginCommandBuffer(m_terrain_command[i], &cmdBeginInfo); vkCmdBindPipeline(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_quad_pipeline); vkCmdBindDescriptorSets(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_quad_pipeline_layout, 0, 1, &m_quad_descriptor_set, 0, NULL); m_screen_quad.bind(&m_terrain_command[i]); m_screen_quad.draw(&m_terrain_command[i]); vkCmdBindPipeline(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_terrain_pipeline); vkCmdBindDescriptorSets(m_terrain_command[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_terrain_pipeline_layout, 0, 1, &m_terrain_descriptor_set, 0, NULL); m_terrain_quad.bind(&m_terrain_command[i]); m_terrain_quad.draw(&m_terrain_command[i]);/**/ vkEndCommandBuffer(m_terrain_command[i]); } } }
void VkeDrawCall::initCommandPool(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VkCommandPoolCreateInfo cmdPoolInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; cmdPoolInfo.queueFamilyIndex = 0; cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VKA_CHECK_ERROR(vkCreateCommandPool(device->getVKDevice(), &cmdPoolInfo, NULL, &m_command_pool), "Could not create command pool.\n"); VkCommandBufferAllocateInfo cmdBufInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmdBufInfo.commandBufferCount = 2; cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; cmdBufInfo.commandPool = m_command_pool; VKA_CHECK_ERROR(vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, m_draw_command), "Could not allocate secondary command buffers.\n"); }
void VkeDrawCall::initDescriptor(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VkWriteDescriptorSet writes[1]; vkResetDescriptorPool(device->getVKDevice(), m_descriptor_pool, 0); VkDescriptorSetAllocateInfo descAlloc = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; descAlloc.descriptorPool = m_descriptor_pool; descAlloc.pSetLayouts = (m_renderer->getTransformDescriptorLayout()); descAlloc.descriptorSetCount = 1; VKA_CHECK_ERROR(vkAllocateDescriptorSets(device->getVKDevice(), &descAlloc, &m_transform_descriptor_set), "Could not allocate descriptor sets.\n"); descriptorSetWrite(&writes[0], 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, (m_renderer->getTransformsDescriptor()), VK_NULL_HANDLE, 0, m_transform_descriptor_set);//transform vkUpdateDescriptorSets(device->getVKDevice(), 1, writes, 0, NULL); }
void VkeDrawCall::initDescriptorPool(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VkDescriptorPoolSize poolSize = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1 }; VkDescriptorPoolCreateInfo poolInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; poolInfo.maxSets = 1; poolInfo.poolSizeCount = 1; poolInfo.pPoolSizes = &poolSize; poolInfo.flags = 0; VKA_CHECK_ERROR(vkCreateDescriptorPool(device->getVKDevice(), &poolInfo, NULL, &m_descriptor_pool), "Could not create descriptor pool.\n"); }
void vkeGameRendererDynamic::initDescriptorPool(){ VkeRenderer::initDescriptorPool(); VkDescriptorPoolSize typeCounts[] = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1 }, { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 2 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 } }; VulkanDC *dc = VulkanDC::Get(); if (!dc) return; VulkanDC::Device *device = dc->getDefaultDevice(); VkDescriptorPoolCreateInfo descriptorPoolInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; descriptorPoolInfo.poolSizeCount = 3; descriptorPoolInfo.pPoolSizes = typeCounts; descriptorPoolInfo.maxSets = (m_descriptor_pool_size * 2) + 3; VKA_CHECK_ERROR(vkCreateDescriptorPool(device->getVKDevice(), &descriptorPoolInfo, NULL, &m_descriptor_pool), "Could not create descriptor pool.\n"); }
void vkeGameRendererDynamic::releaseFramebuffer(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); device->waitIdle(); vkDestroyImageView(device->getVKDevice(), m_depth_attachment.view, NULL); vkDestroyImageView(device->getVKDevice(), m_color_attachment.view, NULL); vkDestroyImageView(device->getVKDevice(), m_resolve_attachment[0].view, NULL); vkDestroyImageView(device->getVKDevice(), m_resolve_attachment[1].view, NULL); m_depth_attachment.view = NULL; m_color_attachment.view = NULL; m_resolve_attachment[0].view = NULL; m_resolve_attachment[1].view = NULL; vkDestroyImage(device->getVKDevice(), m_depth_attachment.image, NULL); vkDestroyImage(device->getVKDevice(), m_color_attachment.image, NULL); vkDestroyImage(device->getVKDevice(), m_resolve_attachment[0].image, NULL); vkDestroyImage(device->getVKDevice(), m_resolve_attachment[1].image, NULL); m_depth_attachment.image = NULL; m_color_attachment.image = NULL; m_resolve_attachment[0].image = NULL; m_resolve_attachment[1].image = NULL; vkFreeMemory(device->getVKDevice(), m_depth_attachment.memory, NULL); vkFreeMemory(device->getVKDevice(), m_color_attachment.memory, NULL); vkFreeMemory(device->getVKDevice(), m_resolve_attachment[0].memory, NULL); vkFreeMemory(device->getVKDevice(), m_resolve_attachment[1].memory, NULL); m_depth_attachment.memory = NULL; m_color_attachment.memory = NULL; m_resolve_attachment[0].memory = NULL; m_resolve_attachment[1].memory = NULL; vkDestroyFramebuffer(device->getVKDevice(), m_framebuffers[0], NULL); vkDestroyFramebuffer(device->getVKDevice(), m_framebuffers[1], NULL); m_framebuffers[0] = NULL; m_framebuffers[1] = NULL; }
void VkeCubeTexture::loadCubeDDS(const char *inFile){ std::string searchPaths[] = { std::string(PROJECT_NAME), NVPWindow::sysExePath() + std::string(PROJECT_RELDIRECTORY), std::string(PROJECT_ABSDIRECTORY) }; nv_dds::CDDSImage ddsImage; for (uint32_t i = 0; i < 3; ++i){ std::string separator = ""; uint32_t strSize = searchPaths[i].size(); if(searchPaths[i].substr(strSize-1,strSize) != "/") separator = "/"; std::string filePath = searchPaths[i] + separator + std::string("images/") + std::string(inFile); ddsImage.load(filePath, true); if (ddsImage.is_valid()) break; } if (!ddsImage.is_valid()){ perror("Could not cube load texture image.\n"); exit(1); } uint32_t imgW = ddsImage.get_width(); uint32_t imgH = ddsImage.get_height(); uint32_t comCount = ddsImage.get_components(); uint32_t fmt = ddsImage.get_format(); bool isCube = ddsImage.is_cubemap(); bool isComp = ddsImage.is_compressed(); VkFormat vkFmt = VK_FORMAT_R8G8B8A8_UNORM; switch (fmt){ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: vkFmt = VK_FORMAT_BC1_RGB_SRGB_BLOCK; break; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: vkFmt = VK_FORMAT_BC2_UNORM_BLOCK; break; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: vkFmt = VK_FORMAT_BC3_UNORM_BLOCK; break; default: break; } m_width = imgW; m_height = imgH; m_format = vkFmt; VulkanDC::Device::Queue::Name queueName = "DEFAULT_GRAPHICS_QUEUE"; VulkanDC::Device::Queue::CommandBufferID cmdID = INIT_COMMAND_ID; VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = device->getQueue(queueName); VkCommandBuffer cmd = VK_NULL_HANDLE; queue->beginCommandBuffer(cmdID, &cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); imageCreateAndBind( &m_data.image, &m_data.memory, m_format, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 6, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, (VkImageUsageFlagBits)(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), VK_IMAGE_TILING_OPTIMAL); VkBuffer cubeMapBuffer; VkDeviceMemory cubeMapMem; bufferCreate(&cubeMapBuffer, m_width*m_height * 3 * 6, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); bufferAlloc(&cubeMapBuffer, &cubeMapMem, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); if (m_memory_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT){ imageSetLayoutBarrier(cmdID, queueName, m_data.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_GENERAL); for (uint32_t i = 0; i < 6; ++i){ void *data = NULL; VkSubresourceLayout layout; VkImageSubresource subres; subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subres.mipLevel = m_mip_level; subres.arrayLayer = i; vkGetImageSubresourceLayout(getDefaultDevice(), m_data.image, &subres, &layout); VKA_CHECK_ERROR(vkMapMemory(getDefaultDevice(), cubeMapMem, layout.offset, layout.size, 0, &data), "Could not map memory for image.\n"); const nv_dds::CTexture &mipmap = ddsImage.get_cubemap_face(i); memcpy(data, (void *)mipmap, layout.size); vkUnmapMemory(getDefaultDevice(), cubeMapMem); } VkBufferImageCopy biCpyRgn[6]; for (uint32_t k = 0; k < 6; ++k){ VkSubresourceLayout layout; VkImageSubresource subres; subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subres.mipLevel = m_mip_level; subres.arrayLayer = k; vkGetImageSubresourceLayout(getDefaultDevice(), m_data.image, &subres, &layout); biCpyRgn[k].bufferOffset = layout.offset; biCpyRgn[k].bufferImageHeight = 0; biCpyRgn[k].bufferRowLength = 0; biCpyRgn[k].imageExtent.width = m_width; biCpyRgn[k].imageExtent.height = m_height; biCpyRgn[k].imageExtent.depth = 1; biCpyRgn[k].imageOffset.x = 0; biCpyRgn[k].imageOffset.y = 0; biCpyRgn[k].imageOffset.z = 0; biCpyRgn[k].imageSubresource.baseArrayLayer = k; biCpyRgn[k].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; biCpyRgn[k].imageSubresource.layerCount = 1; biCpyRgn[k].imageSubresource.mipLevel = 0; } VkFence copyFence; VkFenceCreateInfo fenceInfo; memset(&fenceInfo, 0, sizeof(fenceInfo)); fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; vkCreateFence(device->getVKDevice(), &fenceInfo, NULL, ©Fence); vkCmdCopyBufferToImage(cmd, cubeMapBuffer, m_data.image, m_data.imageLayout, 6, biCpyRgn); queue->flushCommandBuffer(cmdID, ©Fence); vkWaitForFences(device->getVKDevice(), 1, ©Fence, VK_TRUE, 100000000000); vkDestroyBuffer(device->getVKDevice(), cubeMapBuffer, NULL); vkFreeMemory(device->getVKDevice(), cubeMapMem, NULL); } VkSamplerCreateInfo sampler; sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler.pNext = NULL; sampler.magFilter = VK_FILTER_NEAREST; sampler.minFilter = VK_FILTER_NEAREST; sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.mipLodBias = 0.0f; sampler.maxAnisotropy = 1; sampler.compareOp = VK_COMPARE_OP_NEVER; sampler.minLod = 0.0f; sampler.maxLod = 0.0f; sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; VkImageViewCreateInfo view; view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view.pNext = NULL; view.viewType = VK_IMAGE_VIEW_TYPE_CUBE; view.format = m_format; view.components.r = VK_COMPONENT_SWIZZLE_R; view.components.g = VK_COMPONENT_SWIZZLE_G; view.components.b = VK_COMPONENT_SWIZZLE_B; view.components.a = VK_COMPONENT_SWIZZLE_A; view.subresourceRange.baseArrayLayer = 0; view.subresourceRange.levelCount = 1; view.subresourceRange.baseMipLevel = 0; view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view.subresourceRange.layerCount = 1; VKA_CHECK_ERROR(vkCreateSampler(getDefaultDevice(), &sampler, NULL, &m_data.sampler), "Could not create sampler for image texture.\n"); view.image = m_data.image; VKA_CHECK_ERROR(vkCreateImageView(getDefaultDevice(), &view, NULL, &m_data.view), "Could not create image view for texture.\n"); }
void VkeCubeTexture::loadTextureFiles(const char **inPath){ bool imagesOK = true; VKA_INFO_MSG("Loading Cube Texture.\n"); for (uint32_t i = 0; i < 6; ++i){ if (!loadTexture(inPath[i], NULL, NULL, &m_width, &m_height)){ VKA_ERROR_MSG("Error loading texture image.\n"); printf("Texture : %d not available (%s).\n", i, inPath[i]); return; } } VulkanDC::Device::Queue::Name queueName = "DEFAULT_GRAPHICS_QUEUE"; VulkanDC::Device::Queue::CommandBufferID cmdID = INIT_COMMAND_ID; VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = device->getQueue(queueName); VkCommandBuffer cmd = VK_NULL_HANDLE; queue->beginCommandBuffer(cmdID, &cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); imageCreateAndBind( &m_data.image, &m_data.memory, m_format, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 6, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, (VkImageUsageFlagBits)( VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT ), VK_IMAGE_TILING_OPTIMAL); VkBuffer cubeMapBuffer; VkDeviceMemory cubeMapMem; bufferCreate(&cubeMapBuffer, m_width*m_height * 4 * 6, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); bufferAlloc(&cubeMapBuffer, &cubeMapMem, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); VkDeviceSize dSize = m_width * m_height * 4; uint32_t rowPitch = m_width * 4; if (m_memory_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT){ imageSetLayoutBarrier(cmdID, queueName, m_data.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_GENERAL); for (uint32_t i = 0; i < 6; ++i){ void *data = NULL; VkDeviceSize ofst = dSize*i; VKA_CHECK_ERROR(vkMapMemory(getDefaultDevice(),cubeMapMem, ofst, dSize, 0, &data), "Could not map memory for image.\n"); if (!loadTexture(inPath[i], (uint8_t**)&data, rowPitch, &m_width, &m_height)){ VKA_ERROR_MSG("Could not load final image.\n"); } vkUnmapMemory(getDefaultDevice(), cubeMapMem); } VkBufferImageCopy biCpyRgn[6]; for (uint32_t k = 0; k < 6; ++k){ VkDeviceSize ofst = dSize*k; biCpyRgn[k].bufferOffset = ofst; biCpyRgn[k].bufferImageHeight = 0; biCpyRgn[k].bufferRowLength = 0; biCpyRgn[k].imageExtent.width = m_width; biCpyRgn[k].imageExtent.height = m_height; biCpyRgn[k].imageExtent.depth = 1; biCpyRgn[k].imageOffset.x = 0; biCpyRgn[k].imageOffset.y = 0; biCpyRgn[k].imageOffset.z = 0; biCpyRgn[k].imageSubresource.baseArrayLayer = k; biCpyRgn[k].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; biCpyRgn[k].imageSubresource.layerCount = 1; biCpyRgn[k].imageSubresource.mipLevel = 0; } VkFence copyFence; VkFenceCreateInfo fenceInfo; memset(&fenceInfo, 0, sizeof(fenceInfo)); fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; vkCreateFence(device->getVKDevice(), &fenceInfo,NULL , ©Fence); vkCmdCopyBufferToImage(cmd, cubeMapBuffer, m_data.image, m_data.imageLayout, 6, biCpyRgn); queue->flushCommandBuffer(cmdID , ©Fence); vkWaitForFences(device->getVKDevice(), 1, ©Fence, VK_TRUE, 100000000000); vkDestroyBuffer(device->getVKDevice(), cubeMapBuffer, NULL); vkFreeMemory(device->getVKDevice(), cubeMapMem, NULL); } VkSamplerCreateInfo sampler; sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler.pNext = NULL; sampler.magFilter = VK_FILTER_NEAREST; sampler.minFilter = VK_FILTER_NEAREST; sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.mipLodBias = 0.0f; sampler.maxAnisotropy = 1; sampler.compareOp = VK_COMPARE_OP_NEVER; sampler.minLod = 0.0f; sampler.maxLod = 0.0f; sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; VkImageViewCreateInfo view; view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view.pNext = NULL; view.viewType = VK_IMAGE_VIEW_TYPE_CUBE; view.format = m_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, 0 }; view.subresourceRange.baseArrayLayer = 0; view.subresourceRange.levelCount = 1; view.subresourceRange.baseMipLevel = 0; view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view.subresourceRange.layerCount = 1; VKA_CHECK_ERROR(vkCreateSampler(getDefaultDevice(), &sampler,NULL, &m_data.sampler), "Could not create sampler for image texture.\n"); view.image = m_data.image; VKA_CHECK_ERROR(vkCreateImageView(getDefaultDevice(), &view,NULL, &m_data.view), "Could not create image view for texture.\n"); VKA_INFO_MSG("Created CUBE Image Texture.\n"); }
void vkeGameRendererDynamic::initPipeline(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VkPipelineCacheCreateInfo pipelineCache = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; VkPipelineVertexInputStateCreateInfo vertexState; VkPipelineInputAssemblyStateCreateInfo inputState; VkPipelineRasterizationStateCreateInfo rasterState; VkPipelineColorBlendStateCreateInfo blendState; VkPipelineDepthStencilStateCreateInfo depthState; VkPipelineViewportStateCreateInfo viewportState; VkPipelineMultisampleStateCreateInfo multisampleState; VkVertexInputBindingDescription binding; VkVertexInputAttributeDescription attrs[3]; /*---------------------------------------------------------- Create the pipeline cache. ----------------------------------------------------------*/ VKA_CHECK_ERROR(vkCreatePipelineCache(device->getVKDevice(), &pipelineCache, NULL, &m_pipeline_cache), "Couldn not create pipeline cache.\n"); /*---------------------------------------------------------- Create the scene pipeline. ----------------------------------------------------------*/ /* Create the vertex input state. Binding at location 0. 3 attributes: 1 : Vertex Position : vec4 2 : Vertex Normal : vec4 3 : UV : vec2 */ vertexBinding(&binding, 0, sizeof(VertexObject), VK_VERTEX_INPUT_RATE_VERTEX); vertexAttributef(&attrs[0], 0, binding.binding, VK_FORMAT_R32G32B32A32_SFLOAT, 0); vertexAttributef(&attrs[1], 1, binding.binding, VK_FORMAT_R32G32B32A32_SFLOAT, 4); vertexStateInfo(&vertexState, 1, 2, &binding, attrs); /* Create the input assembly state Topology: Triangle List Primitive restart enable : false */ inputAssemblyStateInfo(&inputState, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE); /* Create the raster state */ rasterStateInfo(&rasterState, VK_POLYGON_MODE_FILL); /* Create the color blend state. */ VkPipelineColorBlendAttachmentState attState[3]; uint32_t sampleMask = 0xFF; blendAttachmentStateN(3, attState); blendStateInfo(&blendState, 3, attState); /* Create the viewport state */ viewportStateInfo(&viewportState, 1); /* Create the depth stencil state */ depthStateInfo(&depthState); /* Create the multisample state */ multisampleStateInfo(&multisampleState, getSamples(), &sampleMask); /* Create the pipeline shaders. */ VkPipelineShaderStageCreateInfo shaderStages[4]; createShaderStage(&shaderStages[0], VK_SHADER_STAGE_VERTEX_BIT, m_shaders.scene_vertex); createShaderStage(&shaderStages[1], VK_SHADER_STAGE_FRAGMENT_BIT, m_shaders.scene_fragment); /* Create the graphics pipeline. */ graphicsPipelineCreate(&m_pipeline, &m_pipeline_cache, m_pipeline_layout, 2, shaderStages, &vertexState, &inputState, &rasterState, &blendState, &multisampleState, &viewportState, &depthState, &m_render_pass, 0, VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT); /*---------------------------------------------------------- Create the skybox pipeline. ----------------------------------------------------------*/ /* Reusing the create info struct from the scene pipeline, just update what we need. */ vertexBinding(&binding, 0, sizeof(VertexObjectUV), VK_VERTEX_INPUT_RATE_VERTEX); vertexAttributef(&attrs[0], 0, binding.binding, VK_FORMAT_R32G32B32A32_SFLOAT, 0); vertexAttributef(&attrs[1], 1, binding.binding, VK_FORMAT_R32G32_SFLOAT, 4); vertexStateInfo(&vertexState, 1, 2, &binding, attrs); depthStateInfo(&depthState, VK_FALSE); /* Create the pipeline shaders. */ createShaderStage(&shaderStages[0], VK_SHADER_STAGE_VERTEX_BIT, m_shaders.quad_vertex); createShaderStage(&shaderStages[1], VK_SHADER_STAGE_FRAGMENT_BIT, m_shaders.quad_fragment); /* create the graphics pipeline. */ graphicsPipelineCreate(&m_quad_pipeline, &m_pipeline_cache, m_quad_pipeline_layout, 2, shaderStages, &vertexState, &inputState, &rasterState, &blendState, &multisampleState, &viewportState, &depthState, &m_render_pass, 0, VK_PIPELINE_CREATE_DERIVATIVE_BIT); /*---------------------------------------------------------- Create the terrain pipeline. ----------------------------------------------------------*/ /* Reusing the create info struct from the scene pipeline, just update what we need. */ inputAssemblyStateInfo(&inputState, VK_PRIMITIVE_TOPOLOGY_PATCH_LIST); depthStateInfo(&depthState); rasterStateInfo(&rasterState, VK_POLYGON_MODE_FILL); /* create the graphics pipeline. */ createShaderStage(&shaderStages[0], VK_SHADER_STAGE_VERTEX_BIT, m_shaders.terrain_vertex); createShaderStage(&shaderStages[1], VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_shaders.terrain_tcs); createShaderStage(&shaderStages[2], VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_shaders.terrain_tes); createShaderStage(&shaderStages[3], VK_SHADER_STAGE_FRAGMENT_BIT, m_shaders.terrain_fragment); /* create the graphics pipeline. */ graphicsPipelineCreate(&m_terrain_pipeline, &m_pipeline_cache, m_terrain_pipeline_layout, 4, shaderStages, &vertexState, &inputState, &rasterState, &blendState, &multisampleState, &viewportState, &depthState, &m_render_pass, 0, VK_PIPELINE_CREATE_DERIVATIVE_BIT); }
void vkeGameRendererDynamic::initDescriptorSets(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); uint32_t count = 1; if (!dc) return; initCamera(); vkResetDescriptorPool(device->getVKDevice(), getDescriptorPool(), 0); VkWriteDescriptorSet writes[5]; /*---------------------------------------------------------- Get the resource data for the bindings. ----------------------------------------------------------*/ /* Terrain textures. */ VkeTexture::Data terrain = m_textures.getTexture(0)->getData(); /* Camera and Light uniforms */ VkDescriptorBufferInfo camInfo = m_camera->getDescriptor(); VkDescriptorBufferInfo lightInfo = m_light->getDescriptor(); /* Cube map texture. */ VkeCubeTexture::Data cube = m_cube_textures.getTexture(1)->getData(); /* Create descriptor image info array for the terrain textures. */ VkDescriptorImageInfo fpSampler = { terrain.sampler, terrain.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; VkeMaterial *material = m_materials->getMaterial(0); /* Create descriptor image info array for the scene textures. */ uint32_t texCount = m_materials->count(); VkDescriptorImageInfo *texImageInfo = (VkDescriptorImageInfo*)malloc(texCount * sizeof(VkDescriptorImageInfo)); for (uint32_t i = 0; i < texCount; ++i){ VkeMaterial *mtrl = m_materials->getMaterial(i); VkeTexture::Data texData = mtrl->getTextures().getTexture(0)->getData(); texImageInfo[i].imageView = texData.view; texImageInfo[i].sampler = texData.sampler; } /* Create descriptor image info for the cube map texture. */ VkDescriptorImageInfo cubeTexture; cubeTexture.sampler = cube.sampler; cubeTexture.imageView = cube.view; cubeTexture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; /* Capture the layouts for the scene descriptor sets and the texture descriptor sets. */ VkDescriptorSetLayout *textureLayouts = (VkDescriptorSetLayout*)malloc(sizeof(VkDescriptorSetLayout) * texCount); for (uint32_t i = 0; i < texCount; ++i){ textureLayouts[i] = m_texture_descriptor_set_layout; } /* Allocate storage for the scene and texture descriptor sets. */ /*---------------------------------------------------------- Allocate the descriptor sets. ----------------------------------------------------------*/ m_texture_descriptor_sets = (VkDescriptorSet*)malloc(sizeof(VkDescriptorSet)); /* Set up the alocate info structure for the descriptor sets. */ VkDescriptorSetAllocateInfo descAlloc; memset(&descAlloc, 0, sizeof(descAlloc)); descAlloc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; descAlloc.descriptorPool = getDescriptorPool(); descAlloc.pSetLayouts = &m_scene_descriptor_layout; descAlloc.descriptorSetCount = 1; VKA_CHECK_ERROR(vkAllocateDescriptorSets(device->getVKDevice(), &descAlloc, &m_scene_descriptor_set), "Could not allocate descriptor sets.\n"); /* Set up the texture descriptor sets. */ descAlloc.pSetLayouts = &m_texture_descriptor_set_layout; descAlloc.descriptorSetCount = 1; VKA_CHECK_ERROR(vkAllocateDescriptorSets(device->getVKDevice(), &descAlloc, m_texture_descriptor_sets), "Could not allocate texture descriptor sets.\n"); /* Set up the skybox descriptor sets. */ descAlloc.pSetLayouts = &m_quad_descriptor_set_layout; descAlloc.descriptorSetCount = 1; VKA_CHECK_ERROR(vkAllocateDescriptorSets(device->getVKDevice(), &descAlloc, &m_quad_descriptor_set), "Could not allocate descriptor sets.\n"); /* Set up the terrian descriptor sets. */ descAlloc.pSetLayouts = &m_terrain_descriptor_set_layout; descAlloc.descriptorSetCount = 1; VKA_CHECK_ERROR(vkAllocateDescriptorSets(device->getVKDevice(), &descAlloc, &m_terrain_descriptor_set), "Could not allocate descriptor sets.\n"); /* Set up the transforms descriptor sets. */ descAlloc.pSetLayouts = &m_transform_descriptor_layout; descAlloc.descriptorSetCount = 1; VKA_CHECK_ERROR(vkAllocateDescriptorSets(device->getVKDevice(), &descAlloc, &m_transform_descriptor_set), "Could not allocate descriptor sets.\n"); /*---------------------------------------------------------- Update the descriptor sets with resource bindings. ----------------------------------------------------------*/ /* Scene layout bindings (set 0) Binding 0: Environment Cube Map Binding 1: Camera Matrix Binding 2: Model Matrix Binding 3: Material */ descriptorSetWrite(&writes[0], 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_NULL_HANDLE, &cubeTexture, 0, m_scene_descriptor_set);//cubemap descriptorSetWrite(&writes[1], 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &camInfo, VK_NULL_HANDLE, 0, m_scene_descriptor_set); //Camera descriptorSetWrite(&writes[2], 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &m_uniforms_descriptor, VK_NULL_HANDLE, 0, m_scene_descriptor_set);//modelview descriptorSetWrite(&writes[3], 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &material->getDescriptor(), VK_NULL_HANDLE, 0, m_scene_descriptor_set);//material vkUpdateDescriptorSets(device->getVKDevice(), 4, writes, 0, NULL); /* Transform layout bindings (set 0) Binding 0: Transform */ descriptorSetWrite(&writes[0], 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &m_transforms_descriptor, VK_NULL_HANDLE, 0, m_transform_descriptor_set);//transform vkUpdateDescriptorSets(device->getVKDevice(), 1, writes, 0, NULL); /* Scene layout bindings (set 1) Binding 0: Scene texture array */ descriptorSetWrite(&writes[0], 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, texCount, VK_NULL_HANDLE, texImageInfo, 0, m_texture_descriptor_sets[0]);//cubemap vkUpdateDescriptorSets(device->getVKDevice(), (uint32_t)1, writes, 0, NULL); //Free the texture image info allocated earlier. free(texImageInfo); /* Skybox layout bindings (set 0) Binding 0: Skybox Uniforms Binding 1: Skybox Textures Binding 2: Camera uniforms */ descriptorSetWrite(&writes[0], 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &m_screen_quad.getData().descriptor, VK_NULL_HANDLE, 0, m_quad_descriptor_set); descriptorSetWrite(&writes[1], 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_NULL_HANDLE, &cubeTexture, 0, m_quad_descriptor_set); descriptorSetWrite(&writes[2], 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &camInfo, VK_NULL_HANDLE, 0, m_quad_descriptor_set); vkUpdateDescriptorSets(device->getVKDevice(), 3, writes, 0, NULL); /* Terrain layout bindings (set 0) Binding 0: Terrain Uniforms Binding 1: Camera Uniforms Binding 2: Terrain texture array */ descriptorSetWrite(&writes[0], 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &m_terrain_quad.getData().descriptor, VK_NULL_HANDLE, 0, m_terrain_descriptor_set); descriptorSetWrite(&writes[1], 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &camInfo, VK_NULL_HANDLE, 0, m_terrain_descriptor_set); descriptorSetWrite(&writes[2], 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_NULL_HANDLE, &fpSampler, 0, m_terrain_descriptor_set); descriptorSetWrite(&writes[3], 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_NULL_HANDLE, &cubeTexture, 0, m_terrain_descriptor_set); vkUpdateDescriptorSets(device->getVKDevice(), 4, writes, 0, NULL); /*---------------------------------------------------------- Initialise the terrain and scene command buffers. ----------------------------------------------------------*/ initTerrainCommand(); for (uint32_t i = 0; i < m_max_draw_calls; ++i){ m_draw_calls[i]->initDescriptor(); } //m_test_drawcall->initDrawCommands(m_node_data->count()); //this needs to happen in the thread. //m_draw_calls[0]->initDrawCommands(m_node_data->count()); }
void vkeGameRendererDynamic::update(){ VulkanAppContext *ctxt = VulkanAppContext::GetInstance(); VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VkCommandBuffer cmd = VK_NULL_HANDLE; VulkanDC::Device::Queue::CommandBufferID cmdID = INIT_COMMAND_ID + 300; static float sTime = 0.0f; static uint32_t *uniforms = NULL; uint32_t cnt = m_node_data->count(); uint32_t sz = (sizeof(VkeNodeUniform) * cnt) + (m_instance_count * 64); static bool ismapped(false); nv_math::mat4f tempMatrix; const float r2d = 180 / (3.14159265359); static float xTheta(0.0f); for (uint32_t i = 0; i < m_instance_count; ++i){ size_t pointerOffset = (sizeof(VkeNodeUniform) * cnt) + (64 * i); nv_math::mat4f *matPtr = (nv_math::mat4f*)(((uint8_t*)m_uniforms_local) + pointerOffset); m_flight_paths[i]->update(matPtr, sTime); } m_node_data->update((VkeNodeUniform*)m_uniforms_local, m_instance_count); m_camera->setViewport(0, 0, (float)m_width, (float)m_height); m_camera->update(); generateDrawCommands(); if (!m_is_first_frame){ vkResetFences(device->getVKDevice(), 1, &m_update_fence[m_current_buffer_index]); const VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo subInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; subInfo.commandBufferCount = 1; subInfo.waitSemaphoreCount = 1; subInfo.pWaitSemaphores = &m_present_done[m_current_buffer_index]; subInfo.pWaitDstStageMask = &waitStages; subInfo.signalSemaphoreCount = 1; subInfo.pSignalSemaphores = &m_render_done[m_current_buffer_index]; subInfo.pCommandBuffers = &m_primary_commands[m_current_buffer_index]; vkQueueSubmit(dc->getDefaultQueue()->getVKQueue(), 1, &subInfo, m_update_fence[m_current_buffer_index]); /* Synchronise the next buffer. This prevents the buffer from being reset when still in use when we have more than 2 frames in flight. */ uint32_t nextBufferIndex = (m_current_buffer_index + 1) % 2; present(); vkWaitForFences(device->getVKDevice(), 1, &m_update_fence[nextBufferIndex], VK_TRUE, 1000000); } else{ m_is_first_frame = false; } m_current_buffer_index++; m_current_buffer_index %= 2; sTime += 0.16; }
void vkeGameRendererDynamic::initRenderer(){ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDevice(); m_instance_count = 128; glWaitVkSemaphoreNV = (PFNGLWAITVKSEMAPHORENVPROC)NVPWindow::sysGetProcAddress("glWaitVkSemaphoreNV"); glSignalVkSemaphoreNV = (PFNGLSIGNALVKSEMAPHORENVPROC)NVPWindow::sysGetProcAddress("glSignalVkSemaphoreNV"); glSignalVkFenceNV = (PFNGLSIGNALVKFENCENVPROC)NVPWindow::sysGetProcAddress("glSignalVkFenceNV"); glDrawVkImageNV = (PFNGLDRAWVKIMAGENVPROC)NVPWindow::sysGetProcAddress("glDrawVkImageNV"); VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; VkFenceCreateInfo fenceInfo = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO}; VKA_CHECK_ERROR(vkCreateSemaphore(device->getVKDevice(), &semInfo, NULL, &m_present_done[0]), "Could not create present done semaphore.\n"); VKA_CHECK_ERROR(vkCreateSemaphore(device->getVKDevice(), &semInfo, NULL, &m_render_done[0]), "Could not create render done semaphore.\n"); VKA_CHECK_ERROR(vkCreateSemaphore(device->getVKDevice(), &semInfo, NULL, &m_present_done[1]), "Could not create present done semaphore.\n"); VKA_CHECK_ERROR(vkCreateSemaphore(device->getVKDevice(), &semInfo, NULL, &m_render_done[1]), "Could not create render done semaphore.\n"); VKA_CHECK_ERROR(vkCreateFence(device->getVKDevice(), &fenceInfo, NULL, &m_update_fence[0]), "Could not create update fence.\n"); fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; VKA_CHECK_ERROR(vkCreateFence(device->getVKDevice(), &fenceInfo, NULL, &m_update_fence[1]), "Could not create update fence.\n"); m_terrain_command[0] = VK_NULL_HANDLE; m_terrain_command[1] = VK_NULL_HANDLE; m_framebuffers[0] = VK_NULL_HANDLE; m_framebuffers[1] = VK_NULL_HANDLE; m_update_commands[0] = VK_NULL_HANDLE; m_update_commands[1] = VK_NULL_HANDLE; m_is_first_frame = true; nv_math::vec3f table[128][128]; for (int v = 0; v < 128; ++v){ for (int u = 0; u < 128; ++u){ nv_math::vec2f vctr(quickRandomUVD(), quickRandomUVD()); vctr = nv_math::normalize(vctr); table[u][v] = nv_math::vec3f(vctr.x, vctr.y, vctr.x); } } m_cube_textures.newTexture(1)->loadCubeDDS("environ.dds"); m_screen_quad.initQuadData(); m_terrain_quad.initQuadData(); m_textures.newTexture(0)->setFormat(VK_FORMAT_R32G32B32_SFLOAT); m_textures.getTexture(0)->loadTextureFloatData((float *)&(table[0][0].x), 128, 128, 3); m_flight_paths = (FlightPath**)malloc(sizeof(FlightPath*) * m_instance_count); for (uint32_t i = 0; i < m_instance_count; ++i){ nv_math::vec2f initPos(quickRandomUVD()*100.0, -200 + (quickRandomUVD() * 20)); nv_math::vec2f endPos(quickRandomUVD()*100.0, 200 + (quickRandomUVD() * 20)); m_flight_paths[i] = new FlightPath(initPos, endPos, quickRandomUVD() * 0.5 + 0.5, quickRandomUVD() * 4 + 10); } /* Just initialises the draw call objects not the threads. They store thread local data for the threaded cmd buffer builds. */ initDrawCalls(); /* Create primary command pool for the */ VkCommandPoolCreateInfo cmdPoolInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; cmdPoolInfo.queueFamilyIndex = 0; cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VKA_CHECK_ERROR(vkCreateCommandPool(device->getVKDevice(), &cmdPoolInfo, NULL, &m_primary_buffer_cmd_pool), "Could not create primary command pool.\n"); m_primary_commands[0] = VK_NULL_HANDLE; m_primary_commands[1] = VK_NULL_HANDLE; VkCommandBufferAllocateInfo cmdBufInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmdBufInfo.commandBufferCount = 2; cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; cmdBufInfo.commandPool = m_primary_buffer_cmd_pool; VKA_CHECK_ERROR(vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, m_primary_commands), "Could not allocate primary command buffers.\n"); VKA_CHECK_ERROR(vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, m_update_commands), "Could not allocate primary command buffers.\n"); m_current_buffer_index = 0; }
void vkeGameRendererDynamic::initIndirectCommands(){ if (!m_node_data) return; VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = dc->getDefaultQueue(); uint32_t cnt = m_node_data->count(); uint32_t sz = sizeof(VkDrawIndexedIndirectCommand)*cnt; VkBuffer sceneIndirectStaging; VkDeviceMemory sceneIndirectMemStaging; VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; bufferCreate(&m_scene_indirect_buffer, sz, (VkBufferUsageFlagBits)usageFlags); bufferAlloc(&m_scene_indirect_buffer, &m_scene_indirect_memory, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; bufferCreate(&sceneIndirectStaging, sz, (VkBufferUsageFlagBits)usageFlags); bufferAlloc(&sceneIndirectStaging, &sceneIndirectMemStaging, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); VkDrawIndexedIndirectCommand *commands = NULL; VKA_CHECK_ERROR(vkMapMemory(device->getVKDevice(), sceneIndirectMemStaging, 0, sz, 0, (void **)&commands), "Could not map indirect buffer memory.\n"); for (uint32_t i = 0; i < cnt; ++i){ VkeMesh *mesh = m_node_data->getData(i)->getMesh(); commands[i].firstIndex = mesh->getFirstIndex(); commands[i].firstInstance = i*m_instance_count; commands[i].vertexOffset = mesh->getFirstVertex(); commands[i].indexCount = mesh->getIndexCount(); commands[i].instanceCount = m_instance_count; } vkUnmapMemory(device->getVKDevice(), sceneIndirectMemStaging); VkBufferCopy bufCpy; bufCpy.dstOffset = 0; bufCpy.srcOffset = 0; bufCpy.size = sz; VkCommandBuffer copyCmd; VkCommandBufferAllocateInfo cmdBufInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmdBufInfo.commandBufferCount = 1; cmdBufInfo.commandPool = queue->getCommandPool(); cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; VKA_CHECK_ERROR(vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, ©Cmd), "Could not allocate command buffers.\n"); VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; VKA_CHECK_ERROR(vkBeginCommandBuffer(copyCmd, &cmdBeginInfo), "Could not begin commmand buffer.\n"); vkCmdCopyBuffer(copyCmd, sceneIndirectStaging, m_scene_indirect_buffer, 1, &bufCpy); VKA_CHECK_ERROR(vkEndCommandBuffer(copyCmd), "Could not end command buffer.\n"); VkSubmitInfo subInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; subInfo.commandBufferCount = 1; subInfo.pCommandBuffers = ©Cmd; VkFence theFence; VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; VKA_CHECK_ERROR(vkCreateFence(device->getVKDevice(), &fenceInfo, NULL, &theFence), "Could not create fence.\n"); VKA_CHECK_ERROR(vkQueueSubmit(queue->getVKQueue(), 1, &subInfo, theFence), "Could not submit queue for indirect buffer copy.\n"); VKA_CHECK_ERROR(vkWaitForFences(device->getVKDevice(), 1, &theFence, VK_TRUE, UINT_MAX), "Could not wait for fence.\n"); vkFreeCommandBuffers(device->getVKDevice(), queue->getCommandPool(), 1, ©Cmd); vkDestroyFence(device->getVKDevice(), theFence, NULL); }
void vkeGameRendererDynamic::initFramebuffer(uint32_t inWidth, uint32_t inHeight){ /*---------------------------------------------------------- Create the framebuffer ----------------------------------------------------------*/ VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = dc->getDefaultQueue(); const VkFormat depthFmt = VK_FORMAT_D24_UNORM_S8_UINT; const VkFormat colorFmt = VK_FORMAT_R8G8B8A8_UNORM; /* If framebuffers already exist, release them. */ if (m_framebuffers[0] != VK_NULL_HANDLE){ releaseFramebuffer(); } /* Update the frame dimensions. */ m_width = inWidth; m_height = inHeight; /* Specify usage for the frame buffer attachments. */ VkImageUsageFlagBits gBufferFlags = (VkImageUsageFlagBits)(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); VkImageUsageFlagBits sBufferFlags = (VkImageUsageFlagBits)(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); /* Create the depth attachment image and image view. */ m_depth_attachment.format = depthFmt; imageCreateAndBind(&m_depth_attachment.image, &m_depth_attachment.memory, depthFmt, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 1, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, getSamples()); imageViewCreate(&m_depth_attachment.view, m_depth_attachment.image, VK_IMAGE_VIEW_TYPE_2D, depthFmt); /* Create the color attachment image and image view. */ m_color_attachment.format = colorFmt; imageCreateAndBind(&m_color_attachment.image, &m_color_attachment.memory, colorFmt, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 1, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, gBufferFlags, VK_IMAGE_TILING_OPTIMAL, getSamples()); imageViewCreate(&m_color_attachment.view, m_color_attachment.image, VK_IMAGE_VIEW_TYPE_2D, colorFmt); /* Create the resolve attachment image and image view. */ for (uint32_t i = 0; i < 2; ++i){ m_resolve_attachment[i].format = colorFmt; imageCreateAndBind(&m_resolve_attachment[i].image, &m_resolve_attachment[i].memory, colorFmt, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 1, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, gBufferFlags, VK_IMAGE_TILING_OPTIMAL, VK_SAMPLE_COUNT_1_BIT); imageViewCreate(&m_resolve_attachment[i].view, m_resolve_attachment[i].image, VK_IMAGE_VIEW_TYPE_2D, colorFmt); } /* Put the image views into a temporary array to pass to the framebuffer create info struct. */ /* Setup the framebuffer create info struct. */ for (uint32_t i = 0; i < 2; ++i){ VkImageView views[] = { m_color_attachment.view, m_depth_attachment.view, m_resolve_attachment[i].view }; VkFramebufferCreateInfo fbInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; fbInfo.renderPass = m_render_pass; fbInfo.attachmentCount = 3; fbInfo.pAttachments = views; fbInfo.width = m_width; fbInfo.height = m_height; fbInfo.layers = 1; /* Create 2 framebuffers for ping pong. */ VKA_CHECK_ERROR(vkCreateFramebuffer(device->getVKDevice(), &fbInfo, NULL, &m_framebuffers[i]), "Could not create framebuffer.\n"); } }
void vkeGameRendererDynamic::update(){ VulkanAppContext *ctxt = VulkanAppContext::GetInstance(); VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VkCommandBuffer cmd = VK_NULL_HANDLE; VulkanDC::Device::Queue::CommandBufferID cmdID = INIT_COMMAND_ID + 300; static float sTime = 0.0f; static uint32_t *uniforms = NULL; uint32_t sz = (sizeof(VkeNodeUniform) * 100) + (64 * 64); static bool ismapped(false); nv_math::mat4f tempMatrix; const float r2d = 180 / (3.14159265359); static float xTheta(0.0f); //if (!ismapped){ VKA_CHECK_ERROR(vkMapMemory(getDefaultDevice(), m_uniforms_staging, 0, sz, 0, (void **)&uniforms), "Could not map buffer memory.\n"); //ismapped = true; //} for (uint32_t i = 0; i < 64; ++i){ size_t pointerOffset = (sizeof(VkeNodeUniform) * 100) + (64 * i); nv_math::mat4f *matPtr = (nv_math::mat4f*)(((uint8_t*)uniforms) + pointerOffset); m_flight_paths[i]->update(matPtr, sTime); } m_node_data->update((VkeNodeUniform*)uniforms); m_camera->setViewport(0, 0, (float)m_width, (float)m_height); m_camera->update(); VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; memRange.memory = m_uniforms_staging; memRange.offset = 0; memRange.size = sz; vkFlushMappedMemoryRanges(device->getVKDevice(), 1, &memRange); vkUnmapMemory(device->getVKDevice(), m_uniforms_staging); if (!m_is_first_frame){ VkSubmitInfo subInfo; memset(&subInfo, 0, sizeof(subInfo)); subInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; subInfo.commandBufferCount = 1; subInfo.pCommandBuffers = &m_update_commands[m_current_buffer_index]; vkQueueSubmit(dc->getDefaultQueue()->getVKQueue(), 1, &subInfo, VK_NULL_HANDLE); vkQueueWaitIdle(dc->getDefaultQueue()->getVKQueue()); #if defined(WIN32) subInfo.waitSemaphoreCount = 1; subInfo.pWaitSemaphores = &m_present_done; subInfo.signalSemaphoreCount = 0; subInfo.pSignalSemaphores = &m_render_done; #endif subInfo.pCommandBuffers = &m_primary_commands[m_current_buffer_index]; vkQueueSubmit(dc->getDefaultQueue()->getVKQueue(), 1, &subInfo, VK_NULL_HANDLE); } else{ m_is_first_frame = false; } present(); m_current_buffer_index++; m_current_buffer_index %= 2; sTime += 0.16; generateDrawCommands(); }