VulkanBenchmarks: improve and clarify resource ownership

* Identify members that are owning handles with a comment * Reorder these members in creation order * Reorder explicit destruction of these members in reverse order in destructors * Replace raw pointers with unique_ptrs, but call reset explicitly in destructors to maintain reverse destruction order * Define VULKAN_HPP_NO_NODISCARD_WARNINGS to future-proof for C++17 and up * Remove vestigial vk::UniqueShaderModule and vk::UniquePipeline usage Bug: b/176981107 Change-Id: Ia090be98c2f8ed47701dfc92388547985e5c57b4 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51829Tested-by: 's avatarAntonio Maiorano <amaiorano@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 765e4f6f
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
# define VK_USE_PLATFORM_WIN32_KHR # define VK_USE_PLATFORM_WIN32_KHR
#endif #endif
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#define VULKAN_HPP_NO_NODISCARD_WARNINGS
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
...@@ -211,16 +212,16 @@ public: ...@@ -211,16 +212,16 @@ public:
instance.destroy(nullptr); instance.destroy(nullptr);
} }
private:
std::unique_ptr<vk::DynamicLoader> dl;
protected: protected:
const uint32_t queueFamilyIndex = 0; const uint32_t queueFamilyIndex = 0;
vk::Instance instance; vk::Instance instance; // Owning handle
vk::PhysicalDevice physicalDevice; vk::PhysicalDevice physicalDevice;
vk::Device device; vk::Device device; // Owning handle
vk::Queue queue; vk::Queue queue;
private:
std::unique_ptr<vk::DynamicLoader> dl;
}; };
class ClearImageBenchmark : public VulkanBenchmark class ClearImageBenchmark : public VulkanBenchmark
...@@ -317,11 +318,10 @@ public: ...@@ -317,11 +318,10 @@ public:
} }
private: private:
vk::CommandPool commandPool; vk::Image image; // Owning handle
vk::CommandBuffer commandBuffer; vk::DeviceMemory memory; // Owning handle
vk::CommandPool commandPool; // Owning handle
vk::Image image; vk::CommandBuffer commandBuffer; // Owning handle
vk::DeviceMemory memory;
}; };
static void ClearImage(benchmark::State &state, vk::Format clearFormat, vk::ImageAspectFlagBits clearAspect) static void ClearImage(benchmark::State &state, vk::Format clearFormat, vk::ImageAspectFlagBits clearAspect)
...@@ -449,10 +449,10 @@ private: ...@@ -449,10 +449,10 @@ private:
class Swapchain class Swapchain
{ {
public: public:
Swapchain(vk::PhysicalDevice physicalDevice, vk::Device device, Window *window) Swapchain(vk::PhysicalDevice physicalDevice, vk::Device device, Window &window)
: device(device) : device(device)
{ {
vk::SurfaceKHR surface = window->getSurface(); vk::SurfaceKHR surface = window.getSurface();
// Create the swapchain // Create the swapchain
vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface); vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface);
...@@ -542,11 +542,11 @@ public: ...@@ -542,11 +542,11 @@ public:
private: private:
const vk::Device device; const vk::Device device;
vk::SwapchainKHR swapchain; vk::SwapchainKHR swapchain; // Owning handle
vk::Extent2D extent; vk::Extent2D extent;
std::vector<vk::Image> images; // Weak pointers. Presentable images owned by swapchain object. std::vector<vk::Image> images; // Weak pointers. Presentable images owned by swapchain object.
std::vector<vk::ImageView> imageViews; std::vector<vk::ImageView> imageViews; // Owning handles
}; };
class Buffer class Buffer
...@@ -597,8 +597,8 @@ public: ...@@ -597,8 +597,8 @@ public:
private: private:
const vk::Device device; const vk::Device device;
vk::DeviceSize size; vk::DeviceSize size;
vk::Buffer buffer; vk::Buffer buffer; // Owning handle
vk::DeviceMemory bufferMemory; vk::DeviceMemory bufferMemory; // Owning handle
}; };
class Image class Image
...@@ -645,9 +645,9 @@ public: ...@@ -645,9 +645,9 @@ public:
~Image() ~Image()
{ {
device.destroyImage(image);
device.destroyImageView(imageView); device.destroyImageView(imageView);
device.freeMemory(imageMemory); device.freeMemory(imageMemory);
device.destroyImage(image);
} }
vk::Image getImage() vk::Image getImage()
...@@ -663,9 +663,9 @@ public: ...@@ -663,9 +663,9 @@ public:
private: private:
const vk::Device device; const vk::Device device;
vk::Image image; vk::Image image; // Owning handle
vk::DeviceMemory imageMemory; vk::DeviceMemory imageMemory; // Owning handle
vk::ImageView imageView; vk::ImageView imageView; // Owning handle
}; };
class Framebuffer class Framebuffer
...@@ -678,7 +678,7 @@ public: ...@@ -678,7 +678,7 @@ public:
if(multisample) if(multisample)
{ {
multisampleImage = new Image(device, extent.width, extent.height, colorFormat, vk::SampleCountFlagBits::e4); multisampleImage.reset(new Image(device, extent.width, extent.height, colorFormat, vk::SampleCountFlagBits::e4));
// We'll be rendering to attachment location 0 // We'll be rendering to attachment location 0
attachments[0] = multisampleImage->getImageView(); attachments[0] = multisampleImage->getImageView();
...@@ -703,9 +703,8 @@ public: ...@@ -703,9 +703,8 @@ public:
~Framebuffer() ~Framebuffer()
{ {
multisampleImage.reset();
device.destroyFramebuffer(framebuffer); device.destroyFramebuffer(framebuffer);
delete multisampleImage;
} }
vk::Framebuffer getFramebuffer() vk::Framebuffer getFramebuffer()
...@@ -715,10 +714,8 @@ public: ...@@ -715,10 +714,8 @@ public:
private: private:
const vk::Device device; const vk::Device device;
vk::Framebuffer framebuffer; // Owning handle
vk::Framebuffer framebuffer; std::unique_ptr<Image> multisampleImage;
Image *multisampleImage = nullptr;
}; };
static std::vector<uint32_t> compileGLSLtoSPIRV(const char *glslSource, EShLanguage glslLanguage) static std::vector<uint32_t> compileGLSLtoSPIRV(const char *glslSource, EShLanguage glslLanguage)
...@@ -764,8 +761,8 @@ public: ...@@ -764,8 +761,8 @@ public:
TriangleBenchmark(bool multisample) TriangleBenchmark(bool multisample)
: multisample(multisample) : multisample(multisample)
{ {
window = new Window(instance, windowSize); window.reset(new Window(instance, windowSize));
swapchain = new Swapchain(physicalDevice, device, window); swapchain.reset(new Swapchain(physicalDevice, device, *window));
renderPass = createRenderPass(swapchain->colorFormat); renderPass = createRenderPass(swapchain->colorFormat);
createFramebuffers(renderPass); createFramebuffers(renderPass);
...@@ -781,39 +778,37 @@ public: ...@@ -781,39 +778,37 @@ public:
~TriangleBenchmark() ~TriangleBenchmark()
{ {
delete texture; device.freeCommandBuffers(commandPool, commandBuffers);
device.destroyDescriptorSetLayout(descriptorSetLayout);
device.destroyDescriptorPool(descriptorPool); device.destroyDescriptorPool(descriptorPool);
device.destroySampler(sampler, nullptr); device.destroySampler(sampler, nullptr);
texture.reset();
device.destroyPipelineLayout(pipelineLayout, nullptr); device.destroyCommandPool(commandPool, nullptr);
device.destroyPipelineCache(pipelineCache, nullptr);
device.destroyBuffer(vertices.buffer, nullptr);
device.freeMemory(vertices.memory, nullptr);
device.destroySemaphore(presentCompleteSemaphore, nullptr);
device.destroySemaphore(renderCompleteSemaphore, nullptr);
for(auto &fence : waitFences) for(auto &fence : waitFences)
{ {
device.destroyFence(fence, nullptr); device.destroyFence(fence, nullptr);
} }
for(auto *framebuffer : framebuffers) device.destroySemaphore(renderCompleteSemaphore, nullptr);
device.destroySemaphore(presentCompleteSemaphore, nullptr);
device.destroyPipeline(pipeline);
device.destroyPipelineLayout(pipelineLayout, nullptr);
device.destroyDescriptorSetLayout(descriptorSetLayout);
device.freeMemory(vertices.memory, nullptr);
device.destroyBuffer(vertices.buffer, nullptr);
for(auto &framebuffer : framebuffers)
{ {
delete framebuffer; framebuffer.reset();
} }
device.destroyRenderPass(renderPass, nullptr); device.destroyRenderPass(renderPass, nullptr);
device.freeCommandBuffers(commandPool, commandBuffers); swapchain.reset();
device.destroyCommandPool(commandPool, nullptr); window.reset();
delete swapchain;
delete window;
} }
void renderFrame() void renderFrame()
...@@ -867,7 +862,7 @@ protected: ...@@ -867,7 +862,7 @@ protected:
commandPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer; commandPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
commandPool = device.createCommandPool(commandPoolCreateInfo); commandPool = device.createCommandPool(commandPoolCreateInfo);
texture = new Image(device, 16, 16, vk::Format::eR8G8B8A8Unorm); texture.reset(new Image(device, 16, 16, vk::Format::eR8G8B8A8Unorm));
// Fill texture with white // Fill texture with white
vk::DeviceSize bufferSize = 16 * 16 * 4; vk::DeviceSize bufferSize = 16 * 16 * 4;
...@@ -965,7 +960,7 @@ protected: ...@@ -965,7 +960,7 @@ protected:
commandBuffers[i].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, 1, &descriptorSets[0], 0, nullptr); commandBuffers[i].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, 1, &descriptorSets[0], 0, nullptr);
// Draw a triangle // Draw a triangle
commandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.get()); commandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
VULKAN_HPP_NAMESPACE::DeviceSize offset = 0; VULKAN_HPP_NAMESPACE::DeviceSize offset = 0;
commandBuffers[i].bindVertexBuffers(0, 1, &vertices.buffer, &offset); commandBuffers[i].bindVertexBuffers(0, 1, &vertices.buffer, &offset);
commandBuffers[i].draw(3, 1, 0, 0); commandBuffers[i].draw(3, 1, 0, 0);
...@@ -1026,7 +1021,7 @@ protected: ...@@ -1026,7 +1021,7 @@ protected:
for(size_t i = 0; i < framebuffers.size(); i++) for(size_t i = 0; i < framebuffers.size(); i++)
{ {
framebuffers[i] = new Framebuffer(device, swapchain->getImageView(i), swapchain->colorFormat, renderPass, swapchain->getExtent(), multisample); framebuffers[i].reset(new Framebuffer(device, swapchain->getImageView(i), swapchain->colorFormat, renderPass, swapchain->getExtent(), multisample));
} }
} }
...@@ -1111,7 +1106,7 @@ protected: ...@@ -1111,7 +1106,7 @@ protected:
return device.createRenderPass(renderPassInfo); return device.createRenderPass(renderPassInfo);
} }
vk::UniqueShaderModule createShaderModule(const char *glslSource, EShLanguage glslLanguage) vk::ShaderModule createShaderModule(const char *glslSource, EShLanguage glslLanguage)
{ {
auto spirv = compileGLSLtoSPIRV(glslSource, glslLanguage); auto spirv = compileGLSLtoSPIRV(glslSource, glslLanguage);
...@@ -1119,10 +1114,10 @@ protected: ...@@ -1119,10 +1114,10 @@ protected:
moduleCreateInfo.codeSize = spirv.size() * sizeof(uint32_t); moduleCreateInfo.codeSize = spirv.size() * sizeof(uint32_t);
moduleCreateInfo.pCode = (uint32_t *)spirv.data(); moduleCreateInfo.pCode = (uint32_t *)spirv.data();
return device.createShaderModuleUnique(moduleCreateInfo); return device.createShaderModule(moduleCreateInfo);
} }
vk::UniquePipeline createGraphicsPipeline(vk::RenderPass renderPass) vk::Pipeline createGraphicsPipeline(vk::RenderPass renderPass)
{ {
vk::DescriptorSetLayoutBinding samplerLayoutBinding; vk::DescriptorSetLayoutBinding samplerLayoutBinding;
samplerLayoutBinding.binding = 1; samplerLayoutBinding.binding = 1;
...@@ -1225,16 +1220,16 @@ protected: ...@@ -1225,16 +1220,16 @@ protected:
} }
)"; )";
vk::UniqueShaderModule vertexModule = createShaderModule(vertexShader, EShLanguage::EShLangVertex); vk::ShaderModule vertexModule = createShaderModule(vertexShader, EShLanguage::EShLangVertex);
vk::UniqueShaderModule fragmentModule = createShaderModule(fragmentShader, EShLanguage::EShLangFragment); vk::ShaderModule fragmentModule = createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages; std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages;
shaderStages[0].module = vertexModule.get(); shaderStages[0].module = vertexModule;
shaderStages[0].stage = vk::ShaderStageFlagBits::eVertex; shaderStages[0].stage = vk::ShaderStageFlagBits::eVertex;
shaderStages[0].pName = "main"; shaderStages[0].pName = "main";
shaderStages[1].module = fragmentModule.get(); shaderStages[1].module = fragmentModule;
shaderStages[1].stage = vk::ShaderStageFlagBits::eFragment; shaderStages[1].stage = vk::ShaderStageFlagBits::eFragment;
shaderStages[1].pName = "main"; shaderStages[1].pName = "main";
...@@ -1250,46 +1245,47 @@ protected: ...@@ -1250,46 +1245,47 @@ protected:
pipelineCreateInfo.renderPass = renderPass; pipelineCreateInfo.renderPass = renderPass;
pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.pDynamicState = &dynamicState;
return device.createGraphicsPipelineUnique(nullptr, pipelineCreateInfo).value; auto pipeline = device.createGraphicsPipeline(nullptr, pipelineCreateInfo).value;
device.destroyShaderModule(fragmentModule);
device.destroyShaderModule(vertexModule);
return pipeline;
} }
const vk::Extent2D windowSize = { 1280, 720 }; const vk::Extent2D windowSize = { 1280, 720 };
const bool multisample; const bool multisample;
Window *window = nullptr;
Swapchain *swapchain = nullptr; std::unique_ptr<Window> window;
std::unique_ptr<Swapchain> swapchain;
vk::RenderPass renderPass; vk::RenderPass renderPass; // Owning handle
std::vector<Framebuffer *> framebuffers; std::vector<std::unique_ptr<Framebuffer>> framebuffers;
uint32_t currentFrameBuffer = 0; uint32_t currentFrameBuffer = 0;
struct VertexBuffer struct VertexBuffer
{ {
vk::Buffer buffer; vk::Buffer buffer; // Owning handle
vk::DeviceMemory memory; vk::DeviceMemory memory; // Owning handle
vk::PipelineVertexInputStateCreateInfo inputState;
vk::VertexInputBindingDescription inputBinding; vk::VertexInputBindingDescription inputBinding;
std::vector<vk::VertexInputAttributeDescription> inputAttributes; std::vector<vk::VertexInputAttributeDescription> inputAttributes;
vk::PipelineVertexInputStateCreateInfo inputState;
} vertices; } vertices;
vk::DescriptorPool descriptorPool; vk::DescriptorSetLayout descriptorSetLayout; // Owning handle
vk::DescriptorSetLayout descriptorSetLayout; vk::PipelineLayout pipelineLayout; // Owning handle
vk::PipelineLayout pipelineLayout; vk::Pipeline pipeline; // Owning handle
vk::PipelineCache pipelineCache;
vk::UniquePipeline pipeline;
vk::Sampler sampler;
vk::CommandPool commandPool;
std::vector<vk::CommandBuffer> commandBuffers;
vk::Semaphore presentCompleteSemaphore;
vk::Semaphore renderCompleteSemaphore;
std::vector<vk::Fence> waitFences; vk::Semaphore presentCompleteSemaphore; // Owning handle
vk::Semaphore renderCompleteSemaphore; // Owning handle
std::vector<vk::Fence> waitFences; // Owning handles
Image *texture = nullptr; vk::CommandPool commandPool; // Owning handle
std::unique_ptr<Image> texture;
vk::Sampler sampler; // Owning handle
vk::DescriptorPool descriptorPool; // Owning handle
std::vector<vk::CommandBuffer> commandBuffers; // Owning handles
}; };
static void Triangle(benchmark::State &state, bool multisample) static void Triangle(benchmark::State &state, bool multisample)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment