diff --git a/example/Vulkan/texture_rect.cpp b/example/Vulkan/texture_rect.cpp index b532ff72..26dde38e 100644 --- a/example/Vulkan/texture_rect.cpp +++ b/example/Vulkan/texture_rect.cpp @@ -69,7 +69,7 @@ private: if(!pipeline) return(false); - texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D")); + texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"),true); if(!texture)return(false); sampler=db->CreateSampler(); diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index c30416d1..90186ef1 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -189,7 +189,7 @@ public: cb->BeginRenderPass(); cb->BindPipeline(ri->GetPipeline()); cb->BindDescriptorSets(ri); - cb->BindVAB(ri); + cb->BindVBO(ri); if (ib) cb->DrawIndexed(ib->GetCount()); diff --git a/inc/hgl/graph/VKCommandBuffer.h b/inc/hgl/graph/VKCommandBuffer.h index 6a69a749..416584f5 100644 --- a/inc/hgl/graph/VKCommandBuffer.h +++ b/inc/hgl/graph/VKCommandBuffer.h @@ -148,7 +148,7 @@ public: void PushConstants(const void *data,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0, size,data);} void PushConstants(const void *data,const uint32_t offset,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,offset, size,data);} - bool BindVAB(RenderableInstance *); + bool BindVBO(RenderableInstance *); void SetViewport (uint32_t first,uint32_t count,const VkViewport *vp) {vkCmdSetViewport(cmd_buf,first,count,vp);} void SetScissor (uint32_t first,uint32_t count,const VkRect2D *sci) {vkCmdSetScissor(cmd_buf,first,count,sci);} @@ -183,14 +183,47 @@ public: //draw class TextureCmdBuffer:public GPUCmdBuffer { + VkImageMemoryBarrier imageMemoryBarrier; + public: - using GPUCmdBuffer::GPUCmdBuffer; + TextureCmdBuffer(const GPUDeviceAttribute *attr,VkCommandBuffer cb):GPUCmdBuffer(attr,cb) + { + imageMemoryBarrier.sType=VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + imageMemoryBarrier.pNext=nullptr; + imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + } template void PipelineBarrier (ARGS...args){vkCmdPipelineBarrier (cmd_buf,args...);} template void CopyBufferToImage (ARGS...args){vkCmdCopyBufferToImage(cmd_buf,args...);} template void CopyImageToBuffer (ARGS...args){vkCmdCopyImageToBuffer(cmd_buf,args...);} template void BlitImage (ARGS...args){vkCmdBlitImage (cmd_buf,args...);} + + void ImageMemoryBarrier(VkImage image, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask, + VkImageLayout oldImageLayout, + VkImageLayout newImageLayout, + VkImageSubresourceRange subresourceRange) + { + imageMemoryBarrier.srcAccessMask = srcAccessMask; + imageMemoryBarrier.dstAccessMask = dstAccessMask; + imageMemoryBarrier.oldLayout = oldImageLayout; + imageMemoryBarrier.newLayout = newImageLayout; + imageMemoryBarrier.image = image; + imageMemoryBarrier.subresourceRange = subresourceRange; + + vkCmdPipelineBarrier( cmd_buf, + srcStageMask, + dstStageMask, + 0, + 0, nullptr, + 0, nullptr, + 1, &imageMemoryBarrier); + } };//class TextureCmdBuffer:public GPUCmdBuffer VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VKTextureLoader.h b/inc/hgl/graph/VKTextureLoader.h new file mode 100644 index 00000000..6bf40b8a --- /dev/null +++ b/inc/hgl/graph/VKTextureLoader.h @@ -0,0 +1,97 @@ +#ifndef HGL_GRAPH_VULKAN_TEXTURE_LOADER_INCLUDE +#define HGL_GRAPH_VULKAN_TEXTURE_LOADER_INCLUDE + +#include + +VK_NAMESPACE_BEGIN +template +class VkTextureLoader:public L +{ +protected: + + GPUDevice *device; + GPUBuffer *buf; + + T *tex; + + bool auto_mipmaps; + +public: + + VkTextureLoader(GPUDevice *dev,const bool am) + { + device =dev; + buf =nullptr; + tex =nullptr; + auto_mipmaps=am; + } + + virtual ~VkTextureLoader() + { + SAFE_CLEAR(buf); + SAFE_CLEAR(tex); + } + + T *GetTexture() + { + T *result=tex; + tex=nullptr; + return result; + } + + void *OnBegin(uint32 total_bytes) override + { + SAFE_CLEAR(buf); + SAFE_CLEAR(tex); + + if(!CheckVulkanFormat(format)) + return(nullptr); + + buf=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,total_bytes); + + if(!buf) + return(nullptr); + + return buf->Map(); + } + + void OnEnd() override + { + buf->Unmap(); + + TextureCreateInfo *tci=new TextureCreateInfo(format); + + tci->type=type; + + VkExtent3D extent; + + extent.width =file_header.width; + extent.height =file_header.height; + extent.depth =file_header.depth; + + tci->SetData(buf,extent); + + if(auto_mipmaps&&file_header.mipmaps<=1) + { + if(device->CheckFormatSupport(format,VK_FORMAT_FEATURE_BLIT_DST_BIT)) + { + tci->usage|=VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + tci->SetAutoMipmaps(); + } + } + else + { + tci->origin_mipmaps= + tci->target_mipmaps=file_header.mipmaps; + } + + tci->mipmap_zero_total_bytes=mipmap_zero_total_bytes; + + tex=device->CreateTexture2D(tci); + + if(tex) + buf=nullptr; + } +};//class VkTextureLoader:public L +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_TEXTURE_LOADER_INCLUDE diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index 54ef620b..a23c411a 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -264,7 +264,7 @@ namespace hgl { last_vbo=ri->GetBufferHash(); - cmd_buf->BindVAB(ri); + cmd_buf->BindVBO(ri); } const IndexBuffer *ib=ri->GetIndexBuffer(); diff --git a/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp b/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp index 4cff33f9..62c2f0c5 100644 --- a/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp +++ b/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp @@ -145,7 +145,7 @@ bool RenderCmdBuffer::BindDescriptorSets(RenderableInstance *ri) return(true); } -bool RenderCmdBuffer::BindVAB(RenderableInstance *ri) +bool RenderCmdBuffer::BindVBO(RenderableInstance *ri) { if(!ri) return(false); diff --git a/src/SceneGraph/Vulkan/VKDeviceTexture.cpp b/src/SceneGraph/Vulkan/VKDeviceTexture.cpp index c4cccb92..ca850eab 100644 --- a/src/SceneGraph/Vulkan/VKDeviceTexture.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceTexture.cpp @@ -58,9 +58,6 @@ namespace void GenerateMipmaps(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels) { - //VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels) { - // Check if image format supports linear blitting - VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.image = image; @@ -79,11 +76,11 @@ namespace for (uint32_t i = 1; i < mipLevels; i++) { - barrier.subresourceRange.baseMipLevel = i - 1; - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + barrier.subresourceRange.baseMipLevel = i - 1; texture_cmd_buf->PipelineBarrier( VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, @@ -115,10 +112,10 @@ namespace 1, &blit, VK_FILTER_LINEAR); - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; texture_cmd_buf->PipelineBarrier( VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, @@ -127,12 +124,12 @@ namespace 1, &barrier); } - barrier.subresourceRange.baseMipLevel = mipLevels - 1; - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.subresourceRange.baseMipLevel = mipLevels - 1; + texture_cmd_buf->PipelineBarrier( VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, @@ -279,12 +276,12 @@ bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) + if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //接下来还有,一般是给自动生成mipmaps { imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; } - else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) + else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //接下来就给fragment shader用了,证明是最后一步 { imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;