From 1d499ffd5b3cc056a78c1d32f3b0b5cd5e09ae09 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Fri, 7 Jan 2022 16:55:39 +0800 Subject: [PATCH] added Cubemap support,but only test non-mipmaps texture. --- CMCore | 2 +- CMSceneGraph | 2 +- example/Vulkan/Cubemap.cpp | 178 ++++++++++++ inc/hgl/graph/VKDevice.h | 7 +- inc/hgl/graph/VKRenderResource.h | 1 + res | 2 +- src/SceneGraph/CMakeLists.txt | 5 +- .../Vulkan/Texture/BufferImageCopy2D.h | 6 + .../Vulkan/Texture/GenMipmaps2D.cpp | 6 +- .../Vulkan/Texture/GenMipmapsCube.cpp | 70 +++++ .../Vulkan/Texture/VKDeviceTexture2D.cpp | 2 +- .../Vulkan/Texture/VKDeviceTextureCube.cpp | 254 ++++++++++-------- src/SceneGraph/Vulkan/VKRenderResource.cpp | 20 ++ 13 files changed, 436 insertions(+), 119 deletions(-) create mode 100644 example/Vulkan/Cubemap.cpp create mode 100644 src/SceneGraph/Vulkan/Texture/GenMipmapsCube.cpp diff --git a/CMCore b/CMCore index 1cefb338..c667f679 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 1cefb338da8887ceaf800aecc9e1bc24dee63e8c +Subproject commit c667f679c6189a803c001230ec3cc2a324e3a176 diff --git a/CMSceneGraph b/CMSceneGraph index 26a383ee..45102e04 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 26a383ee11a8f49b87ab7999110e3b9539202d37 +Subproject commit 45102e04208043bf1ae84f9c58d4a56278527844 diff --git a/example/Vulkan/Cubemap.cpp b/example/Vulkan/Cubemap.cpp new file mode 100644 index 00000000..c6710cd7 --- /dev/null +++ b/example/Vulkan/Cubemap.cpp @@ -0,0 +1,178 @@ +// Cubemap +// CubeÌùͼ²âÊÔ + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +class TestApp:public CameraAppFramework +{ +private: + + SceneNode render_root; + RenderList * render_list =nullptr; + + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; + + Pipeline * pipeline_solid =nullptr; + + GPUBuffer * ubo_light =nullptr; + GPUBuffer * ubo_phong =nullptr; + + Sampler * sampler =nullptr; + TextureCube * texture =nullptr; + + Renderable * ro_cube =nullptr; + +private: + + bool InitMaterial() + { + { + texture =db->LoadTextureCube(OS_TEXT("res/cubemap/Test/Test.TexCube"),false); + + if(!texture) + return(false); + + VkSamplerCreateInfo sampler_create_info= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_NEAREST, + VK_FILTER_NEAREST, + VK_SAMPLER_MIPMAP_MODE_NEAREST, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, + VK_FALSE, + 0, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + false + }; + + sampler =db->CreateSampler(&sampler_create_info); + } + + { + material=db->CreateMaterial(OS_TEXT("res/material/Skybox")); + if(!material)return(false); + + material_instance=db->CreateMaterialInstance(material); + if(!material_instance)return(false); + + { + MaterialParameters *mp_texture=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex" ,texture, sampler)) + return(false); + + mp_texture->Update(); + } + } + + pipeline_solid=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Triangles); + if(!pipeline_solid)return(false); + + return(true); + } + + void CreateRenderObject() + { + const VAB *vab=material_instance->GetVAB(); + + { + struct CubeCreateInfo cci; + + ro_cube=CreateRenderableCube(db,vab,&cci); + } + } + + void Add(Renderable *r,Pipeline *pl) + { + auto ri=db->CreateRenderableInstance(r,material_instance,pl); + + render_root.CreateSubNode(ri); + } + + void Add(Renderable *r,Pipeline *pl,const Matrix4f &mat) + { + auto ri=db->CreateRenderableInstance(r,material_instance,pl); + + render_root.CreateSubNode(mat,ri); + } + + bool InitScene() + { + Add(ro_cube,pipeline_solid); + + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + render_list=new RenderList(device); + + if(!InitMaterial()) + return(false); + + CreateRenderObject(); + + if(!InitScene()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32_t index) override + { + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/inc/hgl/graph/VKDevice.h b/inc/hgl/graph/VKDevice.h index 80596e77..7246a0da 100644 --- a/inc/hgl/graph/VKDevice.h +++ b/inc/hgl/graph/VKDevice.h @@ -160,7 +160,12 @@ private: //texture bool CommitTexture2DMipmaps (Texture2D *,GPUBuffer *buf,const VkExtent3D &,uint32_t); bool CommitTexture2D (Texture2D *,GPUBuffer *buf,const VkBufferImageCopy *,const int count,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - bool SubmitTexture (const VkCommandBuffer *cmd_bufs,const uint32_t count=1); ///<æäº¤çº¹ç†å¤„ç†åˆ°é˜Ÿåˆ— + bool SubmitTexture (const VkCommandBuffer *cmd_bufs,const uint32_t count=1); ///<æäº¤çº¹ç†å¤„ç†åˆ°é˜Ÿåˆ— + + + bool CommitTextureCube (TextureCube *,GPUBuffer *buf,const uint32_t mipmaps_zero_bytes,VkPipelineStageFlags stage); + bool CommitTextureCubeMipmaps (TextureCube *,GPUBuffer *buf,const VkExtent3D &,uint32_t); + bool CommitTextureCube (TextureCube *,GPUBuffer *buf,const VkBufferImageCopy *,const int count,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); public: //Texture diff --git a/inc/hgl/graph/VKRenderResource.h b/inc/hgl/graph/VKRenderResource.h index 79544a0b..4b702bfb 100644 --- a/inc/hgl/graph/VKRenderResource.h +++ b/inc/hgl/graph/VKRenderResource.h @@ -104,6 +104,7 @@ public: //Material public: //texture Texture2D * LoadTexture2D(const OSString &,bool auto_mipmaps=false); + TextureCube * LoadTextureCube(const OSString &,bool auto_mipmaps=false); public: //Get diff --git a/res b/res index bb3e05f4..23303f0a 160000 --- a/res +++ b/res @@ -1 +1 @@ -Subproject commit bb3e05f43bcbc2e2cafa1e1e639a8d626e0af738 +Subproject commit 23303f0aff3ac24351f4f872fe657ea8c8172c1e diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 10e22492..f15d6662 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -115,14 +115,15 @@ SET(VK_MEMORY_SOURCE ${SG_INCLUDE_PATH}/VKMemory.h SET(VK_DEVICE_TEXTURE_SOURCE Vulkan/Texture/BufferImageCopy2D.h Vulkan/Texture/GenMipmaps2D.cpp + Vulkan/Texture/GenMipmapsCube.cpp Vulkan/Texture/VKDeviceTexture.cpp Vulkan/Texture/VKDeviceTexture2D.cpp Vulkan/Texture/VKDeviceTextureCube.cpp) SET(VK_TEXTURE_LOADER_SOURCE ${SG_INCLUDE_PATH}/VKTextureCreateInfo.h Vulkan/Texture/VKTextureLoader.h - Vulkan/Texture/VKTexture2DLoader.cpp) - #Vulkan/Texture/VKTextureCubeLoader.cpp) + Vulkan/Texture/VKTexture2DLoader.cpp + Vulkan/Texture/VKTextureCubeLoader.cpp) SET(VK_DEVICE_SOURCE ${SG_INCLUDE_PATH}/VKDevice.h ${SG_INCLUDE_PATH}/VKDeviceAttribute.h diff --git a/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h b/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h index e31abd92..db4b1160 100644 --- a/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h +++ b/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h @@ -22,6 +22,12 @@ public: SetRectScope(0,0,tex->GetWidth(),tex->GetHeight()); } + BufferImageCopy(const TextureCube *tex):BufferImageCopy() + { + imageSubresource.aspectMask=tex->GetAspect(); + SetRectScope(0,0,tex->GetWidth(),tex->GetHeight()); + } + void Set(const VkImageAspectFlags aspect_mask,const uint32_t layer_count) { imageSubresource.aspectMask=aspect_mask; diff --git a/src/SceneGraph/Vulkan/Texture/GenMipmaps2D.cpp b/src/SceneGraph/Vulkan/Texture/GenMipmaps2D.cpp index 5b382150..9f636cb1 100644 --- a/src/SceneGraph/Vulkan/Texture/GenMipmaps2D.cpp +++ b/src/SceneGraph/Vulkan/Texture/GenMipmaps2D.cpp @@ -17,7 +17,6 @@ void GenerateMipmaps2D(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAs int32_t width =extent.width; int32_t height =extent.height; - int32_t depth =extent.depth; for (uint32_t i = 1; i < mipLevels; i++) { @@ -32,14 +31,13 @@ void GenerateMipmaps2D(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAs VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresourceRange); - blit.srcOffsets[1] = {width,height,depth}; + blit.srcOffsets[1] = {width,height,1}; blit.srcSubresource.mipLevel = i - 1; if(width >1)width >>=1; if(height>1)height>>=1; - if(depth >1)depth >>=1; - blit.dstOffsets[1] = {width,height,depth}; + blit.dstOffsets[1] = {width,height,1}; blit.dstSubresource.mipLevel = i; texture_cmd_buf->BlitImage( diff --git a/src/SceneGraph/Vulkan/Texture/GenMipmapsCube.cpp b/src/SceneGraph/Vulkan/Texture/GenMipmapsCube.cpp new file mode 100644 index 00000000..320f7d79 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/GenMipmapsCube.cpp @@ -0,0 +1,70 @@ +#include + +VK_NAMESPACE_BEGIN +void GenerateMipmapsCube(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels) +{ + ImageSubresourceRange subresourceRange(aspect_mask); + + VkImageBlit blit; + + blit.srcOffsets[0] = {0, 0, 0}; + blit.srcSubresource.aspectMask = aspect_mask; + blit.srcSubresource.baseArrayLayer = 0; + blit.srcSubresource.layerCount = 6; + + blit.dstOffsets[0] = {0, 0, 0}; + blit.dstSubresource=blit.srcSubresource; + + int32_t width =extent.width; + int32_t height =extent.height; + + for (uint32_t i = 1; i < mipLevels; i++) + { + subresourceRange.baseMipLevel = i - 1; + + texture_cmd_buf->ImageMemoryBarrier(image, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + subresourceRange); + + blit.srcOffsets[1] = {width,height,1}; + blit.srcSubresource.mipLevel = i - 1; + + if(width >1)width >>=1; + if(height>1)height>>=1; + + blit.dstOffsets[1] = {width,height,1}; + blit.dstSubresource.mipLevel = i; + + texture_cmd_buf->BlitImage( + image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &blit, + VK_FILTER_LINEAR); + + texture_cmd_buf->ImageMemoryBarrier(image, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange); + } + + subresourceRange.baseMipLevel = mipLevels - 1; + + texture_cmd_buf->ImageMemoryBarrier(image, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp b/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp index fb2d85c3..a809a6c9 100644 --- a/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp +++ b/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp @@ -74,7 +74,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci) if(tci->origin_mipmaps<=1) //本身ä¸å«mipmapsæ•°æ®,åˆæƒ³è¦mipmaps { CommitTexture2D(tex,tci->buffer,VK_PIPELINE_STAGE_TRANSFER_BIT); - GenerateMipmaps2D(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel); + GenerateMipmaps2D(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel); } texture_cmd_buf->End(); diff --git a/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp b/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp index 02117844..936aee97 100644 --- a/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp +++ b/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp @@ -3,7 +3,7 @@ #include #include"BufferImageCopy2D.h" VK_NAMESPACE_BEGIN -void GenerateMipmaps2D(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels); +void GenerateMipmapsCube(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels); TextureCube *GPUDevice::CreateTextureCube(TextureData *tex_data) { @@ -59,18 +59,18 @@ TextureCube *GPUDevice::CreateTextureCube(TextureCreateInfo *tci) { if(tci->target_mipmaps<=1) //±¾Éí²»º¬mipmaps£¬µ«Ò²²»Òªmipmaps { - CommitTexture2D(tex,tci->buffer,tci->extent.width,tci->extent.height,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + CommitTextureCube(tex,tci->buffer,tci->mipmap_zero_total_bytes,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); } else //±¾ÉíÓÐmipmapsÊý¾Ý { - CommitTexture2DMipmaps(tex,tci->buffer,tci->extent.width,tci->extent.height,tci->mipmap_zero_total_bytes); + CommitTextureCubeMipmaps(tex,tci->buffer,tci->extent,tci->mipmap_zero_total_bytes); } } else if(tci->origin_mipmaps<=1) //±¾Éí²»º¬mipmapsÊý¾Ý,ÓÖÏëÒªmipmaps { - CommitTexture2D(tex,tci->buffer,tci->extent.width,tci->extent.height,VK_PIPELINE_STAGE_TRANSFER_BIT); - GenerateMipmaps2D(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel); + CommitTextureCube(tex,tci->buffer,tci->mipmap_zero_total_bytes,VK_PIPELINE_STAGE_TRANSFER_BIT); + GenerateMipmapsCube(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel); } texture_cmd_buf->End(); @@ -79,111 +79,149 @@ TextureCube *GPUDevice::CreateTextureCube(TextureCreateInfo *tci) delete tci->buffer; } - delete tci; + delete tci; //"delete tci" is correct,please don't use "Clear(tci)" return tex; } -// -//bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,VkPipelineStageFlags destinationStage) -//{ -// if(!tex||!buf) -// return(false); -// -// ImageSubresourceRange subresourceRange(tex->GetAspect(),tex->GetMipLevel()); -// -// texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), -// VK_PIPELINE_STAGE_HOST_BIT, -// VK_PIPELINE_STAGE_TRANSFER_BIT, -// 0, -// VK_ACCESS_TRANSFER_WRITE_BIT, -// VK_IMAGE_LAYOUT_UNDEFINED, -// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, -// subresourceRange); -// -// texture_cmd_buf->CopyBufferToImage( -// buf->GetBuffer(), -// tex->GetImage(), -// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, -// count, -// buffer_image_copy); -// -// if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //½ÓÏÂÀ´»¹ÓУ¬Ò»°ãÊǸø×Ô¶¯Éú³Émipmaps -// { -// texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), -// VK_PIPELINE_STAGE_TRANSFER_BIT, -// VK_PIPELINE_STAGE_TRANSFER_BIT, -// VK_ACCESS_TRANSFER_WRITE_BIT, -// VK_ACCESS_TRANSFER_WRITE_BIT, -// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, -// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, -// subresourceRange); -// } -// else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //½ÓÏÂÀ´¾Í¸øfragment shaderÓÃÁË£¬Ö¤Ã÷ÊÇ×îºóÒ»²½ -// { -// texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), -// VK_PIPELINE_STAGE_TRANSFER_BIT, -// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, -// VK_ACCESS_TRANSFER_WRITE_BIT, -// VK_ACCESS_SHADER_READ_BIT, -// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, -// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, -// subresourceRange); -// } -// -// return(true); -//} -// -//bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t width,uint32_t height,VkPipelineStageFlags destinationStage) -//{ -// if(!tex||!buf)return(false); -// -// BufferImageCopy buffer_image_copy(tex); -// -// return CommitTexture2D(tex,buf,&buffer_image_copy,1,destinationStage); -//} -// -//bool GPUDevice::CommitTexture2DMipmaps(Texture2D *tex,GPUBuffer *buf,uint32_t width,uint32_t height,uint32_t total_bytes) -//{ -// if(!tex||!buf -// ||width<=0||height<=0) -// return(false); -// -// const uint32_t miplevel=tex->GetMipLevel(); -// -// AutoDeleteArray buffer_image_copy(miplevel); -// -// VkDeviceSize offset=0; -// uint32_t level=0; -// -// buffer_image_copy.zero(); -// -// for(VkBufferImageCopy &bic:buffer_image_copy) -// { -// bic.bufferOffset = offset; -// bic.bufferRowLength = 0; -// bic.bufferImageHeight = 0; -// bic.imageSubresource.aspectMask = tex->GetAspect(); -// bic.imageSubresource.mipLevel = level++; -// bic.imageSubresource.baseArrayLayer = 0; -// bic.imageSubresource.layerCount = 1; -// bic.imageOffset.x = 0; -// bic.imageOffset.y = 0; -// bic.imageOffset.z = 0; -// bic.imageExtent.width = width; -// bic.imageExtent.height= height; -// bic.imageExtent.depth = 1; -// -// if(total_bytes<8) -// offset+=8; -// else -// offset+=total_bytes; -// -// if(width>1){width>>=1;total_bytes>>=1;} -// if(height>1){height>>=1;total_bytes>>=1;} -// } -// -// return CommitTexture2D(tex,buf,buffer_image_copy,miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); -//} -// + +bool GPUDevice::CommitTextureCube(TextureCube *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf) + return(false); + + ImageSubresourceRange subresourceRange(tex->GetAspect(),tex->GetMipLevel(),6); + + texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + subresourceRange); + + texture_cmd_buf->CopyBufferToImage( + buf->GetBuffer(), + tex->GetImage(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + count, + buffer_image_copy); + + if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //½ÓÏÂÀ´»¹ÓУ¬Ò»°ãÊǸø×Ô¶¯Éú³Émipmaps + { + texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + subresourceRange); + } + else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //½ÓÏÂÀ´¾Í¸øfragment shaderÓÃÁË£¬Ö¤Ã÷ÊÇ×îºóÒ»²½ + { + texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange); + } + + return(true); +} + +bool GPUDevice::CommitTextureCube(TextureCube *tex,GPUBuffer *buf,const uint32_t mipmaps_zero_bytes,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf||!mipmaps_zero_bytes)return(false); + + AutoDeleteArray bic_list(6); + + uint32_t face=0; + uint32_t offset=0; + + for(VkBufferImageCopy &bic:bic_list) + { + bic.bufferOffset = offset; + bic.bufferRowLength = 0; + bic.bufferImageHeight = 0; + bic.imageSubresource.aspectMask = tex->GetAspect(); + bic.imageSubresource.mipLevel = 0; + bic.imageSubresource.baseArrayLayer = face; + bic.imageSubresource.layerCount = 1; + bic.imageOffset.x = 0; + bic.imageOffset.y = 0; + bic.imageOffset.z = 0; + bic.imageExtent.width = tex->GetWidth(); + bic.imageExtent.height= tex->GetHeight(); + bic.imageExtent.depth = 1; + + ++face; + offset+=mipmaps_zero_bytes; + } + + return CommitTextureCube(tex,buf,bic_list,6,destinationStage); +} + +bool GPUDevice::CommitTextureCubeMipmaps(TextureCube *tex,GPUBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes) +{ + if(!tex||!buf + ||extent.width*extent.height<=0) + return(false); + + const uint32_t miplevel=tex->GetMipLevel(); + + AutoDeleteArray buffer_image_copy(miplevel*6); + + VkDeviceSize offset=0; + + uint32_t face=0; + uint32_t level=0; + + uint32_t width=extent.width; + uint32_t height=extent.height; + + buffer_image_copy.zero(); + + for(VkBufferImageCopy &bic:buffer_image_copy) + { + bic.bufferOffset = offset; + bic.bufferRowLength = 0; + bic.bufferImageHeight = 0; + bic.imageSubresource.aspectMask = tex->GetAspect(); + bic.imageSubresource.mipLevel = level; + bic.imageSubresource.baseArrayLayer = face; + bic.imageSubresource.layerCount = 1; + bic.imageOffset.x = 0; + bic.imageOffset.y = 0; + bic.imageOffset.z = 0; + bic.imageExtent.width = width; + bic.imageExtent.height= height; + bic.imageExtent.depth = 1; + + if(total_bytes<8) + offset+=8; + else + offset+=total_bytes; + + if(face==5) + { + face=0; + ++level; + + if(width>1){width>>=1;total_bytes>>=1;} + if(height>1){height>>=1;total_bytes>>=1;} + } + else + { + ++face; + } + } + + return CommitTextureCube(tex,buf,buffer_image_copy,miplevel*6,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); +} + //bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List &ir_list,VkPipelineStageFlags destinationStage) //{ // if(!tex||!buf||ir_list.GetCount()<=0) diff --git a/src/SceneGraph/Vulkan/VKRenderResource.cpp b/src/SceneGraph/Vulkan/VKRenderResource.cpp index c3da262b..ab2653cd 100644 --- a/src/SceneGraph/Vulkan/VKRenderResource.cpp +++ b/src/SceneGraph/Vulkan/VKRenderResource.cpp @@ -148,4 +148,24 @@ Texture2D *RenderResource::LoadTexture2D(const OSString &filename,bool auto_mipm return tex; } + +TextureCube *CreateTextureCubeFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps); + +TextureCube *RenderResource::LoadTextureCube(const OSString &filename,bool auto_mipmaps) +{ + TextureCube *tex; + + if(texture_by_name.Get(filename,(Texture *&)tex)) + return tex; + + tex=CreateTextureCubeFromFile(device,filename,auto_mipmaps); + + if(tex) + { + texture_by_name.Add(filename,tex); + Add(tex); + } + + return tex; +} VK_NAMESPACE_END