diff --git a/data/shaders/dynamicuniformbuffer/base.frag b/data/shaders/dynamicuniformbuffer/base.frag new file mode 100644 index 00000000..8461f680 --- /dev/null +++ b/data/shaders/dynamicuniformbuffer/base.frag @@ -0,0 +1,13 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec3 inColor; + +layout (location = 0) out vec4 outFragColor; + +void main() +{ + outFragColor = vec4(inColor, 1.0); +} \ No newline at end of file diff --git a/data/shaders/dynamicuniformbuffer/base.frag.spv b/data/shaders/dynamicuniformbuffer/base.frag.spv new file mode 100644 index 00000000..06ab7a2f Binary files /dev/null and b/data/shaders/dynamicuniformbuffer/base.frag.spv differ diff --git a/data/shaders/dynamicuniformbuffer/base.vert b/data/shaders/dynamicuniformbuffer/base.vert new file mode 100644 index 00000000..009ff763 --- /dev/null +++ b/data/shaders/dynamicuniformbuffer/base.vert @@ -0,0 +1,33 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec3 inPos; +layout (location = 1) in vec3 inColor; + +layout (binding = 0) uniform UboView +{ + mat4 projection; + mat4 view; +} uboView; + +layout (binding = 1) uniform UboInstance +{ + mat4 model; +} uboInstance; + +layout (location = 0) out vec3 outColor; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + outColor = inColor; + mat4 modelView = uboView.view * uboInstance.model; + vec3 worldPos = vec3(modelView * vec4(inPos, 1.0)); + gl_Position = uboView.projection * modelView * vec4(inPos.xyz, 1.0); +} diff --git a/data/shaders/dynamicuniformbuffer/base.vert.spv b/data/shaders/dynamicuniformbuffer/base.vert.spv new file mode 100644 index 00000000..8b1bc182 Binary files /dev/null and b/data/shaders/dynamicuniformbuffer/base.vert.spv differ diff --git a/dynamicuniformbuffer/dynamicuniformbuffer.cpp b/dynamicuniformbuffer/dynamicuniformbuffer.cpp new file mode 100644 index 00000000..daa04ab4 --- /dev/null +++ b/dynamicuniformbuffer/dynamicuniformbuffer.cpp @@ -0,0 +1,519 @@ +/* +* Vulkan Example - Dynamic uniform buffers +* +* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de +* +* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +* +* Summary: +* Demonstrates the use of dynamic uniform buffers. +* +* Instead of using one uniform buffer per-object, this example allocates one big uniform buffer +* with respect to the alignment reported by the device via minUniformBufferOffsetAlignment that +* contains all matrices for the objects in the scene. +* +* The used descriptor type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC then allows to set a dynamic +* offset used to pass data from the single uniform buffer to the connected shader binding point. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include +#include + +#include +#include "vulkanexamplebase.h" +#include "vulkandevice.hpp" +#include "vulkanbuffer.hpp" + +#define VERTEX_BUFFER_BIND_ID 0 +#define ENABLE_VALIDATION false +#define OBJECT_INSTANCES 125 + +// Vertex layout for this example +struct Vertex { + float pos[3]; + float color[3]; +}; + +class VulkanExample : public VulkanExampleBase +{ +public: + struct { + VkPipelineVertexInputStateCreateInfo inputState; + std::vector bindingDescriptions; + std::vector attributeDescriptions; + } vertices; + + vk::Buffer vertexBuffer; + vk::Buffer indexBuffer; + uint32_t indexCount; + + struct { + vk::Buffer view; + vk::Buffer dynamic; + } uniformBuffers; + + struct { + glm::mat4 projection; + glm::mat4 view; + } uboVS; + + // Store random per-object rotations + glm::vec3 rotations[OBJECT_INSTANCES]; + glm::vec3 rotationSpeeds[OBJECT_INSTANCES]; + + // One big uniform buffer that contains all matrices + // Note that we need to manually allocate the data to cope for GPU-specific uniform buffer offset alignments + struct UboDataDynamic { + glm::mat4 *model = nullptr; + } uboDataDynamic; + + VkPipeline pipeline; + VkPipelineLayout pipelineLayout; + VkDescriptorSet descriptorSet; + VkDescriptorSetLayout descriptorSetLayout; + + float animationTimer = 0.0f; + + size_t dynamicAlignment; + + VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION) + { + title = "Vulkan Example - Dynamic uniform buffers"; + enableTextOverlay = true; + camera.type = Camera::CameraType::lookat; + camera.setPosition(glm::vec3(0.0f, 0.0f, -30.0f)); + camera.setRotation(glm::vec3(0.0f)); + camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f); + } + + ~VulkanExample() + { + if (uboDataDynamic.model) { + // todo: linux, android + _aligned_free(uboDataDynamic.model); + } + + // Clean up used Vulkan resources + // Note : Inherited destructor cleans up resources stored in base class + vkDestroyPipeline(device, pipeline, nullptr); + + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + + vertexBuffer.destroy(); + indexBuffer.destroy(); + + uniformBuffers.view.destroy(); + uniformBuffers.dynamic.destroy(); + } + + void buildCommandBuffers() + { + VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); + + VkClearValue clearValues[2]; + clearValues[0].color = defaultClearColor; + clearValues[1].depthStencil = { 1.0f, 0 }; + + VkRenderPassBeginInfo renderPassBeginInfo = vkTools::initializers::renderPassBeginInfo(); + renderPassBeginInfo.renderPass = renderPass; + renderPassBeginInfo.renderArea.offset.x = 0; + renderPassBeginInfo.renderArea.offset.y = 0; + renderPassBeginInfo.renderArea.extent.width = width; + renderPassBeginInfo.renderArea.extent.height = height; + renderPassBeginInfo.clearValueCount = 2; + renderPassBeginInfo.pClearValues = clearValues; + + for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) + { + renderPassBeginInfo.framebuffer = frameBuffers[i]; + + VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); + + vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); + vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); + + VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0); + vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); + + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + + VkDeviceSize offsets[1] = { 0 }; + vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &vertexBuffer.buffer, offsets); + vkCmdBindIndexBuffer(drawCmdBuffers[i], indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); + + // Render multiple objects using different model matrices by dynamically offsetting into one uniform buffer + for (uint32_t j = 0; j < OBJECT_INSTANCES; j++) + { + // One dynamic offset per dynamic descriptor to offset into the ubo containing all model matrices + uint32_t dynamicOffset = j * static_cast(dynamicAlignment); + // Bind the descriptor set for rendering a mesh using the dynamic offset + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 1, &dynamicOffset); + + vkCmdDrawIndexed(drawCmdBuffers[i], indexCount, 1, 0, 0, 0); + } + + vkCmdEndRenderPass(drawCmdBuffers[i]); + + VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); + } + } + + void draw() + { + VulkanExampleBase::prepareFrame(); + + // Command buffer to be sumitted to the queue + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; + + // Submit to queue + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); + + VulkanExampleBase::submitFrame(); + } + + void generateTriangle() + { + // Setup vertices indices for a colored cube + std::vector vertices = { + { { -1.0f, -1.0f, 1.0f },{ 1.0f, 0.0f, 0.0f } }, + { { 1.0f, -1.0f, 1.0f },{ 0.0f, 1.0f, 0.0f } }, + { { 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, 1.0f } }, + { { -1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f, 0.0f } }, + { { -1.0f, -1.0f, -1.0f },{ 1.0f, 0.0f, 0.0f } }, + { { 1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f, 0.0f } }, + { { 1.0f, 1.0f, -1.0f },{ 0.0f, 0.0f, 1.0f } }, + { { -1.0f, 1.0f, -1.0f },{ 0.0f, 0.0f, 0.0f } }, + }; + + std::vector indices = { + 0,1,2, 2,3,0, 1,5,6, 6,2,1, 7,6,5, 5,4,7, 4,0,3, 3,7,4, 4,5,1, 1,0,4, 3,2,6, 6,7,3, + }; + + indexCount = static_cast(indices.size()); + + // Create buffers + // For the sake of simplicity we won't stage the vertex data to the gpu memory + // Vertex buffer + 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())); + // Index buffer + 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())); + } + + void setupVertexDescriptions() + { + // Binding description + vertices.bindingDescriptions = { + vkTools::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX), + }; + + // Attribute descriptions + vertices.attributeDescriptions = { + vkTools::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos)), // Location 0 : Position + vkTools::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, color)), // Location 1 : Color + }; + + vertices.inputState = vkTools::initializers::pipelineVertexInputStateCreateInfo(); + vertices.inputState.vertexBindingDescriptionCount = static_cast(vertices.bindingDescriptions.size()); + vertices.inputState.pVertexBindingDescriptions = vertices.bindingDescriptions.data(); + vertices.inputState.vertexAttributeDescriptionCount = static_cast(vertices.attributeDescriptions.size()); + vertices.inputState.pVertexAttributeDescriptions = vertices.attributeDescriptions.data(); + } + + void setupDescriptorPool() + { + // Example uses one ubo and one image sampler + std::vector poolSizes = + { + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1), + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1) + }; + + VkDescriptorPoolCreateInfo descriptorPoolInfo = + vkTools::initializers::descriptorPoolCreateInfo( + static_cast(poolSizes.size()), + poolSizes.data(), + 2); + + VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); + } + + void setupDescriptorSetLayout() + { + std::vector setLayoutBindings = + { + vkTools::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), + vkTools::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_SHADER_STAGE_VERTEX_BIT, 1), + vkTools::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 2) + }; + + VkDescriptorSetLayoutCreateInfo descriptorLayout = + vkTools::initializers::descriptorSetLayoutCreateInfo( + setLayoutBindings.data(), + static_cast(setLayoutBindings.size())); + + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); + + VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = + vkTools::initializers::pipelineLayoutCreateInfo( + &descriptorSetLayout, + 1); + + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); + } + + void setupDescriptorSet() + { + VkDescriptorSetAllocateInfo allocInfo = + vkTools::initializers::descriptorSetAllocateInfo( + descriptorPool, + &descriptorSetLayout, + 1); + + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); + + std::vector writeDescriptorSets = { + // Binding 0 : Projection/View matrix uniform buffer + vkTools::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.view.descriptor), + // Binding 1 : Instance matrix as dynamic uniform buffer + vkTools::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, &uniformBuffers.dynamic.descriptor), + }; + + vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL); + } + + void preparePipelines() + { + VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = + vkTools::initializers::pipelineInputAssemblyStateCreateInfo( + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + 0, + VK_FALSE); + + VkPipelineRasterizationStateCreateInfo rasterizationState = + vkTools::initializers::pipelineRasterizationStateCreateInfo( + VK_POLYGON_MODE_FILL, + VK_CULL_MODE_NONE, + VK_FRONT_FACE_COUNTER_CLOCKWISE, + 0); + + VkPipelineColorBlendAttachmentState blendAttachmentState = + vkTools::initializers::pipelineColorBlendAttachmentState( + 0xf, + VK_FALSE); + + VkPipelineColorBlendStateCreateInfo colorBlendState = + vkTools::initializers::pipelineColorBlendStateCreateInfo( + 1, + &blendAttachmentState); + + VkPipelineDepthStencilStateCreateInfo depthStencilState = + vkTools::initializers::pipelineDepthStencilStateCreateInfo( + VK_TRUE, + VK_TRUE, + VK_COMPARE_OP_LESS_OR_EQUAL); + + VkPipelineViewportStateCreateInfo viewportState = + vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0); + + VkPipelineMultisampleStateCreateInfo multisampleState = + vkTools::initializers::pipelineMultisampleStateCreateInfo( + VK_SAMPLE_COUNT_1_BIT, + 0); + + std::vector dynamicStateEnables = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR + }; + VkPipelineDynamicStateCreateInfo dynamicState = + vkTools::initializers::pipelineDynamicStateCreateInfo( + dynamicStateEnables.data(), + static_cast(dynamicStateEnables.size()), + 0); + + // Load shaders + std::array shaderStages; + + shaderStages[0] = loadShader(getAssetPath() + "shaders/dynamicuniformbuffer/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaderStages[1] = loadShader(getAssetPath() + "shaders/dynamicuniformbuffer/base.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + + VkGraphicsPipelineCreateInfo pipelineCreateInfo = + vkTools::initializers::pipelineCreateInfo( + pipelineLayout, + renderPass, + 0); + + pipelineCreateInfo.pVertexInputState = &vertices.inputState; + pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; + pipelineCreateInfo.pRasterizationState = &rasterizationState; + pipelineCreateInfo.pColorBlendState = &colorBlendState; + pipelineCreateInfo.pMultisampleState = &multisampleState; + pipelineCreateInfo.pViewportState = &viewportState; + pipelineCreateInfo.pDepthStencilState = &depthStencilState; + pipelineCreateInfo.pDynamicState = &dynamicState; + pipelineCreateInfo.stageCount = static_cast(shaderStages.size()); + pipelineCreateInfo.pStages = shaderStages.data(); + + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); + } + + // Prepare and initialize uniform buffer containing shader uniforms + void prepareUniformBuffers() + { + // Allocate data for the dynamic uniform buffer object + // We allocate this manually as the alignment of the offset differs between GPUs + + // Calculate required alignment depending on device limits + uint32_t uboAlignment = vulkanDevice->properties.limits.minUniformBufferOffsetAlignment; + dynamicAlignment = (sizeof(glm::mat4) / uboAlignment) * uboAlignment + ((sizeof(glm::mat4) % uboAlignment) > 0 ? uboAlignment : 0); + + size_t bufferSize = OBJECT_INSTANCES * dynamicAlignment; + + //todo: _algined_malloc only windows + uboDataDynamic.model = (glm::mat4*)_aligned_malloc(bufferSize, dynamicAlignment); + + std::cout << "minUniformBufferOffsetAlignment = " << uboAlignment << std::endl; + std::cout << "dynamicAlignment = " << dynamicAlignment << std::endl; + + // Vertex shader uniform buffer block + + // Static shared uniform buffer object with projection and view matrix + VK_CHECK_RESULT(vulkanDevice->createBuffer( + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &uniformBuffers.view, + sizeof(uboVS))); + + // Uniform buffer object with per-object matrices + VK_CHECK_RESULT(vulkanDevice->createBuffer( + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + &uniformBuffers.dynamic, + bufferSize)); + + // Map persistent + VK_CHECK_RESULT(uniformBuffers.view.map()); + VK_CHECK_RESULT(uniformBuffers.dynamic.map()); + + // Prepare per-object matrices with offsets and random rotations + std::mt19937 rndGen(static_cast(time(0))); + std::normal_distribution rndDist(-1.0f, 1.0f); + for (uint32_t i = 0; i < OBJECT_INSTANCES; i++) + { + rotations[i] = glm::vec3(rndDist(rndGen), rndDist(rndGen), rndDist(rndGen)) * 2.0f * (float)M_PI; + rotationSpeeds[i] = glm::vec3(rndDist(rndGen), rndDist(rndGen), rndDist(rndGen)); + } + + updateUniformBuffers(); + updateDynamicUniformBuffer(true); + } + + void updateUniformBuffers() + { + // Fixed ubo with projection and view matrices + uboVS.projection = camera.matrices.perspective; + uboVS.view = camera.matrices.view; + + memcpy(uniformBuffers.view.mapped, &uboVS, sizeof(uboVS)); + } + + void updateDynamicUniformBuffer(bool force = false) + { + // Update at max. 60 fps + animationTimer += frameTimer; + if ((animationTimer <= 1.0f / 60.0f) && (!force)) { + return; + } + + // Dynamic ubo with per-object model matrices indexed by offsets in the command buffer + uint32_t dim = pow(OBJECT_INSTANCES, (1.0 / 3.0)); + glm::vec3 offset(5.0f); + + for (uint32_t x = 0; x < dim; x++) + { + for (uint32_t y = 0; y < dim; y++) + { + for (uint32_t z = 0; z < dim; z++) + { + uint32_t index = x * dim * dim + y * dim + z; + + // Aligned offset + glm::mat4* modelMat = (glm::mat4*)(((uint64_t)uboDataDynamic.model + (index * dynamicAlignment))); + + // Update rotations + rotations[index] += animationTimer * rotationSpeeds[index]; + + // Update matrices + glm::vec3 pos = glm::vec3(-((dim * offset.x) / 2.0f) + offset.x / 2.0f + x * offset.x, -((dim * offset.y) / 2.0f) + offset.y / 2.0f + y * offset.y, -((dim * offset.z) / 2.0f) + offset.z / 2.0f + z * offset.z); + *modelMat = glm::translate(glm::mat4(), pos); + *modelMat = glm::rotate(*modelMat, rotations[index].x, glm::vec3(1.0f, 1.0f, 0.0f)); + *modelMat = glm::rotate(*modelMat, rotations[index].y, glm::vec3(0.0f, 1.0f, 0.0f)); + *modelMat = glm::rotate(*modelMat, rotations[index].z, glm::vec3(0.0f, 0.0f, 1.0f)); + } + } + } + + animationTimer = 0.0f; + + memcpy(uniformBuffers.dynamic.mapped, uboDataDynamic.model, uniformBuffers.dynamic.size); + // Flush to make changes visible to the host + VkMappedMemoryRange memoryRange = vkTools::initializers::mappedMemoryRange(); + memoryRange.memory = uniformBuffers.dynamic.memory; + memoryRange.size = sizeof(uboDataDynamic); + vkFlushMappedMemoryRanges(device, 1, &memoryRange); + } + + void prepare() + { + VulkanExampleBase::prepare(); + generateTriangle(); + setupVertexDescriptions(); + prepareUniformBuffers(); + setupDescriptorSetLayout(); + preparePipelines(); + setupDescriptorPool(); + setupDescriptorSet(); + buildCommandBuffers(); + prepared = true; + } + + virtual void render() + { + if (!prepared) + return; + draw(); + if (!paused) + updateDynamicUniformBuffer(); + } + + virtual void viewChanged() + { + updateUniformBuffers(); + } +}; + +VULKAN_EXAMPLE_MAIN() diff --git a/dynamicuniformbuffer/dynamicuniformbuffer.vcxproj b/dynamicuniformbuffer/dynamicuniformbuffer.vcxproj new file mode 100644 index 00000000..fd1a46b6 --- /dev/null +++ b/dynamicuniformbuffer/dynamicuniformbuffer.vcxproj @@ -0,0 +1,99 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {3DB2A9C4-50BC-4390-A94F-F7F724238101} + Win32Proj + 8.1 + + + + Application + true + v140 + + + Application + false + v140 + + + + + + + + + + + + + true + $(SolutionDir)\bin\ + $(SolutionDir)\bin\intermediate\$(ProjectName)\$(ConfigurationName) + + + true + $(SolutionDir)\bin\ + $(SolutionDir)\bin\intermediate\$(ProjectName)\$(ConfigurationName) + + + + WIN32;_DEBUG;_WINDOWS;VK_USE_PLATFORM_WIN32_KHR;_USE_MATH_DEFINES;NOMINMAX;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + ..\base;..\external\glm;..\external\gli;..\external\assimp;..\external;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + true + Windows + ..\libs\vulkan\vulkan-1.lib;..\libs\assimp\assimp.lib;%(AdditionalDependencies) + + + + + WIN32;NDEBUG;_WINDOWS;VK_USE_PLATFORM_WIN32_KHR;_USE_MATH_DEFINES;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + ..\base;..\external\glm;..\external\gli;..\external\assimp;..\external;%(AdditionalIncludeDirectories) + + + true + Windows + true + true + ..\libs\vulkan\vulkan-1.lib;..\libs\assimp\assimp.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dynamicuniformbuffer/dynamicuniformbuffer.vcxproj.filters b/dynamicuniformbuffer/dynamicuniformbuffer.vcxproj.filters new file mode 100644 index 00000000..1fb03458 --- /dev/null +++ b/dynamicuniformbuffer/dynamicuniformbuffer.vcxproj.filters @@ -0,0 +1,53 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {63dc9158-9a3b-41c0-9e79-70fa1772be4c} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Shaders + + + Shaders + + + \ No newline at end of file diff --git a/vulkanExamples.sln b/vulkanExamples.sln index 2afb7793..246bf836 100644 --- a/vulkanExamples.sln +++ b/vulkanExamples.sln @@ -130,6 +130,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "screenshot", "screenshot\screenshot.vcxproj", "{AD1DAD4D-A753-4A78-88E2-B4DCE15D482F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamicuniformbuffer", "dynamicuniformbuffer\dynamicuniformbuffer.vcxproj", "{3DB2A9C4-50BC-4390-A94F-F7F724238101}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -316,6 +318,10 @@ Global {AD1DAD4D-A753-4A78-88E2-B4DCE15D482F}.Debug|x64.Build.0 = Debug|x64 {AD1DAD4D-A753-4A78-88E2-B4DCE15D482F}.Release|x64.ActiveCfg = Release|x64 {AD1DAD4D-A753-4A78-88E2-B4DCE15D482F}.Release|x64.Build.0 = Release|x64 + {3DB2A9C4-50BC-4390-A94F-F7F724238101}.Debug|x64.ActiveCfg = Debug|x64 + {3DB2A9C4-50BC-4390-A94F-F7F724238101}.Debug|x64.Build.0 = Debug|x64 + {3DB2A9C4-50BC-4390-A94F-F7F724238101}.Release|x64.ActiveCfg = Release|x64 + {3DB2A9C4-50BC-4390-A94F-F7F724238101}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE