Code cleanup, fix query results
This commit is contained in:
parent
dec7d2e9f8
commit
06439511e4
1 changed files with 77 additions and 104 deletions
|
|
@ -9,46 +9,41 @@
|
||||||
#include "vulkanexamplebase.h"
|
#include "vulkanexamplebase.h"
|
||||||
#include "VulkanglTFModel.h"
|
#include "VulkanglTFModel.h"
|
||||||
|
|
||||||
#define OBJ_DIM 0.05f
|
|
||||||
|
|
||||||
class VulkanExample : public VulkanExampleBase
|
class VulkanExample : public VulkanExampleBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// This sample lets you select between different models to display
|
||||||
struct Models {
|
struct Models {
|
||||||
std::vector<vkglTF::Model> objects;
|
std::vector<vkglTF::Model> objects;
|
||||||
int32_t objectIndex = 3;
|
int32_t objectIndex{ 3 };
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
} models;
|
} models;
|
||||||
|
// Size for the two-dimensional grid of objects (e.g. 3 = draws 3x3 objects)
|
||||||
|
int32_t gridSize{ 3 };
|
||||||
|
|
||||||
struct UniformBuffers {
|
struct UniformData {
|
||||||
vks::Buffer VS;
|
|
||||||
} uniformBuffers;
|
|
||||||
|
|
||||||
struct UBOVS {
|
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
glm::mat4 modelview;
|
glm::mat4 modelview;
|
||||||
glm::vec4 lightPos = glm::vec4(-10.0f, -10.0f, 10.0f, 1.0f);
|
glm::vec4 lightPos{ -10.0f, -10.0f, 10.0f, 1.0f };
|
||||||
} uboVS;
|
} uniformData;
|
||||||
|
vks::Buffer uniformBuffer;
|
||||||
|
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
int32_t cullMode{ VK_CULL_MODE_BACK_BIT };
|
||||||
|
bool blending{ false };
|
||||||
|
bool discard{ false };
|
||||||
|
bool wireframe{ false };
|
||||||
|
bool tessellation{ false };
|
||||||
|
|
||||||
int32_t cullMode = VK_CULL_MODE_BACK_BIT;
|
VkPipeline pipeline{ VK_NULL_HANDLE };
|
||||||
bool blending = false;
|
VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
|
||||||
bool discard = false;
|
VkDescriptorSet descriptorSet{ VK_NULL_HANDLE };
|
||||||
bool wireframe = false;
|
VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE };
|
||||||
bool tessellation = false;
|
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout;
|
VkQueryPool queryPool{ VK_NULL_HANDLE };
|
||||||
VkDescriptorSet descriptorSet;
|
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
|
||||||
|
|
||||||
VkQueryPool queryPool;
|
|
||||||
|
|
||||||
// Vector for storing pipeline statistics results
|
// Vector for storing pipeline statistics results
|
||||||
std::vector<uint64_t> pipelineStats;
|
std::vector<uint64_t> pipelineStats{};
|
||||||
std::vector<std::string> pipelineStatNames;
|
std::vector<std::string> pipelineStatNames{};
|
||||||
|
|
||||||
int32_t gridSize = 3;
|
|
||||||
|
|
||||||
VulkanExample() : VulkanExampleBase()
|
VulkanExample() : VulkanExampleBase()
|
||||||
{
|
{
|
||||||
|
|
@ -63,11 +58,13 @@ public:
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample()
|
||||||
{
|
{
|
||||||
vkDestroyPipeline(device, pipeline, nullptr);
|
if (device) {
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipeline(device, pipeline, nullptr);
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyQueryPool(device, queryPool, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
uniformBuffers.VS.destroy();
|
vkDestroyQueryPool(device, queryPool, nullptr);
|
||||||
|
uniformBuffer.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getEnabledFeatures()
|
virtual void getEnabledFeatures()
|
||||||
|
|
@ -141,7 +138,7 @@ public:
|
||||||
dataSize,
|
dataSize,
|
||||||
pipelineStats.data(),
|
pipelineStats.data(),
|
||||||
stride,
|
stride,
|
||||||
VK_QUERY_RESULT_64_BIT);
|
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildCommandBuffers()
|
void buildCommandBuffers()
|
||||||
|
|
@ -206,20 +203,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw()
|
|
||||||
{
|
|
||||||
VulkanExampleBase::prepareFrame();
|
|
||||||
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
|
||||||
|
|
||||||
// Read query results for displaying in next frame
|
|
||||||
getQueryResults();
|
|
||||||
|
|
||||||
VulkanExampleBase::submitFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadAssets()
|
void loadAssets()
|
||||||
{
|
{
|
||||||
// Objects
|
// Objects
|
||||||
|
|
@ -231,47 +214,45 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupDescriptorPool()
|
void setupDescriptors()
|
||||||
{
|
{
|
||||||
|
// Pool
|
||||||
std::vector<VkDescriptorPoolSize> poolSizes = {
|
std::vector<VkDescriptorPoolSize> poolSizes = {
|
||||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3)
|
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3)
|
||||||
};
|
};
|
||||||
VkDescriptorPoolCreateInfo descriptorPoolInfo =
|
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 3);
|
||||||
vks::initializers::descriptorPoolCreateInfo(poolSizes, 3);
|
|
||||||
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
||||||
}
|
|
||||||
|
|
||||||
void setupDescriptorSetLayout()
|
// Layout
|
||||||
{
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
|
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
|
||||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0)
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0)
|
||||||
};
|
};
|
||||||
VkDescriptorSetLayoutCreateInfo descriptorLayout =
|
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
||||||
vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
|
||||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
|
// Set
|
||||||
vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
|
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
||||||
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::vec3), 0);
|
|
||||||
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
|
||||||
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
|
|
||||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setupDescriptorSets()
|
|
||||||
{
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo =
|
|
||||||
vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.VS.descriptor)
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor)
|
||||||
};
|
};
|
||||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
|
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void preparePipelines()
|
void preparePipelines()
|
||||||
{
|
{
|
||||||
|
// Layout
|
||||||
|
if (pipelineLayout == VK_NULL_HANDLE) {
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
|
||||||
|
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::vec3), 0);
|
||||||
|
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
||||||
|
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
|
||||||
|
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pipeline
|
||||||
if (pipeline != VK_NULL_HANDLE) {
|
if (pipeline != VK_NULL_HANDLE) {
|
||||||
|
// Destroy old pipeline if we're going to recreate it
|
||||||
vkDestroyPipeline(device, pipeline, nullptr);
|
vkDestroyPipeline(device, pipeline, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -336,23 +317,15 @@ public:
|
||||||
// Prepare and initialize uniform buffer containing shader uniforms
|
// Prepare and initialize uniform buffer containing shader uniforms
|
||||||
void prepareUniformBuffers()
|
void prepareUniformBuffers()
|
||||||
{
|
{
|
||||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffer, sizeof(UniformData)));
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
VK_CHECK_RESULT(uniformBuffer.map());
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&uniformBuffers.VS,
|
|
||||||
sizeof(uboVS)));
|
|
||||||
|
|
||||||
// Map persistent
|
|
||||||
VK_CHECK_RESULT(uniformBuffers.VS.map());
|
|
||||||
|
|
||||||
updateUniformBuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateUniformBuffers()
|
void updateUniformBuffers()
|
||||||
{
|
{
|
||||||
uboVS.projection = camera.matrices.perspective;
|
uniformData.projection = camera.matrices.perspective;
|
||||||
uboVS.modelview = camera.matrices.view;
|
uniformData.modelview = camera.matrices.view;
|
||||||
memcpy(uniformBuffers.VS.mapped, &uboVS, sizeof(uboVS));
|
memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
|
|
@ -361,24 +334,32 @@ public:
|
||||||
loadAssets();
|
loadAssets();
|
||||||
setupQueryPool();
|
setupQueryPool();
|
||||||
prepareUniformBuffers();
|
prepareUniformBuffers();
|
||||||
setupDescriptorSetLayout();
|
setupDescriptors();
|
||||||
preparePipelines();
|
preparePipelines();
|
||||||
setupDescriptorPool();
|
|
||||||
setupDescriptorSets();
|
|
||||||
buildCommandBuffers();
|
buildCommandBuffers();
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw()
|
||||||
|
{
|
||||||
|
VulkanExampleBase::prepareFrame();
|
||||||
|
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||||
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
|
||||||
|
VulkanExampleBase::submitFrame();
|
||||||
|
|
||||||
|
// Read query results for displaying in next frame
|
||||||
|
getQueryResults();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void render()
|
virtual void render()
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void viewChanged()
|
|
||||||
{
|
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
|
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
|
||||||
|
|
@ -391,28 +372,20 @@ public:
|
||||||
if (overlay->sliderInt("Grid size", &gridSize, 1, 10)) {
|
if (overlay->sliderInt("Grid size", &gridSize, 1, 10)) {
|
||||||
buildCommandBuffers();
|
buildCommandBuffers();
|
||||||
}
|
}
|
||||||
|
// To avoid having to create pipelines for all the settings up front, we recreate a single pipelin with different settings instead
|
||||||
|
bool recreatePipeline{ false };
|
||||||
std::vector<std::string> cullModeNames = { "None", "Front", "Back", "Back and front" };
|
std::vector<std::string> cullModeNames = { "None", "Front", "Back", "Back and front" };
|
||||||
if (overlay->comboBox("Cull mode", &cullMode, cullModeNames)) {
|
recreatePipeline |= overlay->comboBox("Cull mode", &cullMode, cullModeNames);
|
||||||
preparePipelines();
|
recreatePipeline |= overlay->checkBox("Blending", &blending);
|
||||||
buildCommandBuffers();
|
recreatePipeline |= overlay->checkBox("Discard", &discard);
|
||||||
}
|
// These features may not be supported by all implementations
|
||||||
if (overlay->checkBox("Blending", &blending)) {
|
|
||||||
preparePipelines();
|
|
||||||
buildCommandBuffers();
|
|
||||||
}
|
|
||||||
if (deviceFeatures.fillModeNonSolid) {
|
if (deviceFeatures.fillModeNonSolid) {
|
||||||
if (overlay->checkBox("Wireframe", &wireframe)) {
|
recreatePipeline |= overlay->checkBox("Wireframe", &wireframe);
|
||||||
preparePipelines();
|
|
||||||
buildCommandBuffers();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (deviceFeatures.tessellationShader) {
|
if (deviceFeatures.tessellationShader) {
|
||||||
if (overlay->checkBox("Tessellation", &tessellation)) {
|
recreatePipeline |= overlay->checkBox("Tessellation", &tessellation);
|
||||||
preparePipelines();
|
|
||||||
buildCommandBuffers();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (overlay->checkBox("Discard", &discard)) {
|
if (recreatePipeline) {
|
||||||
preparePipelines();
|
preparePipelines();
|
||||||
buildCommandBuffers();
|
buildCommandBuffers();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue