Code cleanup
This commit is contained in:
parent
f211a64153
commit
24591c6570
4 changed files with 108 additions and 112 deletions
|
|
@ -128,7 +128,7 @@ public:
|
|||
// Get device properties for the requested texture format
|
||||
VkFormatProperties formatProperties;
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProperties);
|
||||
// Check if requested image format supports image storage operations required for storing pixesl fromn the compute shader
|
||||
// Check if requested image format supports image storage operations required for storing pixel from the compute shader
|
||||
assert(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
|
||||
|
||||
// Prepare blit target texture
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* Demonstrates use of descriptor indexing to dynamically index into a variable sized array of images
|
||||
*
|
||||
* The sample renders multiple objects with the index of the texture (descriptor) to use passed as a vertex attribute (aka "descriptor indexing")
|
||||
*
|
||||
* Relevant code parts are marked with [POI]
|
||||
*
|
||||
* Copyright (C) 2021-2023 Sascha Willems - www.saschawillems.de
|
||||
|
|
@ -24,12 +26,12 @@ public:
|
|||
vks::Buffer indexBuffer;
|
||||
uint32_t indexCount{ 0 };
|
||||
|
||||
vks::Buffer uniformBufferVS;
|
||||
struct {
|
||||
struct UniformData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
} uboVS;
|
||||
} uniformData;
|
||||
vks::Buffer uniformBuffer;
|
||||
|
||||
VkPipeline pipeline{ VK_NULL_HANDLE };
|
||||
VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
|
||||
|
|
@ -74,7 +76,8 @@ public:
|
|||
|
||||
~VulkanExample()
|
||||
{
|
||||
for (auto &texture : textures) {
|
||||
if (device) {
|
||||
for (auto& texture : textures) {
|
||||
texture.destroy();
|
||||
}
|
||||
vkDestroyPipeline(device, pipeline, nullptr);
|
||||
|
|
@ -82,7 +85,8 @@ public:
|
|||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||
vertexBuffer.destroy();
|
||||
indexBuffer.destroy();
|
||||
uniformBufferVS.destroy();
|
||||
uniformBuffer.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// Generate some random textures
|
||||
|
|
@ -106,7 +110,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Generates a line of cubes with randomized per-face texture indices
|
||||
// Generates a line of cubes with randomized per-face texture indices and uploads them to the GPU
|
||||
void generateCubes()
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
|
|
@ -177,19 +181,27 @@ public:
|
|||
|
||||
indexCount = static_cast<uint32_t>(indices.size());
|
||||
|
||||
// For the sake of simplicity we won't stage the vertex data to the gpu memory
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&vertexBuffer,
|
||||
vertices.size() * sizeof(Vertex),
|
||||
vertices.data()));
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&indexBuffer,
|
||||
indices.size() * sizeof(uint32_t),
|
||||
indices.data()));
|
||||
// Create buffers and upload data to the GPU
|
||||
struct StagingBuffers {
|
||||
vks::Buffer vertices;
|
||||
vks::Buffer indices;
|
||||
} stagingBuffers;
|
||||
|
||||
// Host visible source buffers (staging)
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffers.vertices, vertices.size() * sizeof(Vertex), vertices.data()));
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffers.indices, indices.size() * sizeof(uint32_t), indices.data()));
|
||||
|
||||
// Device local destination buffers
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertexBuffer, vertices.size() * sizeof(Vertex)));
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &indexBuffer, indices.size() * sizeof(uint32_t)));
|
||||
|
||||
// Copy from host do device
|
||||
vulkanDevice->copyBuffer(&stagingBuffers.vertices, &vertexBuffer, queue);
|
||||
vulkanDevice->copyBuffer(&stagingBuffers.indices, &indexBuffer, queue);
|
||||
|
||||
// Clean up
|
||||
stagingBuffers.vertices.destroy();
|
||||
stagingBuffers.indices.destroy();
|
||||
}
|
||||
|
||||
// [POI] Set up descriptor sets and set layout
|
||||
|
|
@ -211,8 +223,7 @@ public:
|
|||
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
|
||||
// Binding 0 : Vertex shader uniform buffer
|
||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
|
||||
// [POI] Binding 1 contains a texture array that is dynamically non-uniform sampled from
|
||||
// In the fragment shader:
|
||||
// [POI] Binding 1 contains a texture array that is dynamically non-uniform sampled from in the fragment shader:
|
||||
// outFragColor = texture(textures[nonuniformEXT(inTexIndex)], inUV);
|
||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1, static_cast<uint32_t>(textures.size()))
|
||||
};
|
||||
|
|
@ -257,7 +268,7 @@ public:
|
|||
|
||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets(2);
|
||||
|
||||
writeDescriptorSets[0] = vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBufferVS.descriptor);
|
||||
writeDescriptorSets[0] = vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor);
|
||||
|
||||
// Image descriptors for the texture array
|
||||
std::vector<VkDescriptorImageInfo> textureDescriptors(textures.size());
|
||||
|
|
@ -284,10 +295,11 @@ public:
|
|||
|
||||
void preparePipelines()
|
||||
{
|
||||
|
||||
// Layout
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
|
||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
||||
|
||||
// Pipeline
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
|
||||
|
|
@ -335,21 +347,17 @@ public:
|
|||
|
||||
void prepareUniformBuffers()
|
||||
{
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&uniformBufferVS,
|
||||
sizeof(uboVS)));
|
||||
VK_CHECK_RESULT(uniformBufferVS.map());
|
||||
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_CHECK_RESULT(uniformBuffer.map());
|
||||
updateUniformBuffersCamera();
|
||||
}
|
||||
|
||||
void updateUniformBuffersCamera()
|
||||
{
|
||||
uboVS.projection = camera.matrices.perspective;
|
||||
uboVS.view = camera.matrices.view;
|
||||
uboVS.model = glm::mat4(1.0f);
|
||||
memcpy(uniformBufferVS.mapped, &uboVS, sizeof(uboVS));
|
||||
uniformData.projection = camera.matrices.perspective;
|
||||
uniformData.view = camera.matrices.view;
|
||||
uniformData.model = glm::mat4(1.0f);
|
||||
memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData));
|
||||
}
|
||||
|
||||
void buildCommandBuffers()
|
||||
|
|
@ -389,15 +397,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
VulkanExampleBase::prepareFrame();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
VulkanExampleBase::submitFrame();
|
||||
}
|
||||
|
||||
void prepare()
|
||||
{
|
||||
VulkanExampleBase::prepare();
|
||||
|
|
@ -410,18 +409,21 @@ public:
|
|||
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();
|
||||
}
|
||||
|
||||
virtual void render()
|
||||
{
|
||||
if (!prepared)
|
||||
return;
|
||||
updateUniformBuffersCamera();
|
||||
draw();
|
||||
if (camera.updated)
|
||||
updateUniformBuffersCamera();
|
||||
}
|
||||
|
||||
virtual void viewChanged()
|
||||
{
|
||||
updateUniformBuffersCamera();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Vulkan Example - Passing vertex attributes using interleaved and separate buffers
|
||||
*
|
||||
* Copyright (C) 2022 by Sascha Willems - www.saschawillems.de
|
||||
* Copyright (C) 2022-2023 by Sascha Willems - www.saschawillems.de
|
||||
*
|
||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
|
@ -153,6 +153,7 @@ VulkanExample::VulkanExample() : VulkanExampleBase()
|
|||
|
||||
VulkanExample::~VulkanExample()
|
||||
{
|
||||
if (device) {
|
||||
vkDestroyPipeline(device, pipelines.vertexAttributesInterleaved, nullptr);
|
||||
vkDestroyPipeline(device, pipelines.vertexAttributesSeparate, nullptr);
|
||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||
|
|
@ -171,6 +172,7 @@ VulkanExample::~VulkanExample()
|
|||
vkDestroySampler(vulkanDevice->logicalDevice, image.texture.sampler, nullptr);
|
||||
vkFreeMemory(vulkanDevice->logicalDevice, image.texture.deviceMemory, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanExample::getEnabledFeatures()
|
||||
|
|
@ -178,6 +180,33 @@ void VulkanExample::getEnabledFeatures()
|
|||
enabledFeatures.samplerAnisotropy = deviceFeatures.samplerAnisotropy;
|
||||
}
|
||||
|
||||
void VulkanExample::drawSceneNode(VkCommandBuffer commandBuffer, Node node)
|
||||
{
|
||||
if (node.mesh.primitives.size() > 0) {
|
||||
PushConstBlock pushConstBlock;
|
||||
glm::mat4 nodeMatrix = node.matrix;
|
||||
Node* currentParent = node.parent;
|
||||
while (currentParent) {
|
||||
nodeMatrix = currentParent->matrix * nodeMatrix;
|
||||
currentParent = currentParent->parent;
|
||||
}
|
||||
for (Primitive& primitive : node.mesh.primitives) {
|
||||
if (primitive.indexCount > 0) {
|
||||
Material& material = scene.materials[primitive.materialIndex];
|
||||
pushConstBlock.nodeMatrix = nodeMatrix;
|
||||
pushConstBlock.alphaMask = (material.alphaMode == "MASK");
|
||||
pushConstBlock.alphaMaskCutoff = material.alphaCutOff;
|
||||
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &material.descriptorSet, 0, nullptr);
|
||||
vkCmdDrawIndexed(commandBuffer, primitive.indexCount, 1, primitive.firstIndex, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& child : node.children) {
|
||||
drawSceneNode(commandBuffer, child);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanExample::buildCommandBuffers()
|
||||
{
|
||||
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
||||
|
|
@ -545,44 +574,10 @@ void VulkanExample::prepare()
|
|||
prepared = true;
|
||||
}
|
||||
|
||||
void VulkanExample::drawSceneNode(VkCommandBuffer commandBuffer, Node node)
|
||||
{
|
||||
if (node.mesh.primitives.size() > 0) {
|
||||
PushConstBlock pushConstBlock;
|
||||
glm::mat4 nodeMatrix = node.matrix;
|
||||
Node* currentParent = node.parent;
|
||||
while (currentParent) {
|
||||
nodeMatrix = currentParent->matrix * nodeMatrix;
|
||||
currentParent = currentParent->parent;
|
||||
}
|
||||
for (Primitive& primitive : node.mesh.primitives) {
|
||||
if (primitive.indexCount > 0) {
|
||||
Material& material = scene.materials[primitive.materialIndex];
|
||||
pushConstBlock.nodeMatrix = nodeMatrix;
|
||||
pushConstBlock.alphaMask = (material.alphaMode == "MASK");
|
||||
pushConstBlock.alphaMaskCutoff = material.alphaCutOff;
|
||||
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &material.descriptorSet, 0, nullptr);
|
||||
vkCmdDrawIndexed(commandBuffer, primitive.indexCount, 1, primitive.firstIndex, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& child : node.children) {
|
||||
drawSceneNode(commandBuffer, child);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanExample::render()
|
||||
{
|
||||
updateUniformBuffers();
|
||||
renderFrame();
|
||||
if (camera.updated) {
|
||||
updateUniformBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanExample::viewChanged()
|
||||
{
|
||||
updateUniformBuffers();
|
||||
}
|
||||
|
||||
void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Vulkan Example - Passing vertex attributes using interleaved and separate buffers
|
||||
*
|
||||
* Copyright (C) 2022 by Sascha Willems - www.saschawillems.de
|
||||
* Copyright (C) 2022-2023 by Sascha Willems - www.saschawillems.de
|
||||
*
|
||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
|
@ -137,6 +137,5 @@ public:
|
|||
void loadSceneNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, Node* parent);
|
||||
void drawSceneNode(VkCommandBuffer commandBuffer, Node node);
|
||||
virtual void render();
|
||||
virtual void viewChanged();
|
||||
virtual void OnUpdateUIOverlay(vks::UIOverlay* overlay);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue