From 2be28d722f2bb364ca6e71548b1a6f13041153e9 Mon Sep 17 00:00:00 2001 From: Unknown <0.tamas.marton@gmail.com> Date: Mon, 19 Aug 2019 22:12:51 +0100 Subject: [PATCH] added vulkan code to create and bind a texture still need to implement driver backend --- driver/ConsecutivePoolAllocator.c | 2 +- driver/PoolAllocator.c | 2 +- driver/command.c | 9 ++- driver/common.h | 4 +- driver/descriptorSet.c | 5 +- driver/sampler.c | 36 ++++++++++- test/triangle/triangle.cpp | 101 ++++++++++++++++++++++++------ 7 files changed, 131 insertions(+), 28 deletions(-) diff --git a/driver/ConsecutivePoolAllocator.c b/driver/ConsecutivePoolAllocator.c index a2e7ad9..dbf17bb 100644 --- a/driver/ConsecutivePoolAllocator.c +++ b/driver/ConsecutivePoolAllocator.c @@ -9,7 +9,7 @@ ConsecutivePoolAllocator createConsecutivePoolAllocator(char* b, unsigned bs, un assert(b); //only allocated memory assert(bs >= sizeof(void*)); //we need to be able to store assert(s%bs==0); //we want a size that is the exact multiple of block size - assert(s > bs); //at least 1 element + assert(s >= bs); //at least 1 element ConsecutivePoolAllocator pa = { diff --git a/driver/PoolAllocator.c b/driver/PoolAllocator.c index 0efdd95..a8ca6e4 100644 --- a/driver/PoolAllocator.c +++ b/driver/PoolAllocator.c @@ -9,7 +9,7 @@ PoolAllocator createPoolAllocator(char* b, unsigned bs, unsigned s) assert(b); //only allocated memory assert(bs >= sizeof(void*)); //we need to be able to store assert(s%bs==0); //we want a size that is the exact multiple of block size - assert(s > bs); //at least 1 element + assert(s >= bs); //at least 1 element PoolAllocator pa = { diff --git a/driver/command.c b/driver/command.c index 4747d99..62e902b 100644 --- a/driver/command.c +++ b/driver/command.c @@ -288,8 +288,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( //TODO: deal with pSubmits->pWaitDstStageMask - //TODO wait for fence?? - for(int c = 0; c < pSubmits->commandBufferCount; ++c) { if(pSubmits->pCommandBuffers[c]->state == CMDBUF_STATE_EXECUTABLE) @@ -360,6 +358,13 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( sem_post((sem_t*)pSubmits->pSignalSemaphores[c]); } + //TODO is this correct? + _fence* f = fence; + if(f) + { + f->seqno = queue->lastEmitSeqno; + } + return VK_SUCCESS; } diff --git a/driver/common.h b/driver/common.h index 2f7acaa..cd83a8b 100644 --- a/driver/common.h +++ b/driver/common.h @@ -288,6 +288,8 @@ typedef struct VkPipeline_T typedef struct VkCommandBuffer_T { + _device* dev; //device from which it was created + //Recorded commands include commands to bind pipelines and descriptor sets to the command buffer, commands to modify dynamic state, commands to draw (for graphics rendering), //commands to dispatch (for compute), commands to execute secondary command buffers (for primary command buffers only), commands to copy buffers and images, and other commands @@ -369,7 +371,7 @@ typedef struct VkSampler_T { VkFilter minFilter, magFilter; VkSamplerMipmapMode mipmapMode; - VkSamplerAddressMode addressModeU, addressModeV, assressModeW; + VkSamplerAddressMode addressModeU, addressModeV, addressModeW; float mipLodBias; VkBool32 anisotropyEnable; float maxAnisotropy; diff --git a/driver/descriptorSet.c b/driver/descriptorSet.c index 5104a32..7c55491 100644 --- a/driver/descriptorSet.c +++ b/driver/descriptorSet.c @@ -112,6 +112,8 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( *dp->texelBufferDescriptorCPA = createConsecutivePoolAllocator(mem, sizeof(_descriptorTexelBuffer), sizeof(_descriptorTexelBuffer) * texelBufferDescriptorCount); } + *pDescriptorPool = dp; + return VK_SUCCESS; } @@ -252,9 +254,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( return VK_ERROR_OUT_OF_HOST_MEMORY; } - memcpy(dsl->bindings, pCreateInfo->bindingCount, sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->bindingCount); + memcpy(dsl->bindings, pCreateInfo->pBindings, sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->bindingCount); dsl->flags = pCreateInfo->flags; + dsl->bindingsCount = pCreateInfo->bindingCount; *pSetLayout = dsl; diff --git a/driver/sampler.c b/driver/sampler.c index f9e2fc4..8080c10 100644 --- a/driver/sampler.c +++ b/driver/sampler.c @@ -1,13 +1,40 @@ #include "common.h" -//TODO - VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler) { + assert(device); + assert(pCreateInfo); + assert(pSampler); + + _sampler* s = ALLOCATE(sizeof(_sampler), 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + + if(!s) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + s->minFilter = pCreateInfo->minFilter; + s->magFilter = pCreateInfo->magFilter; + s->mipmapMode = pCreateInfo->mipmapMode; + s->addressModeU = pCreateInfo->addressModeU; + s->addressModeV = pCreateInfo->addressModeV; + s->addressModeW = pCreateInfo->addressModeW; + s->mipLodBias = pCreateInfo->mipLodBias; + s->anisotropyEnable = pCreateInfo->anisotropyEnable; + s->maxAnisotropy = pCreateInfo->maxAnisotropy; + s->compareEnable = pCreateInfo->compareEnable; + s->compareOp = pCreateInfo->compareOp; + s->minLod = pCreateInfo->minLod; + s->maxLod = pCreateInfo->maxLod; + s->borderColor = pCreateInfo->borderColor; + s->unnormalizedCoordinates = pCreateInfo->unnormalizedCoordinates; + + *pSampler = s; + return VK_SUCCESS; } @@ -16,7 +43,9 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySampler( VkSampler sampler, const VkAllocationCallbacks* pAllocator) { + assert(device); + FREE(sampler); } VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( @@ -25,6 +54,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) { + //TODO return VK_SUCCESS; } @@ -33,5 +63,5 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion( VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator) { - + //TODO } diff --git a/test/triangle/triangle.cpp b/test/triangle/triangle.cpp index 6eba1e0..7d5f39a 100644 --- a/test/triangle/triangle.cpp +++ b/test/triangle/triangle.cpp @@ -45,6 +45,7 @@ void CreatePipeline(); void CreateUniformBuffer(); void CreateDescriptorSet(); void CreateVertexBuffer(); +void CreateTexture(); void recordCommandBuffers(); VkSurfaceFormatKHR chooseSurfaceFormat(const std::vector& availableFormats); VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& surfaceCapabilities); @@ -150,9 +151,10 @@ void setupVulkan() { CreateRenderPass(); CreateFramebuffer(); CreateVertexBuffer(); - CreateUniformBuffer(); + //CreateUniformBuffer(); CreateDescriptorSet(); CreateShaders(); + CreateTexture(); CreatePipeline(); recordCommandBuffers(); } @@ -658,7 +660,7 @@ void recordCommandBuffers() VkDeviceSize offsets = 0; vkCmdBindVertexBuffers(presentCommandBuffers[i], 0, 1, &vertexBuffer, &offsets ); - //vkCmdBindDescriptorSets(presentCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, 0); + vkCmdBindDescriptorSets(presentCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, 0); float Wcoeff = 1.0f; //1.0f / Wc = 2.0 - Wcoeff float viewportScaleX = (float)(swapChainExtent.width) * 0.5f * 16.0f; @@ -1061,8 +1063,8 @@ void CreatePipeline() VkPipelineLayoutCreateInfo pipelineLayoutCI = {}; pipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - //pipelineLayoutCI.setLayoutCount = 1; - //pipelineLayoutCI.pSetLayouts = &dsl; + pipelineLayoutCI.setLayoutCount = 1; + pipelineLayoutCI.pSetLayouts = &dsl; pipelineLayoutCI.pushConstantRangeCount = 2; pipelineLayoutCI.pPushConstantRanges = &pushConstantRanges[0]; vkCreatePipelineLayout(device, &pipelineLayoutCI, 0, &pipelineLayout); @@ -1269,7 +1271,68 @@ void CreateTexture() vkBindImageMemory(device, textureImage, textureMemory, 0); - //TODO do barrier here to transition layout... + //TODO copy texture over to optimal layout + //vkCmdCopyBufferToImage(); + + { //transition image + VkCommandBufferAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.commandPool = commandPool; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandBufferCount = 1; + + VkCommandBuffer copyCommandBuffer; + + vkAllocateCommandBuffers(device, &allocInfo, ©CommandBuffer); + + VkImageSubresourceRange subresourceRange = {}; + subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + subresourceRange.baseMipLevel = 0; + subresourceRange.levelCount = 1; + subresourceRange.layerCount = 1; + + VkImageMemoryBarrier imageMemoryBarrier = {}; + imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageMemoryBarrier.image = textureImage; + imageMemoryBarrier.subresourceRange = subresourceRange; + + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + + vkBeginCommandBuffer(copyCommandBuffer, &beginInfo); + + vkCmdPipelineBarrier(copyCommandBuffer, + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); + + vkEndCommandBuffer(copyCommandBuffer); + + VkFenceCreateInfo fenceInfo = {}; + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceInfo.flags = 0; + + VkFence fence; + vkCreateFence(device, &fenceInfo, 0, &fence); + + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = ©CommandBuffer; + + vkQueueSubmit(graphicsQueue, 1, &submitInfo, fence); + + vkWaitForFences(device, 1, &fence, VK_TRUE, -1); + + vkDestroyFence(device, fence, 0); + vkFreeCommandBuffers(device, commandPool, 1, ©CommandBuffer); + } + VkSamplerCreateInfo sampler = {}; sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -1304,22 +1367,22 @@ void CreateTexture() void CreateDescriptorSet() { - /*VkDescriptorSetLayoutBinding setLayoutBinding = {}; - setLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + VkDescriptorSetLayoutBinding setLayoutBinding = {}; + setLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; setLayoutBinding.binding = 0; - setLayoutBinding.descriptorCount = 4; - setLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + setLayoutBinding.descriptorCount = 1; + setLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; VkDescriptorSetLayoutCreateInfo descriptorLayoutCI = {}; descriptorLayoutCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptorLayoutCI.bindingCount = 0;//1; + descriptorLayoutCI.bindingCount = 1; descriptorLayoutCI.pBindings = &setLayoutBinding; vkCreateDescriptorSetLayout(device, &descriptorLayoutCI, 0, &dsl); VkDescriptorPoolSize descriptorPoolSize = {}; descriptorPoolSize.descriptorCount = 1; - descriptorPoolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorPoolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; VkDescriptorPoolCreateInfo descriptorPoolCI = {}; descriptorPoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; @@ -1337,20 +1400,20 @@ void CreateDescriptorSet() vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); - VkDescriptorBufferInfo bufferInfo; - bufferInfo.buffer = uniformBuffer; - bufferInfo.offset = 0; - bufferInfo.range = VK_WHOLE_SIZE; + VkDescriptorImageInfo imageInfo; + imageInfo.imageView = textureView; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageInfo.sampler = textureSampler; VkWriteDescriptorSet writeDescriptorSet = {}; writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSet.dstSet = descriptorSet; writeDescriptorSet.dstBinding = 0; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - writeDescriptorSet.pBufferInfo = &bufferInfo; - writeDescriptorSet.descriptorCount = 4; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = &imageInfo; + writeDescriptorSet.descriptorCount = 1; - vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, 0);*/ + vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, 0); } void CreateVertexBuffer()