From 0092ce4c9ed824c555fd75834a0ab4c0b8c4286d Mon Sep 17 00:00:00 2001 From: Anish Bhobe Date: Mon, 15 Jul 2024 00:20:37 +0200 Subject: [PATCH] Extended testing for vertices. --- aster/image.cpp | 9 +- .../03_model_render/model/DamagedHelmet.glb | 3 + samples/03_model_render/model_loader.cpp | 226 +++++++++++++--- samples/03_model_render/model_loader.h | 25 +- samples/03_model_render/model_render.cpp | 241 +----------------- samples/03_model_render/pipeline_utils.cpp | 2 +- 6 files changed, 220 insertions(+), 286 deletions(-) create mode 100644 samples/03_model_render/model/DamagedHelmet.glb diff --git a/aster/image.cpp b/aster/image.cpp index 59cc9c6..8a1c64b 100644 --- a/aster/image.cpp +++ b/aster/image.cpp @@ -23,6 +23,13 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF const cstr name) { const u32 mipLevels = isMipmapped ? 1 + Cast(floor(log2(eastl::max(extent.width, extent.height)))) : 1; + + auto usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst; + if (isMipmapped) + { + usage |= vk::ImageUsageFlagBits::eTransferSrc; + } + vk::ImageCreateInfo imageCreateInfo = { .imageType = vk::ImageType::e2D, .format = imageFormat, @@ -31,7 +38,7 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF .arrayLayers = 1, .samples = vk::SampleCountFlagBits::e1, .tiling = vk::ImageTiling::eOptimal, - .usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst, + .usage = usage, .sharingMode = vk::SharingMode::eExclusive, .initialLayout = vk::ImageLayout::eUndefined, }; diff --git a/samples/03_model_render/model/DamagedHelmet.glb b/samples/03_model_render/model/DamagedHelmet.glb new file mode 100644 index 0000000..a8c16b5 --- /dev/null +++ b/samples/03_model_render/model/DamagedHelmet.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1e3b04de97b11de564ce6e53b95f02954a297f0008183ac63a4f5974f6b32d8 +size 3773916 diff --git a/samples/03_model_render/model_loader.cpp b/samples/03_model_render/model_loader.cpp index a635567..56a3e74 100644 --- a/samples/03_model_render/model_loader.cpp +++ b/samples/03_model_render/model_loader.cpp @@ -52,8 +52,11 @@ ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, Stagin { assert(image->component == 4); + usize byteSize = image->image.size(); texture->Init(m_ResourceManager->m_Device, {.width = Cast(image->width), .height = Cast(image->height)}, vk::Format::eR8G8B8A8Srgb, true, image->name.data()); + stagingBuffer->Init(m_ResourceManager->m_Device, byteSize); + stagingBuffer->Write(m_ResourceManager->m_Device, 0, byteSize, image->image.data()); // .srcAccessMask = , // .dstAccessMask = , @@ -144,7 +147,8 @@ ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, Stagin i32 prevMipWidth = Cast(texture->m_Extent.width); i32 prevMipHeight = Cast(texture->m_Extent.height); - for (u32 prevMipLevel = 1; prevMipLevel < texture->m_MipLevels; ++prevMipLevel) + u32 maxPrevMip = texture->m_MipLevels - 1; + for (u32 prevMipLevel = 0; prevMipLevel < maxPrevMip; ++prevMipLevel) { i32 currentMipWidth = calcNextMip(prevMipWidth); i32 currentMipHeight = calcNextMip(prevMipHeight); @@ -177,21 +181,24 @@ ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, Stagin }, }; - nextMipBarrier.subresourceRange.baseMipLevel = prevMipLevel; + nextMipBarrier.subresourceRange.baseMipLevel = currentMipLevel; commandBuffer.blitImage(texture->m_Image, vk::ImageLayout::eTransferSrcOptimal, texture->m_Image, vk::ImageLayout::eTransferDstOptimal, 1, &blitRegion, vk::Filter::eLinear); commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {}, 0, nullptr, 0, nullptr, 1, &nextMipBarrier); + + prevMipHeight = currentMipHeight; + prevMipWidth = currentMipWidth; } - commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTopOfPipe, {}, 0, - nullptr, 0, nullptr, 1, &imageReadyBarrier); + commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {}, + 0, nullptr, 0, nullptr, 1, &imageReadyBarrier); return m_ResourceManager->Commit(texture); } Model -ModelLoader::LoadModel(cstr path, cstr name) +ModelLoader::LoadModel(cstr path, cstr name, bool batched) { namespace fs = std::filesystem; tinygltf::Model model; @@ -222,17 +229,9 @@ ModelLoader::LoadModel(cstr path, cstr name) } } - vk::CommandBuffer commandBuffer; { - vk::CommandBufferAllocateInfo commandBufferAllocateInfo = { - .commandPool = m_CommandPool, - .level = vk::CommandBufferLevel::ePrimary, - .commandBufferCount = 1, - }; - AbortIfFailed(pDevice->m_Device.allocateCommandBuffers(&commandBufferAllocateInfo, &commandBuffer)); - vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit}; - AbortIfFailed(commandBuffer.begin(&beginInfo)); + AbortIfFailed(m_CommandBuffer.begin(&beginInfo)); } eastl::vector stagingBuffers; @@ -252,10 +251,8 @@ ModelLoader::LoadModel(cstr path, cstr name) auto imagePtr = model.images.data(); for (TextureHandle &handle : textureHandles) { - handle = LoadImage(commandBuffer, texturePtr++, stagingPtr++, imagePtr++); + handle = LoadImage(m_CommandBuffer, texturePtr++, stagingPtr++, imagePtr++); } - - AbortIfFailed(commandBuffer.end()); } eastl::vector materials; @@ -297,25 +294,32 @@ ModelLoader::LoadModel(cstr path, cstr name) materialStaging.Write(pDevice, 0, materialsByteSize, materials.data()); vk::BufferCopy bufferCopy = {.srcOffset = 0, .dstOffset = 0, .size = materialsByteSize}; - commandBuffer.copyBuffer(materialStaging.m_Buffer, materialsBuffer.m_Buffer, 1, &bufferCopy); + m_CommandBuffer.copyBuffer(materialStaging.m_Buffer, materialsBuffer.m_Buffer, 1, &bufferCopy); } // TODO: Mesh reordering based on nodes AND OR meshoptimizer // TODO: Support scenes eastl::vector vertexPositions; + eastl::vector normalVectors; + eastl::vector texCoord0; eastl::vector indices; eastl::vector meshPrimitives; meshPrimitives.reserve(model.meshes.size()); + u32 vertexOffset = 0; + i32 normalOffset = 0; + i32 texCoord0Offset = 0; + u32 indexOffset = 0; + for (auto &mesh : model.meshes) { for (auto &prim : mesh.primitives) { - u32 vertexOffset = Cast(vertexPositions.size()); - u32 vertexCount; - u32 indexOffset = Cast(indices.size()); - u32 indexCount; + u32 vertexCount = 0; + u32 indexCount = 0; + i32 normalCount = 0; + i32 texCoord0Count = 0; assert(prim.attributes.contains(APosition)); assert(prim.mode == TINYGLTF_MODE_TRIANGLES); @@ -354,6 +358,65 @@ ModelLoader::LoadModel(cstr path, cstr name) } } + // Normal Coords + if (prim.attributes.contains(ANormal)) + { + tinygltf::Accessor *normAccessor = &model.accessors[prim.attributes[ANormal]]; + + assert(normAccessor->count <= MaxValue); + + tinygltf::BufferView *normBufferView = &model.bufferViews[normAccessor->bufferView]; + tinygltf::Buffer *normBuffer = &model.buffers[normBufferView->buffer]; + usize byteOffset = (normAccessor->byteOffset + normBufferView->byteOffset); + + normalCount = Cast(normAccessor->count); + normalVectors.reserve(vertexPositions.size()); + + if (normAccessor->type == TINYGLTF_TYPE_VEC4) + { + vec4 *data = Recast(normBuffer->data.data() + byteOffset); + normalVectors.insert(normalVectors.end(), data, data + vertexCount); + } + else if (normAccessor->type == TINYGLTF_TYPE_VEC3) + { + vec3 *data = Recast(normBuffer->data.data() + byteOffset); + for (u32 i = 0; i < vertexCount; ++i) + { + normalVectors.push_back(vec4(data[i], 1.0f)); + } + } + else if (normAccessor->type == TINYGLTF_TYPE_VEC2) + { + vec2 *data = Recast(normBuffer->data.data() + byteOffset); + for (u32 i = 0; i < vertexCount; ++i) + { + normalVectors.push_back(vec4(data[i], 0.0f, 1.0f)); + } + } + } + + // UV0 + if (prim.attributes.contains(ATexCoord0)) + { + tinygltf::Accessor *uvAccessor = &model.accessors[prim.attributes[ATexCoord0]]; + + assert(uvAccessor->count <= MaxValue); + + tinygltf::BufferView *uvBufferView = &model.bufferViews[uvAccessor->bufferView]; + tinygltf::Buffer *uvBuffer = &model.buffers[uvBufferView->buffer]; + usize byteOffset = (uvAccessor->byteOffset + uvBufferView->byteOffset); + + texCoord0Count = Cast(uvAccessor->count); + texCoord0.reserve(vertexPositions.size()); + + assert(uvAccessor->type == TINYGLTF_TYPE_VEC2); + { + vec2 *data = Recast(uvBuffer->data.data() + byteOffset); + texCoord0.insert(texCoord0.end(), data, data + vertexCount); + } + } + + // Indices if (prim.indices >= 0) { tinygltf::Accessor *indexAccessor = &model.accessors[prim.indices]; @@ -395,10 +458,20 @@ ModelLoader::LoadModel(cstr path, cstr name) meshPrimitives.push_back({ .m_VertexOffset = vertexOffset, + .m_NormalOffset = normalCount > 0 ? normalOffset : -1, + .m_TexCoord0Offset = texCoord0Count > 0 ? texCoord0Offset : -1, .m_FirstIndex = indexOffset, .m_IndexCount = indexCount, .m_MaterialIdx = prim.material, }); + + vertexOffset += vertexCount; + indexOffset += indexCount; + texCoord0Offset += texCoord0Count; + normalOffset += normalCount; + + assert(normalVectors.empty() || normalVectors.size() == vertexPositions.size()); + assert(texCoord0.empty() || texCoord0.size() == vertexPositions.size()); } } @@ -406,32 +479,66 @@ ModelLoader::LoadModel(cstr path, cstr name) positionBuffer.Init(pDevice, vertexPositions.size() * sizeof vertexPositions[0], false); BufferHandle positionBufferHandle = m_ResourceManager->Commit(&positionBuffer); + StorageBuffer normalBuffer; + BufferHandle normalBufferHandle; + if (!normalVectors.empty()) + { + normalBuffer.Init(pDevice, normalVectors.size() * sizeof normalVectors[0], false); + normalBufferHandle = m_ResourceManager->Commit(&normalBuffer); + } + + StorageBuffer texCoord0Buffer; + BufferHandle texCoord0BufferHandle; + if (!texCoord0.empty()) + { + texCoord0Buffer.Init(pDevice, texCoord0.size() * sizeof texCoord0[0], false); + texCoord0BufferHandle = m_ResourceManager->Commit(&texCoord0Buffer); + } + IndexBuffer indexBuffer; indexBuffer.Init(pDevice, indices.size() * sizeof indices[0]); { vk::BufferCopy bufferCopy = {.srcOffset = 0, .dstOffset = 0}; - StagingBuffer &positionStaging = stagingBuffers.push_back(); - positionStaging.Init(pDevice, positionBuffer.GetSize()); - positionStaging.Write(pDevice, 0, positionBuffer.GetSize(), vertexPositions.data()); bufferCopy.size = positionBuffer.GetSize(); - commandBuffer.copyBuffer(positionStaging.m_Buffer, positionBuffer.m_Buffer, 1, &bufferCopy); + StagingBuffer &positionStaging = stagingBuffers.push_back(); + positionStaging.Init(pDevice, bufferCopy.size); + positionStaging.Write(pDevice, 0, bufferCopy.size, vertexPositions.data()); + m_CommandBuffer.copyBuffer(positionStaging.m_Buffer, positionBuffer.m_Buffer, 1, &bufferCopy); + + if (normalBuffer.IsValid()) + { + bufferCopy.size = normalBuffer.GetSize(); + StagingBuffer &normalStaging = stagingBuffers.push_back(); + normalStaging.Init(pDevice, bufferCopy.size); + normalStaging.Write(pDevice, 0, bufferCopy.size, normalVectors.data()); + m_CommandBuffer.copyBuffer(normalStaging.m_Buffer, normalBuffer.m_Buffer, 1, &bufferCopy); + } + + if (texCoord0Buffer.IsValid()) + { + bufferCopy.size = texCoord0Buffer.GetSize(); + StagingBuffer &textureStaging = stagingBuffers.push_back(); + textureStaging.Init(pDevice, bufferCopy.size); + textureStaging.Write(pDevice, 0, bufferCopy.size, texCoord0.data()); + m_CommandBuffer.copyBuffer(textureStaging.m_Buffer, texCoord0Buffer.m_Buffer, 1, &bufferCopy); + } - StagingBuffer &indexStaging = stagingBuffers.push_back(); - indexStaging.Init(pDevice, indexBuffer.GetSize()); - indexStaging.Write(pDevice, 0, indexBuffer.GetSize(), indices.data()); bufferCopy.size = indexBuffer.GetSize(); - commandBuffer.copyBuffer(indexStaging.m_Buffer, indexBuffer.m_Buffer, 1, &bufferCopy); + StagingBuffer &indexStaging = stagingBuffers.push_back(); + indexStaging.Init(pDevice, bufferCopy.size); + indexStaging.Write(pDevice, 0, bufferCopy.size, indices.data()); + m_CommandBuffer.copyBuffer(indexStaging.m_Buffer, indexBuffer.m_Buffer, 1, &bufferCopy); } - AbortIfFailed(commandBuffer.end()); + AbortIfFailed(m_CommandBuffer.end()); vk::SubmitInfo submitInfo = { .waitSemaphoreCount = 0, - .pWaitDstStageMask = 0, + .pWaitDstStageMask = nullptr, .commandBufferCount = 1, - .pCommandBuffers = &commandBuffer, + .pCommandBuffers = &m_CommandBuffer, }; vk::Fence fence; @@ -441,20 +548,25 @@ ModelLoader::LoadModel(cstr path, cstr name) AbortIfFailed(pDevice->m_Device.waitForFences(1, &fence, true, MaxValue)); pDevice->m_Device.destroy(fence, nullptr); + AbortIfFailed(pDevice->m_Device.resetCommandPool( + m_CommandPool, batched ? vk::CommandPoolResetFlags{} : vk::CommandPoolResetFlagBits::eReleaseResources)); + for (auto &buffer : stagingBuffers) { buffer.Destroy(pDevice); } - return Model{m_ResourceManager, std::move(textures), std::move(textureHandles), - materialsBuffer, materialsHandle, positionBuffer, - positionBufferHandle, indexBuffer, meshPrimitives}; + return Model{m_ResourceManager, std::move(textures), std::move(textureHandles), materialsBuffer, + materialsHandle, positionBuffer, positionBufferHandle, normalBuffer, + normalBufferHandle, texCoord0Buffer, texCoord0BufferHandle, indexBuffer, + meshPrimitives}; } Model::Model(RenderResourceManager *resourceManager, eastl::vector &&textures, eastl::vector &&textureHandles, const StorageBuffer &materialsBuffer, BufferHandle materialsHandle, const StorageBuffer &vertexPosBuffer, BufferHandle vertexPosHandle, - const IndexBuffer &indexBuffer, const eastl::vector &meshPrimitives) + const StorageBuffer &normalBuffer, BufferHandle normalHandle, const StorageBuffer &uv0Buffer, + BufferHandle uv0Handle, const IndexBuffer &indexBuffer, const eastl::vector &meshPrimitives) : m_ResourceManager(resourceManager) , m_Textures(textures) , m_TextureHandles(textureHandles) @@ -462,6 +574,10 @@ Model::Model(RenderResourceManager *resourceManager, eastl::vector &&te , m_MaterialsHandle(materialsHandle) , m_VertexPositions(vertexPosBuffer) , m_VertexPositionHandle(vertexPosHandle) + , m_NormalVectors(normalBuffer) + , m_NormalHandle(normalHandle) + , m_TexCoord0(uv0Buffer) + , m_TexCoord0Handle(uv0Handle) , m_IndexBuffer(indexBuffer) , m_MeshPrimitives(meshPrimitives) { @@ -475,6 +591,10 @@ Model::Model(Model &&other) noexcept , m_MaterialsHandle(other.m_MaterialsHandle) , m_VertexPositions(other.m_VertexPositions) , m_VertexPositionHandle(other.m_VertexPositionHandle) + , m_NormalVectors(other.m_NormalVectors) + , m_NormalHandle(other.m_NormalHandle) + , m_TexCoord0(other.m_TexCoord0) + , m_TexCoord0Handle(other.m_TexCoord0Handle) , m_IndexBuffer(other.m_IndexBuffer) , m_MeshPrimitives(std::move(other.m_MeshPrimitives)) { @@ -492,6 +612,10 @@ Model::operator=(Model &&other) noexcept m_MaterialsHandle = other.m_MaterialsHandle; m_VertexPositions = other.m_VertexPositions; m_VertexPositionHandle = other.m_VertexPositionHandle; + m_NormalVectors = other.m_NormalVectors; + m_NormalHandle = other.m_NormalHandle; + m_TexCoord0 = other.m_TexCoord0; + m_TexCoord0Handle = other.m_TexCoord0Handle; m_IndexBuffer = other.m_IndexBuffer; m_MeshPrimitives = std::move(other.m_MeshPrimitives); return *this; @@ -504,8 +628,12 @@ Model::~Model() m_VertexPositions.Destroy(m_ResourceManager->m_Device); m_IndexBuffer.Destroy(m_ResourceManager->m_Device); + m_NormalVectors.Destroy(m_ResourceManager->m_Device); + m_TexCoord0.Destroy(m_ResourceManager->m_Device); m_ResourceManager->Release(m_VertexPositionHandle); + m_ResourceManager->Release(m_NormalHandle); + m_ResourceManager->Release(m_TexCoord0Handle); for (const TextureHandle &handle : m_TextureHandles) { m_ResourceManager->Release(handle); @@ -518,12 +646,30 @@ Model::~Model() m_MaterialsBuffer.Destroy(m_ResourceManager->m_Device); } -ModelLoader::ModelLoader(RenderResourceManager *resourceManager, vk::CommandPool commandPool, vk::Queue transferQueue, - u32 transferQueueIndex, u32 graphicsQueueIndex) +ModelLoader::ModelLoader(RenderResourceManager *resourceManager, vk::Queue transferQueue, u32 transferQueueIndex, + u32 graphicsQueueIndex) : m_ResourceManager(resourceManager) - , m_CommandPool(commandPool) , m_TransferQueue(transferQueue) , m_TransferQueueIndex(transferQueueIndex) , m_GraphicsQueueIndex(graphicsQueueIndex) { + const Device *pDevice = resourceManager->m_Device; + const vk::CommandPoolCreateInfo poolCreateInfo = { + .flags = vk::CommandPoolCreateFlagBits::eTransient, + .queueFamilyIndex = transferQueueIndex, + }; + AbortIfFailedM(pDevice->m_Device.createCommandPool(&poolCreateInfo, nullptr, &m_CommandPool), + "Transfer command pool creation failed."); + + const vk::CommandBufferAllocateInfo commandBufferAllocateInfo = { + .commandPool = m_CommandPool, + .level = vk::CommandBufferLevel::ePrimary, + .commandBufferCount = 1, + }; + AbortIfFailed(pDevice->m_Device.allocateCommandBuffers(&commandBufferAllocateInfo, &m_CommandBuffer)); +} + +ModelLoader::~ModelLoader() +{ + m_ResourceManager->m_Device->m_Device.destroy(m_CommandPool, nullptr); } \ No newline at end of file diff --git a/samples/03_model_render/model_loader.h b/samples/03_model_render/model_loader.h index 7a361e5..b956dc0 100644 --- a/samples/03_model_render/model_loader.h +++ b/samples/03_model_render/model_loader.h @@ -22,9 +22,11 @@ constexpr auto GLTF_BINARY_FILE_EXTENSION = ".glb"; struct MeshPrimitive { u32 m_VertexOffset; + i32 m_NormalOffset; // <0 for invalid + i32 m_TexCoord0Offset; // <0 for invalid u32 m_FirstIndex; u32 m_IndexCount; - i32 m_MaterialIdx; // -1 for invalid + i32 m_MaterialIdx; // <0 for invalid }; struct Material @@ -43,19 +45,30 @@ struct Material struct Model { RenderResourceManager *m_ResourceManager; + eastl::vector m_Textures; eastl::vector m_TextureHandles; + StorageBuffer m_MaterialsBuffer; BufferHandle m_MaterialsHandle; + StorageBuffer m_VertexPositions; BufferHandle m_VertexPositionHandle; + + StorageBuffer m_NormalVectors; + BufferHandle m_NormalHandle; + + StorageBuffer m_TexCoord0; + BufferHandle m_TexCoord0Handle; + IndexBuffer m_IndexBuffer; eastl::vector m_MeshPrimitives; Model(RenderResourceManager *resourceManager, eastl::vector &&textures, eastl::vector &&textureHandles, const StorageBuffer &materialsBuffer, BufferHandle materialsHandle, const StorageBuffer &vertexPosBuffer, BufferHandle vertexPosHandle, - const IndexBuffer &indexBuffer, const eastl::vector &meshPrimitives); + const StorageBuffer &normalBuffer, BufferHandle normalHandle, const StorageBuffer &uv0Buffer, + BufferHandle uv0Handle, const IndexBuffer &indexBuffer, const eastl::vector &meshPrimitives); Model(Model &&other) noexcept; Model &operator=(Model &&other) noexcept; @@ -69,16 +82,18 @@ struct ModelLoader { RenderResourceManager *const m_ResourceManager; vk::CommandPool m_CommandPool; + vk::CommandBuffer m_CommandBuffer; vk::Queue m_TransferQueue; u32 m_TransferQueueIndex; u32 m_GraphicsQueueIndex; - ModelLoader(RenderResourceManager *resourceManager, vk::CommandPool commandPool, vk::Queue transferQueue, - u32 transferQueueIndex, u32 graphicsQueueIndex); + ModelLoader(RenderResourceManager *resourceManager, vk::Queue transferQueue, u32 transferQueueIndex, + u32 graphicsQueueIndex); + ~ModelLoader(); TextureHandle LoadImage(vk::CommandBuffer commandBuffer, Texture *texture, StagingBuffer *stagingBuffer, tinygltf::Image *image); - Model LoadModel(cstr path, cstr name = nullptr); + Model LoadModel(cstr path, cstr name = nullptr, bool batched = false); constexpr static auto ANormal = "NORMAL"; constexpr static auto APosition = "POSITION"; diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index 6d48374..a7cb3f3 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -27,7 +27,7 @@ #include constexpr u32 MAX_FRAMES_IN_FLIGHT = 3; -constexpr auto MODEL_FILE = "model/Box.glb"; +constexpr auto MODEL_FILE = "model/BoxTextured.glb"; struct ImageFile { @@ -87,27 +87,7 @@ main(int, char **) Swapchain swapchain = {&window, &device, "Primary Chain"}; RenderResourceManager resourceManager = {&device, 1000}; - vk::CommandPool copyPool; - vk::CommandBuffer copyBuffer; - - { - vk::CommandPoolCreateInfo poolCreateInfo = { - .flags = vk::CommandPoolCreateFlagBits::eTransient, - .queueFamilyIndex = queueAllocation.m_Family, - }; - AbortIfFailedM(device.m_Device.createCommandPool(&poolCreateInfo, nullptr, ©Pool), - "Copy command pool creation failed."); - vk::CommandBufferAllocateInfo bufferAllocateInfo = { - .commandPool = copyPool, - .level = vk::CommandBufferLevel::ePrimary, - .commandBufferCount = 1, - }; - AbortIfFailedM(device.m_Device.allocateCommandBuffers(&bufferAllocateInfo, ©Buffer), - "Copy command buffer allocation failed."); - } - - ModelLoader modelLoader = {&resourceManager, copyPool, commandQueue, queueAllocation.m_Family, - queueAllocation.m_Family}; + ModelLoader modelLoader = {&resourceManager, commandQueue, queueAllocation.m_Family, queueAllocation.m_Family}; auto model = modelLoader.LoadModel(MODEL_FILE); @@ -130,10 +110,6 @@ main(int, char **) .type = vk::DescriptorType::eUniformBuffer, .descriptorCount = 1, }, - vk::DescriptorPoolSize{ - .type = vk::DescriptorType::eCombinedImageSampler, - .descriptorCount = 1, - }, }; vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo = { .maxSets = 1, .poolSizeCount = Cast(poolSizes.size()), .pPoolSizes = poolSizes.data()}; @@ -147,195 +123,6 @@ main(int, char **) AbortIfFailed(device.m_Device.allocateDescriptorSets(&descriptorSetAllocateInfo, &descriptorSet)); } - eastl::array vertices = { - Vertex{.m_Position = vec3(0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - - Vertex{.m_Position = vec3(-0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 0.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 1.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - - Vertex{.m_Position = vec3(-0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 1.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - - Vertex{.m_Position = vec3(0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 0.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - - Vertex{.m_Position = vec3(-0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 0.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 1.0f)}, - Vertex{.m_Position = vec3(-0.5f, -0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - - Vertex{.m_Position = vec3(0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(1.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, -0.5f), .m_TexCoord0 = vec2(0.0f, 0.0f)}, - Vertex{.m_Position = vec3(-0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(0.0f, 1.0f)}, - Vertex{.m_Position = vec3(0.5f, 0.5f, 0.5f), .m_TexCoord0 = vec2(1.0f, 1.0f)}, - }; - - ImageFile crateImageFile; - ImageFile plainImageFile; - assert(crateImageFile.Load("image/container.jpg")); - INFO("Image {}x{} : {} channels", crateImageFile.m_Width, crateImageFile.m_Height, crateImageFile.m_NumChannels); - assert(plainImageFile.Load({0.7f, 0.4f, 0.1f, 1.0f})); - - StorageBuffer pvbo; - Texture crateTexture; - Texture plainTexture; - crateTexture.Init(&device, {crateImageFile.m_Width, crateImageFile.m_Height}, vk::Format::eR8G8B8A8Srgb, false, - "Crate Texture"); - plainTexture.Init(&device, {crateImageFile.m_Width, crateImageFile.m_Height}, vk::Format::eR8G8B8A8Srgb, false, - "Plain Texture"); - pvbo.Init(&device, vertices.size() * sizeof vertices[0], true, "Pull VBO"); - pvbo.Write(&device, 0, pvbo.GetSize(), vertices.data()); - - auto crateTextureId = resourceManager.Commit(&crateTexture); - auto plainTextureId = resourceManager.Commit(&plainTexture); - auto pvboBufferId = resourceManager.Commit(&pvbo); - - { - StagingBuffer imageStaging1, imageStaging2; - - imageStaging1.Init(&device, crateImageFile.GetSize(), "Image Staging 1"); - imageStaging1.Write(&device, 0, crateImageFile.GetSize(), crateImageFile.m_Data); - - imageStaging2.Init(&device, plainImageFile.GetSize(), "Image Staging 2"); - imageStaging2.Write(&device, 0, plainImageFile.GetSize(), plainImageFile.m_Data); - - eastl::array imageReadyToWrite = { - vk::ImageMemoryBarrier{ - .oldLayout = vk::ImageLayout::eUndefined, - .newLayout = vk::ImageLayout::eTransferDstOptimal, - .srcQueueFamilyIndex = queueAllocation.m_Family, - .dstQueueFamilyIndex = queueAllocation.m_Family, - .image = crateTexture.m_Image, - .subresourceRange = - { - .aspectMask = vk::ImageAspectFlagBits::eColor, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }, - vk::ImageMemoryBarrier{ - .oldLayout = vk::ImageLayout::eUndefined, - .newLayout = vk::ImageLayout::eTransferDstOptimal, - .srcQueueFamilyIndex = queueAllocation.m_Family, - .dstQueueFamilyIndex = queueAllocation.m_Family, - .image = plainTexture.m_Image, - .subresourceRange = - { - .aspectMask = vk::ImageAspectFlagBits::eColor, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }, - }; - - eastl::array imageReadyToRead = { - vk::ImageMemoryBarrier{ - .oldLayout = vk::ImageLayout::eTransferDstOptimal, - .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, - .srcQueueFamilyIndex = queueAllocation.m_Family, - .dstQueueFamilyIndex = queueAllocation.m_Family, - .image = crateTexture.m_Image, - .subresourceRange = - { - .aspectMask = vk::ImageAspectFlagBits::eColor, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }, - vk::ImageMemoryBarrier{ - .oldLayout = vk::ImageLayout::eTransferDstOptimal, - .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, - .srcQueueFamilyIndex = queueAllocation.m_Family, - .dstQueueFamilyIndex = queueAllocation.m_Family, - .image = plainTexture.m_Image, - .subresourceRange = - { - .aspectMask = vk::ImageAspectFlagBits::eColor, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }, - }; - - vk::Fence fence; - vk::FenceCreateInfo fenceCreateInfo = {}; - AbortIfFailed(device.m_Device.createFence(&fenceCreateInfo, nullptr, &fence)); - - vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit}; - AbortIfFailed(copyBuffer.begin(&beginInfo)); - copyBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eHost, vk::PipelineStageFlagBits::eTransfer, {}, 0, - nullptr, 0, nullptr, Cast(imageReadyToWrite.size()), imageReadyToWrite.data()); - - vk::BufferImageCopy imageCopy = { - .bufferOffset = 0, - .bufferRowLength = crateImageFile.m_Width, - .bufferImageHeight = crateImageFile.m_Height, - .imageSubresource = - { - .aspectMask = vk::ImageAspectFlagBits::eColor, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }, - .imageOffset = {}, - .imageExtent = {crateImageFile.m_Width, crateImageFile.m_Height, 1}, - }; - copyBuffer.copyBufferToImage(imageStaging1.m_Buffer, crateTexture.m_Image, vk::ImageLayout::eTransferDstOptimal, - 1, &imageCopy); - copyBuffer.copyBufferToImage(imageStaging2.m_Buffer, plainTexture.m_Image, vk::ImageLayout::eTransferDstOptimal, - 1, &imageCopy); - copyBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {}, - 0, nullptr, 0, nullptr, Cast(imageReadyToRead.size()), imageReadyToRead.data()); - - AbortIfFailed(copyBuffer.end()); - - vk::SubmitInfo submitInfo = { - .commandBufferCount = 1, - .pCommandBuffers = ©Buffer, - }; - - AbortIfFailed(commandQueue.submit(1, &submitInfo, fence)); - INFO("Submit copy"); - - AbortIfFailed(device.m_Device.waitForFences(1, &fence, true, MaxValue)); - INFO("Fence wait"); - - AbortIfFailedM(device.m_Device.resetCommandPool(copyPool, {}), "Couldn't reset command pool."); - - device.m_Device.destroy(fence, nullptr); - imageStaging1.Destroy(&device); - imageStaging2.Destroy(&device); - } - UniformBuffer ubo; ubo.Init(&device, sizeof camera, "Camera UBO"); ubo.Write(&device, 0, sizeof camera, &camera); @@ -427,17 +214,6 @@ main(int, char **) Time::Init(); - GpuResourceHandle *pushData = &crateTextureId; - GpuResourceHandle *otherPushData = &plainTextureId; - - bool prevPressed = false; - auto isSpaceJustPressed = [&prevPressed, &window] { - const bool pressed = glfwGetKey(window.m_Window, GLFW_KEY_SPACE) == GLFW_PRESS; - const bool justPressed = pressed & !prevPressed; - prevPressed = pressed; - return justPressed; - }; - struct ModelData { BufferHandle m_VertexBuffer; @@ -454,11 +230,6 @@ main(int, char **) { Time::Update(); - if (isSpaceJustPressed()) - { - eastl::swap(pushData, otherPushData); - } - camera.m_Model *= rotate(mat4{1.0f}, Cast(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)); ubo.Write(&device, 0, sizeof camera, &camera); @@ -513,13 +284,9 @@ main(int, char **) cmd.setViewport(0, 1, &viewport); cmd.setScissor(0, 1, &scissor); cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.m_Pipeline); - // cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, 0, sizeof *pushData, pushData); - // cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, sizeof *pushData, sizeof pvboBufferId, - // &pvboBufferId); cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.m_Layout, 0, 1, &resourceManager.m_DescriptorSet, 0, nullptr); cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.m_Layout, 1, 1, &descriptorSet, 0, nullptr); - // cmd.draw(Cast(vertices.size()), 1, 0, 0); cmd.bindIndexBuffer(model.m_IndexBuffer.m_Buffer, 0, vk::IndexType::eUint32); cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, 0, sizeof modelData, &modelData); @@ -561,10 +328,6 @@ main(int, char **) } ubo.Destroy(&device); device.m_Device.destroy(descriptorPool, nullptr); - device.m_Device.destroy(copyPool, nullptr); - crateTexture.Destroy(&device); - plainTexture.Destroy(&device); - pvbo.Destroy(&device); return 0; } diff --git a/samples/03_model_render/pipeline_utils.cpp b/samples/03_model_render/pipeline_utils.cpp index 3922924..84e5a9b 100644 --- a/samples/03_model_render/pipeline_utils.cpp +++ b/samples/03_model_render/pipeline_utils.cpp @@ -58,7 +58,7 @@ CreatePipeline(const Device *device, const Swapchain *swapchain, const RenderRes vk::PushConstantRange pushConstantRange = { .stageFlags = vk::ShaderStageFlagBits::eAll, .offset = 0, - .size = 16, + .size = 32, }; vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {