cleanup and refactoring
This commit is contained in:
parent
2302158928
commit
76f6bf62a4
1285 changed files with 757994 additions and 8 deletions
241
raytracer/nvpro_core/nvvkhl/gbuffer.cpp
Normal file
241
raytracer/nvpro_core/nvvkhl/gbuffer.cpp
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2023 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "gbuffer.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include "application.hpp"
|
||||
#include "third_party/imgui/backends/imgui_impl_vulkan.h"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/commands_vk.hpp"
|
||||
|
||||
nvvkhl::GBuffer::GBuffer(VkDevice device, nvvk::ResourceAllocator* alloc)
|
||||
: m_device(device)
|
||||
, m_alloc(alloc)
|
||||
{
|
||||
}
|
||||
|
||||
nvvkhl::GBuffer::GBuffer(VkDevice device, nvvk::ResourceAllocator* alloc, const VkExtent2D& size, VkFormat color, VkFormat depth)
|
||||
: m_device(device)
|
||||
, m_alloc(alloc)
|
||||
{
|
||||
create(size, {color}, depth);
|
||||
}
|
||||
|
||||
nvvkhl::GBuffer::GBuffer(VkDevice device, nvvk::ResourceAllocator* alloc, const VkExtent2D& size, std::vector<VkFormat> color, VkFormat depth)
|
||||
: m_device(device)
|
||||
, m_alloc(alloc)
|
||||
{
|
||||
create(size, color, depth);
|
||||
}
|
||||
|
||||
nvvkhl::GBuffer::~GBuffer()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void nvvkhl::GBuffer::create(const VkExtent2D& size, std::vector<VkFormat> color, VkFormat depth)
|
||||
{
|
||||
assert(m_colorFormat.empty()); // The buffer must be cleared before creating a new one
|
||||
|
||||
m_imageSize = size;
|
||||
m_colorFormat = std::move(color);
|
||||
m_depthFormat = depth;
|
||||
|
||||
nvvk::DebugUtil dutil(m_device);
|
||||
|
||||
VkImageLayout layout{VK_IMAGE_LAYOUT_GENERAL};
|
||||
|
||||
|
||||
auto num_color = static_cast<uint32_t>(m_colorFormat.size());
|
||||
|
||||
m_res.gBufferColor.resize(num_color);
|
||||
m_res.descriptor.resize(num_color);
|
||||
m_res.uiImageViews.resize(num_color);
|
||||
|
||||
for(uint32_t c = 0; c < num_color; c++)
|
||||
{
|
||||
{ // Color image
|
||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
VkImageCreateInfo info = nvvk::makeImage2DCreateInfo(m_imageSize, m_colorFormat[c], usage);
|
||||
m_res.gBufferColor[c] = m_alloc->createImage(info);
|
||||
dutil.setObjectName(m_res.gBufferColor[c].image, "G-Color" + std::to_string(c));
|
||||
}
|
||||
{ // Image color view
|
||||
VkImageViewCreateInfo info = nvvk::makeImage2DViewCreateInfo(m_res.gBufferColor[c].image, m_colorFormat[c]);
|
||||
vkCreateImageView(m_device, &info, nullptr, &m_res.descriptor[c].imageView);
|
||||
dutil.setObjectName(m_res.descriptor[c].imageView, "G-Color" + std::to_string(c));
|
||||
}
|
||||
{ // UI Image color view
|
||||
VkImageViewCreateInfo info = nvvk::makeImage2DViewCreateInfo(m_res.gBufferColor[c].image, m_colorFormat[c]);
|
||||
info.components.a = VK_COMPONENT_SWIZZLE_ONE;
|
||||
vkCreateImageView(m_device, &info, nullptr, &m_res.uiImageViews[c]);
|
||||
dutil.setObjectName(m_res.uiImageViews[c], "UI G-Color" + std::to_string(c));
|
||||
}
|
||||
|
||||
if(m_res.descriptor[c].sampler == VK_NULL_HANDLE)
|
||||
{ // Image sampler: nearest sampling by default
|
||||
VkSamplerCreateInfo info{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
|
||||
m_res.descriptor[c].sampler = m_alloc->acquireSampler(info);
|
||||
dutil.setObjectName(m_res.descriptor[c].sampler, "G-Sampler");
|
||||
}
|
||||
}
|
||||
|
||||
if(m_depthFormat != VK_FORMAT_UNDEFINED)
|
||||
{ // Depth buffer
|
||||
VkImageCreateInfo info = nvvk::makeImage2DCreateInfo(m_imageSize, m_depthFormat,
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
m_res.gBufferDepth = m_alloc->createImage(info);
|
||||
dutil.setObjectName(m_res.gBufferDepth.image, "G-Depth");
|
||||
}
|
||||
|
||||
if(m_depthFormat != VK_FORMAT_UNDEFINED)
|
||||
{ // Image depth view
|
||||
VkImageViewCreateInfo info = nvvk::makeImage2DViewCreateInfo(m_res.gBufferDepth.image, m_depthFormat);
|
||||
info.subresourceRange = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1};
|
||||
vkCreateImageView(m_device, &info, nullptr, &m_res.depthView);
|
||||
dutil.setObjectName(m_res.depthView, "G-Depth");
|
||||
}
|
||||
|
||||
|
||||
{ // Change color image layout
|
||||
nvvk::CommandPool cpool(m_device, 0);
|
||||
VkCommandBuffer cmd = cpool.createCommandBuffer();
|
||||
for(uint32_t c = 0; c < num_color; c++)
|
||||
{
|
||||
nvvk::cmdBarrierImageLayout(cmd, m_res.gBufferColor[c].image, VK_IMAGE_LAYOUT_UNDEFINED, layout);
|
||||
m_res.descriptor[c].imageLayout = layout;
|
||||
|
||||
// Clear to avoid garbage data
|
||||
VkClearColorValue clear_value = {{0.F, 0.F, 0.F, 0.F}};
|
||||
VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
vkCmdClearColorImage(cmd, m_res.gBufferColor[c].image, layout, &clear_value, 1, &range);
|
||||
}
|
||||
cpool.submitAndWait(cmd);
|
||||
}
|
||||
|
||||
// Descriptor Set for ImGUI
|
||||
if((ImGui::GetCurrentContext() != nullptr) && ImGui::GetIO().BackendPlatformUserData != nullptr)
|
||||
{
|
||||
VkSamplerCreateInfo info{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
|
||||
info.minFilter = VK_FILTER_LINEAR;
|
||||
info.magFilter = VK_FILTER_LINEAR;
|
||||
m_res.linearSampler = m_alloc->acquireSampler(info);
|
||||
|
||||
for(size_t d = 0; d < m_res.descriptor.size(); ++d)
|
||||
{
|
||||
const VkDescriptorImageInfo& desc = m_res.descriptor[d];
|
||||
m_descriptorSet.push_back(ImGui_ImplVulkan_AddTexture(m_res.linearSampler, m_res.uiImageViews[d], layout));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
// Destroying all allocated resources
|
||||
//
|
||||
void nvvkhl::GBuffer::destroy()
|
||||
{
|
||||
if((ImGui::GetCurrentContext() != nullptr) && ImGui::GetIO().BackendPlatformUserData != nullptr)
|
||||
{
|
||||
for(VkDescriptorSet set : m_descriptorSet)
|
||||
{
|
||||
ImGui_ImplVulkan_RemoveTexture(set);
|
||||
}
|
||||
|
||||
if(m_res.linearSampler)
|
||||
m_alloc->releaseSampler(m_res.linearSampler);
|
||||
}
|
||||
|
||||
for(nvvk::Image bc : m_res.gBufferColor)
|
||||
{
|
||||
m_alloc->destroy(bc);
|
||||
}
|
||||
|
||||
m_alloc->destroy(m_res.gBufferDepth);
|
||||
|
||||
vkDestroyImageView(m_device, m_res.depthView, nullptr);
|
||||
|
||||
for(const VkDescriptorImageInfo& desc : m_res.descriptor)
|
||||
{
|
||||
vkDestroyImageView(m_device, desc.imageView, nullptr);
|
||||
m_alloc->releaseSampler(desc.sampler);
|
||||
}
|
||||
|
||||
for(const VkImageView& view : m_res.uiImageViews)
|
||||
{
|
||||
vkDestroyImageView(m_device, view, nullptr);
|
||||
}
|
||||
|
||||
// Reset everything to zero
|
||||
m_res = {};
|
||||
m_imageSize = {};
|
||||
m_colorFormat.clear();
|
||||
m_descriptorSet.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// Creating a buffer from one of the color image.
|
||||
// This can be used to save image to disk:
|
||||
//
|
||||
// Note: it is the responsibility to the function who call this, to destroy the buffer.
|
||||
nvvk::Buffer nvvkhl::GBuffer::createImageToBuffer(VkCommandBuffer cmd, uint32_t i /*= 0*/) const
|
||||
{
|
||||
// Source image
|
||||
VkImage src_image = getColorImage(i);
|
||||
VkExtent2D img_size = getSize();
|
||||
|
||||
VkFormat format = getColorFormat(i);
|
||||
uint32_t bytesPerPixel = 0;
|
||||
if(format >= VK_FORMAT_R8G8B8A8_UNORM && format <= VK_FORMAT_B8G8R8A8_SRGB)
|
||||
bytesPerPixel = 4 * sizeof(uint8_t);
|
||||
else if(format >= VK_FORMAT_R16G16B16A16_UNORM && format <= VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
bytesPerPixel = 4 * sizeof(uint16_t);
|
||||
else if(format >= VK_FORMAT_R32G32B32A32_UINT && format <= VK_FORMAT_R32G32B32A32_SFLOAT)
|
||||
bytesPerPixel = 4 * sizeof(uint32_t);
|
||||
assert(bytesPerPixel != 0); // Format unsupported
|
||||
|
||||
// Destination buffer
|
||||
size_t buf_size = static_cast<size_t>(bytesPerPixel) * img_size.width * img_size.height;
|
||||
nvvk::Buffer dst_buffer = m_alloc->createBuffer(buf_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
// Region to copy from the image (all)
|
||||
VkBufferImageCopy region = {};
|
||||
region.bufferRowLength = img_size.width;
|
||||
region.bufferImageHeight = img_size.height;
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageExtent.width = img_size.width;
|
||||
region.imageExtent.height = img_size.height;
|
||||
region.imageExtent.depth = 1;
|
||||
|
||||
// Copy the image to buffer
|
||||
nvvk::cmdBarrierImageLayout(cmd, src_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
vkCmdCopyImageToBuffer(cmd, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_buffer.buffer, 1, ®ion);
|
||||
nvvk::cmdBarrierImageLayout(cmd, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// Barrier to make sure work is done
|
||||
VkMemoryBarrier memBarrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER};
|
||||
memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
memBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memBarrier, 0,
|
||||
nullptr, 0, nullptr);
|
||||
|
||||
return dst_buffer;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue