From b7c25fc41f1fe7483b7e3b7570c32caa4fc64274 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 15 Apr 2026 22:43:59 -0500 Subject: [PATCH] collada: draw scene textures --- filenames.txt | 4 - include/collada/scene/vulkan.h | 25 +- shader/collada.hlsl | 42 ++- src/collada/scene.cpp | 4 +- src/collada/scene/vulkan.cpp | 126 ++++++--- src/main.cpp | 494 --------------------------------- 6 files changed, 139 insertions(+), 556 deletions(-) diff --git a/filenames.txt b/filenames.txt index 9c62972..74ed75f 100644 --- a/filenames.txt +++ b/filenames.txt @@ -1,8 +1,4 @@ -shader/triangle.spv shader/collada.spv data/scenes/shadow_test/shadow_test.vtx data/scenes/shadow_test/shadow_test.idx data/scenes/shadow_test/images/0_leaf_white.dds -checker.idx -checker.vtx -sprite.data diff --git a/include/collada/scene/vulkan.h b/include/collada/scene/vulkan.h index af05627..33e4930 100644 --- a/include/collada/scene/vulkan.h +++ b/include/collada/scene/vulkan.h @@ -24,6 +24,16 @@ namespace collada::scene { XMFLOAT4 diffuse; XMFLOAT4 specular; }; + struct MaterialImage { + int emission; + int ambient; + int diffuse; + int specular; + }; + struct MaterialColorImage { + MaterialColor color; + MaterialImage image; + }; struct PushConstant { int nodeIndex; int materialIndex; @@ -34,7 +44,8 @@ namespace collada::scene { static constexpr uint32_t perFrameDescriptorCount = 2; static constexpr uint32_t constantDescriptorCount = 1; static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount; - static constexpr uint32_t descriptorCount = uniformBufferDescriptorCount + 2; + // +3: linear sampler, shadow sampled image, scene sampled image (array) + static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 3; // externally initialized, opaque handle VkInstance instance; @@ -79,7 +90,7 @@ namespace collada::scene { struct { Scene scene; // global(?) Node * nodes; // per-scene - MaterialColor * materialColors; // per-scene + MaterialColorImage * materialColorImages; // per-scene } shaderData; struct { VkDeviceMemory memory; @@ -97,10 +108,10 @@ namespace collada::scene { void * nodesMapped; } frame[maxFrames]; struct { // must match constantDescriptorCount - VkBuffer materialColorsBuffer; - VkDeviceAddress materialColorsOffset; - VkDeviceAddress materialColorsSize; - void * materialColorsMapped; + VkBuffer materialColorImagesBuffer; + VkDeviceAddress materialColorImagesOffset; + VkDeviceAddress materialColorImagesSize; + void * materialColorImagesMapped; } constant; } shaderDataDevice; @@ -143,7 +154,7 @@ namespace collada::scene { void create_pipelines(collada::types::descriptor const * const descriptor); void create_uniform_buffers(collada::types::descriptor const * const descriptor); - void create_descriptor_sets(); + void create_descriptor_sets(collada::types::descriptor const * const descriptor); void write_descriptor_sets(collada::types::descriptor const * const descriptor); void load_material_constants(collada::types::descriptor const * const descriptor); void load_images(collada::types::descriptor const * const descriptor); diff --git a/shader/collada.hlsl b/shader/collada.hlsl index 42ac1b4..0aaad50 100644 --- a/shader/collada.hlsl +++ b/shader/collada.hlsl @@ -35,22 +35,35 @@ struct Scene float4 LightPosition; // view space }; -struct MaterialColor -{ +struct MaterialImage { + int Emission; + int Ambient; + int Diffuse; + int Specular; +}; + +struct MaterialColor { float4 Emission; float4 Ambient; float4 Diffuse; float4 Specular; }; +struct MaterialColorImage +{ + MaterialColor Color; + MaterialImage Image; +}; + // set 0: per-frame [[vk::binding(0, 0)]] ConstantBuffer Scene; [[vk::binding(1, 0)]] StructuredBuffer Nodes; // set 1: constant -[[vk::binding(0, 1)]] StructuredBuffer MaterialColors; +[[vk::binding(0, 1)]] StructuredBuffer MaterialColorImages; [[vk::binding(1, 1)]] SamplerState LinearSampler; [[vk::binding(2, 1)]] Texture2D ShadowTexture; +[[vk::binding(3, 1)]] Texture2D SceneTexture[]; struct PushConstant { int NodeIndex; @@ -116,10 +129,25 @@ float ShadowPCF(float3 position, float bias) [shader("pixel")] float4 PSMain(VSOutput input) : SV_TARGET { - //float3 color = texture.Sample(samplers[0], input.Texture).bgr; - float4 diffuseColor = MaterialColors[constants.MaterialIndex].Diffuse; - float4 specularColor = MaterialColors[constants.MaterialIndex].Specular; - float4 emissionColor = MaterialColors[constants.MaterialIndex].Emission; + MaterialColorImage MCI = MaterialColorImages[constants.MaterialIndex]; + float4 diffuseColor; + float4 specularColor; + float4 emissionColor; + if (MCI.Image.Diffuse >= 0) { + diffuseColor = SceneTexture[MCI.Image.Diffuse].Sample(LinearSampler, input.Texture).bgra; + } else { + diffuseColor = MCI.Color.Diffuse; + } + if (MCI.Image.Specular >= 0) { + specularColor = SceneTexture[MCI.Image.Specular].Sample(LinearSampler, input.Texture).bgra; + } else { + specularColor = MCI.Color.Specular; + } + if (MCI.Image.Emission >= 0) { + emissionColor = SceneTexture[MCI.Image.Emission].Sample(LinearSampler, input.Texture).bgra; + } else { + emissionColor = MCI.Color.Emission; + } float3 N = normalize(input.Normal); float3 L = normalize(input.LightDirection); diff --git a/src/collada/scene.cpp b/src/collada/scene.cpp index 6500f59..b5be9ce 100644 --- a/src/collada/scene.cpp +++ b/src/collada/scene.cpp @@ -14,10 +14,10 @@ namespace collada::scene { vulkan.load_vertex_index_buffer(descriptor->position_normal_texture_buffer, descriptor->index_buffer); vulkan.create_uniform_buffers(descriptor); - vulkan.create_descriptor_sets(); - vulkan.write_descriptor_sets(descriptor); + vulkan.create_descriptor_sets(descriptor); vulkan.load_material_constants(descriptor); vulkan.load_images(descriptor); + vulkan.write_descriptor_sets(descriptor); vulkan.create_pipelines(descriptor); node_state.allocate_node_instances(descriptor->nodes, descriptor->nodes_count); diff --git a/src/collada/scene/vulkan.cpp b/src/collada/scene/vulkan.cpp index 48781b7..c595a4f 100644 --- a/src/collada/scene/vulkan.cpp +++ b/src/collada/scene/vulkan.cpp @@ -204,7 +204,7 @@ namespace collada::scene { VkDeviceSize offsets[uniformBufferDescriptorCount]; shaderData.nodes = NewM(descriptor->nodes_count); - shaderData.materialColors = NewM(descriptor->materials_count); + shaderData.materialColorImages = NewM(descriptor->materials_count); uint32_t memoryRequirementsIndex = 0; // per-frame @@ -232,14 +232,14 @@ namespace collada::scene { }; // material color buffer - VkBufferCreateInfo materialColorsBufferCreateInfo{ + VkBufferCreateInfo materialColorImagesBufferCreateInfo{ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = (sizeof (MaterialColor)) * descriptor->materials_count, + .size = (sizeof (MaterialColorImage)) * descriptor->materials_count, .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, .sharingMode = VK_SHARING_MODE_EXCLUSIVE }; - VK_CHECK(vkCreateBuffer(device, &materialColorsBufferCreateInfo, nullptr, &shaderDataDevice.constant.materialColorsBuffer)); - vkGetBufferMemoryRequirements(device, shaderDataDevice.constant.materialColorsBuffer, &memoryRequirements[memoryRequirementsIndex++]); + VK_CHECK(vkCreateBuffer(device, &materialColorImagesBufferCreateInfo, nullptr, &shaderDataDevice.constant.materialColorImagesBuffer)); + vkGetBufferMemoryRequirements(device, shaderDataDevice.constant.materialColorImagesBuffer, &memoryRequirements[memoryRequirementsIndex++]); assert(memoryRequirementsIndex == uniformBufferDescriptorCount); @@ -273,10 +273,10 @@ namespace collada::scene { shaderDataDevice.frame[i].nodesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.frame[i].nodesOffset); VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].nodesBuffer, shaderDataDevice.memory, shaderDataDevice.frame[i].nodesOffset)); } - shaderDataDevice.constant.materialColorsOffset = offsets[offsetsIndex]; - shaderDataDevice.constant.materialColorsSize = memoryRequirements[offsetsIndex++].size; - shaderDataDevice.constant.materialColorsMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.constant.materialColorsOffset); - VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.constant.materialColorsBuffer, shaderDataDevice.memory, shaderDataDevice.constant.materialColorsOffset)); + shaderDataDevice.constant.materialColorImagesOffset = offsets[offsetsIndex]; + shaderDataDevice.constant.materialColorImagesSize = memoryRequirements[offsetsIndex++].size; + shaderDataDevice.constant.materialColorImagesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.constant.materialColorImagesOffset); + VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.constant.materialColorImagesBuffer, shaderDataDevice.memory, shaderDataDevice.constant.materialColorImagesOffset)); assert(offsetsIndex == uniformBufferDescriptorCount); } @@ -285,7 +285,7 @@ namespace collada::scene { // descriptor sets ////////////////////////////////////////////////////////////////////// - void vulkan::create_descriptor_sets() + void vulkan::create_descriptor_sets(collada::types::descriptor const * const descriptor) { // // pool @@ -294,11 +294,11 @@ namespace collada::scene { VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{ { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = maxFrames + 1, // why +1? + .descriptorCount = maxFrames, }, { .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = maxFrames + 1, // +1 for materialColors + .descriptorCount = maxFrames + 1, // +1 for materialColorImages }, { .type = VK_DESCRIPTOR_TYPE_SAMPLER, @@ -306,7 +306,7 @@ namespace collada::scene { }, { .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, + .descriptorCount = (uint32_t)descriptor->images_count + 1, // +1 for shadow sampler }, }; VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{ @@ -362,7 +362,7 @@ namespace collada::scene { // uniform buffer descriptor set layout/allocation (set 1, constant) // { - constexpr int bindingCount = 3; + constexpr int bindingCount = 4; VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{ { .binding = 0, @@ -376,11 +376,17 @@ namespace collada::scene { .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT }, - { + { // shadow sampled image .binding = 2, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT + }, + { // scene images + .binding = 3, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = (uint32_t)descriptor->images_count, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT } }; @@ -407,7 +413,7 @@ namespace collada::scene { void vulkan::write_descriptor_sets(collada::types::descriptor const * const descriptor) { - VkWriteDescriptorSet writeDescriptorSets[descriptorCount]; + VkWriteDescriptorSet writeDescriptorSets[bindingCount]; uint32_t writeIndex = 0; VkDescriptorBufferInfo sceneDescriptorBufferInfos[maxFrames]; @@ -442,10 +448,10 @@ namespace collada::scene { }; } - VkDescriptorBufferInfo materialColorsDescriptorBufferInfo{ - .buffer = shaderDataDevice.constant.materialColorsBuffer, + VkDescriptorBufferInfo materialColorImagesDescriptorBufferInfo{ + .buffer = shaderDataDevice.constant.materialColorImagesBuffer, .offset = 0, - .range = shaderDataDevice.constant.materialColorsSize, + .range = shaderDataDevice.constant.materialColorImagesSize, }; writeDescriptorSets[writeIndex++] = { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, @@ -453,7 +459,7 @@ namespace collada::scene { .dstBinding = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .pBufferInfo = &materialColorsDescriptorBufferInfo + .pBufferInfo = &materialColorImagesDescriptorBufferInfo }; VkDescriptorImageInfo samplerDescriptorImageInfo = { .sampler = linearSampler, @@ -479,9 +485,27 @@ namespace collada::scene { .pImageInfo = &sampledImageDescriptorImageInfo }; - assert(writeIndex == descriptorCount); + // scene images + VkDescriptorImageInfo * sceneDescriptorImageInfos = NewM(descriptor->images_count); + for (int i = 0; i < descriptor->images_count; i++) { + sceneDescriptorImageInfos[i] = { + .imageView = images[i].imageView, + .imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL + }; + } + writeDescriptorSets[writeIndex++] = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet1, + .dstBinding = 3, + .descriptorCount = (uint32_t)descriptor->images_count, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .pImageInfo = sceneDescriptorImageInfos + }; + + assert(writeIndex == bindingCount); vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr); + free(sceneDescriptorImageInfos); } ////////////////////////////////////////////////////////////////////// @@ -490,33 +514,51 @@ namespace collada::scene { void vulkan::load_material_constants(collada::types::descriptor const * const descriptor) { + constexpr collada::types::color_or_texture_type TEXTURE = collada::types::color_or_texture_type::TEXTURE; // store for (int i = 0; i < descriptor->materials_count; i++) { collada::types::effect const * const effect = descriptor->materials[i]->effect; + MaterialColorImage & mci = shaderData.materialColorImages[i]; switch (effect->type) { case collada::types::effect_type::BLINN: - shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->blinn.emission.color); - shaderData.materialColors[i].ambient = *(XMFLOAT4 *)(&effect->blinn.ambient.color); - shaderData.materialColors[i].diffuse = *(XMFLOAT4 *)(&effect->blinn.diffuse.color); - shaderData.materialColors[i].specular = *(XMFLOAT4 *)(&effect->blinn.specular.color); + mci.color.emission = *(XMFLOAT4 *)(&effect->blinn.emission.color); + mci.color.ambient = *(XMFLOAT4 *)(&effect->blinn.ambient.color); + mci.color.diffuse = *(XMFLOAT4 *)(&effect->blinn.diffuse.color); + mci.color.specular = *(XMFLOAT4 *)(&effect->blinn.specular.color); + mci.image.emission = (effect->blinn.emission.type == TEXTURE) ? effect->blinn.emission.texture.image_index : -1; + mci.image.ambient = (effect->blinn.ambient.type == TEXTURE) ? effect->blinn.ambient.texture.image_index : -1; + mci.image.diffuse = (effect->blinn.diffuse.type == TEXTURE) ? effect->blinn.diffuse.texture.image_index : -1; + mci.image.specular = (effect->blinn.specular.type == TEXTURE) ? effect->blinn.specular.texture.image_index : -1; break; case collada::types::effect_type::LAMBERT: - shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->lambert.emission.color); - shaderData.materialColors[i].ambient = *(XMFLOAT4 *)(&effect->lambert.ambient.color); - shaderData.materialColors[i].diffuse = *(XMFLOAT4 *)(&effect->lambert.diffuse.color); - shaderData.materialColors[i].specular = XMFLOAT4{0, 0, 0, 0}; + mci.color.emission = *(XMFLOAT4 *)(&effect->lambert.emission.color); + mci.color.ambient = *(XMFLOAT4 *)(&effect->lambert.ambient.color); + mci.color.diffuse = *(XMFLOAT4 *)(&effect->lambert.diffuse.color); + mci.color.specular = XMFLOAT4{0, 0, 0, 0}; + mci.image.emission = (effect->lambert.emission.type == TEXTURE) ? effect->lambert.emission.texture.image_index : -1; + mci.image.ambient = (effect->lambert.ambient.type == TEXTURE) ? effect->lambert.ambient.texture.image_index : -1; + mci.image.diffuse = (effect->lambert.diffuse.type == TEXTURE) ? effect->lambert.diffuse.texture.image_index : -1; + mci.image.specular = -1; break; case collada::types::effect_type::PHONG: - shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->phong.emission.color); - shaderData.materialColors[i].ambient = *(XMFLOAT4 *)(&effect->phong.ambient.color); - shaderData.materialColors[i].diffuse = *(XMFLOAT4 *)(&effect->phong.diffuse.color); - shaderData.materialColors[i].specular = *(XMFLOAT4 *)(&effect->phong.specular.color); + mci.color.emission = *(XMFLOAT4 *)(&effect->phong.emission.color); + mci.color.ambient = *(XMFLOAT4 *)(&effect->phong.ambient.color); + mci.color.diffuse = *(XMFLOAT4 *)(&effect->phong.diffuse.color); + mci.color.specular = *(XMFLOAT4 *)(&effect->phong.specular.color); + mci.image.emission = (effect->phong.emission.type == TEXTURE) ? effect->phong.emission.texture.image_index : -1; + mci.image.ambient = (effect->phong.ambient.type == TEXTURE) ? effect->phong.ambient.texture.image_index : -1; + mci.image.diffuse = (effect->phong.diffuse.type == TEXTURE) ? effect->phong.diffuse.texture.image_index : -1; + mci.image.specular = (effect->phong.specular.type == TEXTURE) ? effect->phong.specular.texture.image_index : -1; break; case collada::types::effect_type::CONSTANT: - shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->constant.color); - shaderData.materialColors[i].ambient = XMFLOAT4{0, 0, 0, 0}; - shaderData.materialColors[i].diffuse = XMFLOAT4{0, 0, 0, 0}; - shaderData.materialColors[i].specular = XMFLOAT4{0, 0, 0, 0}; + mci.color.emission = *(XMFLOAT4 *)(&effect->constant.color); + mci.color.ambient = XMFLOAT4{0, 0, 0, 0}; + mci.color.diffuse = XMFLOAT4{0, 0, 0, 0}; + mci.color.specular = XMFLOAT4{0, 0, 0, 0}; + mci.image.emission = -1; + mci.image.ambient = -1; + mci.image.diffuse = -1; + mci.image.specular = -1; break; default: assert(false); @@ -525,7 +567,7 @@ namespace collada::scene { } // copy - memcpy(shaderDataDevice.constant.materialColorsMapped, &shaderData.materialColors[0], (sizeof (MaterialColor)) * descriptor->materials_count); + memcpy(shaderDataDevice.constant.materialColorImagesMapped, &shaderData.materialColorImages[0], (sizeof (MaterialColorImage)) * descriptor->materials_count); // flush @@ -533,8 +575,8 @@ namespace collada::scene { { .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, .memory = shaderDataDevice.memory, - .offset = shaderDataDevice.constant.materialColorsOffset, - .size = shaderDataDevice.constant.materialColorsSize, + .offset = shaderDataDevice.constant.materialColorImagesOffset, + .size = shaderDataDevice.constant.materialColorImagesSize, }, }; alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize, @@ -925,7 +967,7 @@ namespace collada::scene { free(images); free(shaderData.nodes); - free(shaderData.materialColors); + free(shaderData.materialColorImages); vkDestroyBuffer(device, vertexIndex.buffer, nullptr); vkFreeMemory(device, vertexIndex.memory, nullptr); @@ -934,7 +976,7 @@ namespace collada::scene { vkDestroyBuffer(device, shaderDataDevice.frame[i].sceneBuffer, nullptr); vkDestroyBuffer(device, shaderDataDevice.frame[i].nodesBuffer, nullptr); } - vkDestroyBuffer(device, shaderDataDevice.constant.materialColorsBuffer, nullptr); + vkDestroyBuffer(device, shaderDataDevice.constant.materialColorImagesBuffer, nullptr); vkFreeMemory(device, shaderDataDevice.memory, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayouts[0], nullptr); diff --git a/src/main.cpp b/src/main.cpp index 5d603b9..6db276c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,11 +39,6 @@ VkImageView shadowDepthImageView{ VK_NULL_HANDLE }; VkImageView shadowDepthImageViewDepth{ VK_NULL_HANDLE }; VkDeviceMemory shadowDepthMemory{ VK_NULL_HANDLE }; -VkBuffer vertexIndexBuffer{ VK_NULL_HANDLE }; -VkDeviceMemory vertexIndexBufferMemory{ VK_NULL_HANDLE }; -VkDeviceSize vertexBufferSize{ 0 }; -VkDeviceSize indexBufferSize{ 0 }; - VkFence fences[maxFramesInFlight]; VkSemaphore presentSemaphores[maxFramesInFlight]; VkSemaphore * renderSemaphores{ nullptr }; @@ -51,30 +46,12 @@ VkSemaphore * renderSemaphores{ nullptr }; VkCommandPool commandPool{ VK_NULL_HANDLE }; VkCommandBuffer commandBuffers[maxFramesInFlight]; -enum { - MAIN_PIPELINE = 0, - OUTLINE_PIPELINE = 1, -}; - -VkPipeline pipelines[2]{ VK_NULL_HANDLE, VK_NULL_HANDLE }; -VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE }; - -VkImage textureImage{ VK_NULL_HANDLE }; -VkImageView textureImageView{ VK_NULL_HANDLE }; -VkDeviceMemory textureImageMemory{ VK_NULL_HANDLE }; VkSampler textureSamplers[3]{ VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE }; VkDescriptorPool descriptorPool{ VK_NULL_HANDLE }; -VkDescriptorSetLayout uniformBufferDescriptorSetLayout{ VK_NULL_HANDLE }; -VkDescriptorSet uniformBufferDescriptorSets[maxFramesInFlight]; -VkDescriptorSetLayout textureDescriptorSetLayout{ VK_NULL_HANDLE }; -VkDescriptorSet textureDescriptorSet{ VK_NULL_HANDLE }; XMINT2 windowSize{}; -ShaderData shaderData{}; -ShaderDataDevice shaderDataDevice{}; - void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags) { int index = 0; @@ -517,102 +494,6 @@ int main() }; VK_CHECK(vkCreateImageView(device, &imageViewCreateInfo, nullptr, &shadowDepthImageViewDepth)); - ////////////////////////////////////////////////////////////////////// - // mesh - ////////////////////////////////////////////////////////////////////// - - { - uint32_t vertexSize; - void const * vertexStart = file::open("checker.vtx", &vertexSize); - uint32_t indexSize; - void const * indexStart = file::open("checker.idx", &indexSize); - vertexBufferSize = vertexSize; - indexBufferSize = indexSize; - - VkDeviceSize bufferSize{ vertexSize + indexSize }; - VkBufferCreateInfo vertexIndexBufferCreateInfo{ - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = bufferSize, - .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE - }; - VK_CHECK(vkCreateBuffer(device, &vertexIndexBufferCreateInfo, nullptr, &vertexIndexBuffer)); - - VkMemoryRequirements memoryRequirements; - vkGetBufferMemoryRequirements(device, vertexIndexBuffer, &memoryRequirements); - VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT }; - VkMemoryAllocateFlags memoryAllocateFlags{}; - VkDeviceSize stride; - allocateFromMemoryRequirements(device, - physicalDeviceProperties.limits.nonCoherentAtomSize, - physicalDeviceMemoryProperties, - memoryRequirements, - memoryPropertyFlags, - memoryAllocateFlags, - 1, - &vertexIndexBufferMemory, - &stride); - VK_CHECK(vkBindBufferMemory(device, vertexIndexBuffer, vertexIndexBufferMemory, 0)); - - void * vertexIndexMappedData; - VK_CHECK(vkMapMemory(device, vertexIndexBufferMemory, 0, VK_WHOLE_SIZE, 0, &vertexIndexMappedData)); - memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize); - memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize); - - VkMappedMemoryRange mappedMemoryRange{ - .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, - .memory = vertexIndexBufferMemory, - .offset = 0, - .size = VK_WHOLE_SIZE, - }; - vkFlushMappedMemoryRanges(device, 1, &mappedMemoryRange); - - vkUnmapMemory(device, vertexIndexBufferMemory); - } - - ////////////////////////////////////////////////////////////////////// - // shader buffers - ////////////////////////////////////////////////////////////////////// - - { - for (uint32_t i = 0; i < maxFramesInFlight; i++) { - VkBufferCreateInfo bufferCreateInfo{ - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = (sizeof (ShaderData)), - .usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE - }; - - VK_CHECK(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &shaderDataDevice.frame[i].buffer)); - } - - VkMemoryRequirements memoryRequirements; - vkGetBufferMemoryRequirements(device, shaderDataDevice.frame[0].buffer, &memoryRequirements); - - VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT }; - VkMemoryAllocateFlags memoryAllocateFlags{ }; - allocateFromMemoryRequirements(device, - physicalDeviceProperties.limits.nonCoherentAtomSize, - physicalDeviceMemoryProperties, - memoryRequirements, - memoryPropertyFlags, - memoryAllocateFlags, - maxFramesInFlight, - &shaderDataDevice.memory, - &shaderDataDevice.stride); - - VkDeviceSize offset{ 0 }; - VkDeviceSize size{ VK_WHOLE_SIZE }; - VkMemoryMapFlags flags{ 0 }; - VK_CHECK(vkMapMemory(device, shaderDataDevice.memory, offset, size, flags, &shaderDataDevice.mappedData)); - - for (uint32_t i = 0; i < maxFramesInFlight; i++) { - VkDeviceSize offset{ shaderDataDevice.stride * i }; - - VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].buffer, shaderDataDevice.memory, offset)); - } - } - ////////////////////////////////////////////////////////////////////// // synchronization objects ////////////////////////////////////////////////////////////////////// @@ -686,365 +567,6 @@ int main() }; VK_CHECK(vkCreateSampler(device, &samplerCreateInfo2, nullptr, &textureSamplers[2])); - ////////////////////////////////////////////////////////////////////// - // descriptors - ////////////////////////////////////////////////////////////////////// - - // - // pool - // - - VkDescriptorPoolSize descriptorPoolSizes[3]{ - { - .type = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 3, - }, - { - .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - }, - { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = maxFramesInFlight, - } - }; - VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = 3, - .poolSizeCount = 3, - .pPoolSizes = descriptorPoolSizes - }; - VK_CHECK(vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool)); - - // - // uniform buffer descriptor set layout/allocation - // - - VkDescriptorSetLayoutBinding uniformBufferDescriptorSetLayoutBinding{ - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT - }; - - VkDescriptorSetLayoutCreateInfo uniformBufferDescriptorSetLayoutCreateInfo{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = 1, - .pBindings = &uniformBufferDescriptorSetLayoutBinding - }; - VK_CHECK(vkCreateDescriptorSetLayout(device, &uniformBufferDescriptorSetLayoutCreateInfo, nullptr, &uniformBufferDescriptorSetLayout)); - - VkDescriptorSetLayout uniformBufferDescriptorSetLayouts[maxFramesInFlight]; - for (uint32_t i = 0; i < maxFramesInFlight; i++) { - uniformBufferDescriptorSetLayouts[i] = uniformBufferDescriptorSetLayout; - }; - - VkDescriptorSetAllocateInfo uniformBufferDescriptorSetAllocateInfo{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = descriptorPool, - .descriptorSetCount = maxFramesInFlight, - .pSetLayouts = uniformBufferDescriptorSetLayouts - }; - VK_CHECK(vkAllocateDescriptorSets(device, &uniformBufferDescriptorSetAllocateInfo, uniformBufferDescriptorSets)); - - // - // texture descriptor set layout/allocation - // - - VkDescriptorSetLayoutBinding textureDescriptorSetLayoutBindings[2]{ - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 3, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT - } - }; - - VkDescriptorSetLayoutCreateInfo textureDescriptorSetLayoutCreateInfo{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = 2, - .pBindings = textureDescriptorSetLayoutBindings - }; - VK_CHECK(vkCreateDescriptorSetLayout(device, &textureDescriptorSetLayoutCreateInfo, nullptr, &textureDescriptorSetLayout)); - - VkDescriptorSetAllocateInfo textureDescriptorSetAllocateInfo{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = descriptorPool, - .descriptorSetCount = 1, - .pSetLayouts = &textureDescriptorSetLayout - }; - VK_CHECK(vkAllocateDescriptorSets(device, &textureDescriptorSetAllocateInfo, &textureDescriptorSet)); - - ////////////////////////////////////////////////////////////////////// - // descriptor set writes - ////////////////////////////////////////////////////////////////////// - - constexpr int writeDescriptorSetsCount = 2 + maxFramesInFlight; - VkWriteDescriptorSet writeDescriptorSets[writeDescriptorSetsCount]; - - VkDescriptorImageInfo textureSamplerDescriptorImageInfos[3] = { - { - .sampler = textureSamplers[0], - }, - { - .sampler = textureSamplers[1], - }, - { - .sampler = textureSamplers[2], - }, - }; - writeDescriptorSets[0] = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = textureDescriptorSet, - .dstBinding = 0, - .descriptorCount = 3, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .pImageInfo = textureSamplerDescriptorImageInfos - }; - VkDescriptorImageInfo textureImageDescriptorImageInfo = { - .imageView = textureImageView, - .imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL - }; - writeDescriptorSets[1] = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = textureDescriptorSet, - .dstBinding = 1, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .pImageInfo = &textureImageDescriptorImageInfo - }; - - for (uint32_t i = 0; i < maxFramesInFlight; i++) { - VkDescriptorBufferInfo descriptorBufferInfo { - .buffer = shaderDataDevice.frame[i].buffer, - .offset = 0, - .range = VK_WHOLE_SIZE, - }; - - writeDescriptorSets[2 + i] = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = uniformBufferDescriptorSets[i], - .dstBinding = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .pBufferInfo = &descriptorBufferInfo - }; - } - - // update all three descriptor sets - vkUpdateDescriptorSets(device, writeDescriptorSetsCount, writeDescriptorSets, 0, nullptr); - - ////////////////////////////////////////////////////////////////////// - // shaders - ////////////////////////////////////////////////////////////////////// - - uint32_t triangleSize; - void const * triangleStart = file::open("shader/triangle.spv", &triangleSize); - - VkShaderModuleCreateInfo shaderModuleCreateInfo{ - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .codeSize = triangleSize, - .pCode = (uint32_t *)triangleStart - }; - VkShaderModule shaderModule{}; - VK_CHECK(vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule)); - - ////////////////////////////////////////////////////////////////////// - // pipeline - ////////////////////////////////////////////////////////////////////// - - VkDescriptorSetLayout descriptorSetLayouts[2] = { - uniformBufferDescriptorSetLayout, - textureDescriptorSetLayout, - }; - - VkPushConstantRange pushConstantRange{ - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .size = (sizeof (int32_t)) - }; - - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 2, - .pSetLayouts = descriptorSetLayouts, - .pushConstantRangeCount = 1, - .pPushConstantRanges = &pushConstantRange - }; - VK_CHECK(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout)); - - VkVertexInputBindingDescription vertexBindingDescriptions[1]{ - { - .binding = 0, - .stride = ((3 + 3 + 2) * (sizeof (float))), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX - } - }; - VkVertexInputAttributeDescription vertexAttributeDescriptions[3]{ - { .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = 3 * 4 * 0 }, - { .location = 1, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = 3 * 4 * 1 }, - { .location = 2, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = 3 * 4 * 2 }, - }; - VkPipelineVertexInputStateCreateInfo vertexInputState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = vertexBindingDescriptions, - .vertexAttributeDescriptionCount = 3, - .pVertexAttributeDescriptions = vertexAttributeDescriptions, - }; - - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST - }; - - VkPipelineShaderStageCreateInfo shaderStages[2]{ - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = shaderModule, - .pName = "VSMain" - }, - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = shaderModule, - .pName = "PSMain" - } - }; - - VkPipelineShaderStageCreateInfo outlineShaderStages[2]{ - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = shaderModule, - .pName = "VSOutlineMain" - }, - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = shaderModule, - .pName = "PSOutlineMain" - } - }; - - VkPipelineViewportStateCreateInfo viewportState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, - .scissorCount = 1 - }; - - constexpr uint32_t dynamicStateCount = 2; - VkDynamicState dynamicStates[dynamicStateCount]{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }; - VkPipelineDynamicStateCreateInfo dynamicState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = dynamicStateCount, - .pDynamicStates = dynamicStates - }; - - VkPipelineDepthStencilStateCreateInfo depthStencilState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_TRUE, - .depthWriteEnable = VK_TRUE, - .depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL, - .stencilTestEnable = VK_TRUE, - .front = { - .failOp = VK_STENCIL_OP_REPLACE, - .passOp = VK_STENCIL_OP_REPLACE, - .depthFailOp = VK_STENCIL_OP_REPLACE, - .compareOp = VK_COMPARE_OP_ALWAYS, - .compareMask = 0x01, - .writeMask = 0x01, - .reference = 1, - }, - }; - - VkPipelineDepthStencilStateCreateInfo outlineDepthStencilState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_TRUE, - .depthWriteEnable = VK_TRUE, - .depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL, - .stencilTestEnable = VK_TRUE, - .front = { - .failOp = VK_STENCIL_OP_KEEP, - .passOp = VK_STENCIL_OP_REPLACE, - .depthFailOp = VK_STENCIL_OP_KEEP, - .compareOp = VK_COMPARE_OP_NOT_EQUAL, - .compareMask = 0x01, - .writeMask = 0x00, - .reference = 1, - }, - }; - - VkPipelineRenderingCreateInfo renderingCreateInfo{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - .colorAttachmentCount = 1, - .pColorAttachmentFormats = &surfaceFormat.format, - .depthAttachmentFormat = depthFormat, - .stencilAttachmentFormat = depthFormat - }; - - VkPipelineColorBlendAttachmentState blendAttachment{ - .colorWriteMask = 0xF - }; - VkPipelineColorBlendStateCreateInfo colorBlendState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &blendAttachment - }; - VkPipelineRasterizationStateCreateInfo rasterizationState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .cullMode = VK_CULL_MODE_BACK_BIT, - .frontFace = VK_FRONT_FACE_CLOCKWISE, - .lineWidth = 1.0f - }; - VkPipelineMultisampleStateCreateInfo multisampleState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT - }; - - VkGraphicsPipelineCreateInfo pipelineCreateInfos[2]{ - { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &renderingCreateInfo, - .stageCount = 2, - .pStages = shaderStages, - .pVertexInputState = &vertexInputState, - .pInputAssemblyState = &inputAssemblyState, - .pViewportState = &viewportState, - .pRasterizationState = &rasterizationState, - .pMultisampleState = &multisampleState, - .pDepthStencilState = &depthStencilState, - .pColorBlendState = &colorBlendState, - .pDynamicState = &dynamicState, - .layout = pipelineLayout - }, - { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &renderingCreateInfo, - .stageCount = 2, - .pStages = outlineShaderStages, - .pVertexInputState = &vertexInputState, - .pInputAssemblyState = &inputAssemblyState, - .pViewportState = &viewportState, - .pRasterizationState = &rasterizationState, - .pMultisampleState = &multisampleState, - .pDepthStencilState = &outlineDepthStencilState, - .pColorBlendState = &colorBlendState, - .pDynamicState = &dynamicState, - .layout = pipelineLayout - } - }; - VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 2, pipelineCreateInfos, nullptr, pipelines)); - ////////////////////////////////////////////////////////////////////// // initialize collada ////////////////////////////////////////////////////////////////////// @@ -1457,11 +979,7 @@ int main() for (uint32_t i = 0; i < maxFramesInFlight; i++) { vkDestroyFence(device, fences[i], nullptr); vkDestroySemaphore(device, presentSemaphores[i], nullptr); - - vkDestroyBuffer(device, shaderDataDevice.frame[i].buffer, nullptr); } - vkUnmapMemory(device, shaderDataDevice.memory); - vkFreeMemory(device, shaderDataDevice.memory, nullptr); for (uint32_t i = 0; i < swapchainImageCount; i++) { vkDestroySemaphore(device, renderSemaphores[i], nullptr); @@ -1477,26 +995,14 @@ int main() vkDestroyImageView(device, shadowDepthImageView, nullptr); vkDestroyImageView(device, shadowDepthImageViewDepth, nullptr); - vkDestroyBuffer(device, vertexIndexBuffer, nullptr); - vkFreeMemory(device, vertexIndexBufferMemory, nullptr); - - vkDestroyImageView(device, textureImageView, nullptr); vkDestroySampler(device, textureSamplers[0], nullptr); vkDestroySampler(device, textureSamplers[1], nullptr); vkDestroySampler(device, textureSamplers[2], nullptr); - vkDestroyImage(device, textureImage, nullptr); - vkFreeMemory(device, textureImageMemory, nullptr); - vkDestroyDescriptorSetLayout(device, uniformBufferDescriptorSetLayout, nullptr); - vkDestroyDescriptorSetLayout(device, textureDescriptorSetLayout, nullptr); vkDestroyDescriptorPool(device, descriptorPool, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyPipeline(device, pipelines[0], nullptr); - vkDestroyPipeline(device, pipelines[1], nullptr); vkDestroySwapchainKHR(device, swapchain, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyCommandPool(device, commandPool, nullptr); - vkDestroyShaderModule(device, shaderModule, nullptr); SDL_DestroyWindow(window); SDL_QuitSubSystem(SDL_INIT_VIDEO);