From 476a60b99e7de39e108590ce6b6996f9e46fe5d8 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sun, 19 May 2019 13:02:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0TGATexture.cpp/texture=5Frect?= =?UTF-8?q?=EF=BC=8C=E5=AE=8C=E6=88=90=E7=BA=B9=E7=90=86=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BD=86=E4=BC=BC=E4=B9=8E=E6=9C=89?= =?UTF-8?q?=E6=8A=A5=E9=94=99=EF=BC=8C=E5=BE=85=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Vulkan/CMakeLists.txt | 5 + example/Vulkan/TGATexture.cpp | 132 +++++++++++ example/Vulkan/indices_rect.cpp | 2 +- example/Vulkan/texture_rect.cpp | 205 ++++++++++++++++++ inc/hgl/graph/vulkan/VKFormat.h | 9 + .../Vulkan/VKDescriptorSetLayoutCreater.h | 1 + src/RenderDevice/Vulkan/VKDeviceTexture.cpp | 34 ++- src/RenderDevice/Vulkan/VKShaderModule.cpp | 2 +- src/RenderDevice/Vulkan/VKShaderParse.h | 2 +- 9 files changed, 379 insertions(+), 13 deletions(-) create mode 100644 example/Vulkan/TGATexture.cpp create mode 100644 example/Vulkan/texture_rect.cpp diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index 462a8341..8aa2ad61 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -3,5 +3,10 @@ target_link_libraries(${name} ${ULRE}) endmacro() +add_library(TGATexture STATIC TGATexture.cpp) + CreateProject(0.triangle main) CreateProject(1.indices_rect indices_rect) +CreateProject(2.texture_rect texture_rect) + +target_link_libraries(2.texture_rect TGATexture) diff --git a/example/Vulkan/TGATexture.cpp b/example/Vulkan/TGATexture.cpp new file mode 100644 index 00000000..fcb21eb0 --- /dev/null +++ b/example/Vulkan/TGATexture.cpp @@ -0,0 +1,132 @@ +#include +#include +#include + +VK_NAMESPACE_BEGIN +namespace +{ + #pragma pack(push,1) + struct TGAHeader + { + uint8 id; + uint8 color_map_type; + uint8 image_type; // 1 colormap image ,2 true-color,3 grayscale + + uint16 color_map_first; + uint16 color_map_length; + uint8 color_map_size; + + uint16 x_origin; + uint16 y_origin; + + uint16 width; + uint16 height; + uint8 bit; + + uint8 image_desc; + }; + + union TGAImageDesc + { + //不要把此union放到上面的struct中,否则Visual C++会将此union编译成4字节。GCC无此问题 + uint8 image_desc; + struct + { + uint alpha_depth:4; + uint reserved:1; + uint direction:1; //0 lower-left,1 upper left + }; + }; + #pragma pack(pop) + + void RGB8to565(uint8 *data,uint size) + { + uint8 *src=data; + uint16 *target=(uint16 *)data; + + for(uint i=0;i>3); + + ++target; + src+=3; + } + } +}//namespace + +Texture2D *LoadTGATexture(const OSString &filename,Device *device) +{ + uint8 *data; + const int64 file_length=filesystem::LoadFileToMemory(filename,(void **)&data); + + if(file_length<=0) + { + std::cerr<<"[ERROR] open file<"< failed."<image_type==2) + { + if(header->bit==24) + { + RGB8to565(data+sizeof(TGAHeader),header->width*header->height); + + format=FMT_RGB565; + pixels_size=header->width*header->height*2; + } + else if(header->bit==32) + { + format=FMT_RGBA8UN; + pixels_size=header->width*header->height*4; + } + } + else if(header->image_type==3&&header->bit==8) + { + format=FMT_R8UN; + pixels_size=header->width*header->height; + } + else + { + std::cerr<<"[ERROR] Image format error,filename: "<CreateTexture2D(format,data+sizeof(TGAHeader),header->width,header->height,pixels_size); + + if(tex) + { + std::cout<<"load image file<"<:<"<width<<"x"<height<<"> to texture ok"<:<"<width<<"x"<height<<"> to texture failed."<GetRenderPass()); + pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass(),device->GetExtent()); pipeline_creater->SetDepthTest(false); pipeline_creater->SetDepthWrite(false); pipeline_creater->CloseCullFace(); diff --git a/example/Vulkan/texture_rect.cpp b/example/Vulkan/texture_rect.cpp new file mode 100644 index 00000000..43831224 --- /dev/null +++ b/example/Vulkan/texture_rect.cpp @@ -0,0 +1,205 @@ +// 1.indices_rect +// ʾ0.triangleĽʾʹݻһ + +#include"VulkanAppFramework.h" +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +VK_NAMESPACE_BEGIN +Texture2D *LoadTGATexture(const OSString &filename,Device *device); +VK_NAMESPACE_END + +constexpr uint32_t SCREEN_WIDTH=128; +constexpr uint32_t SCREEN_HEIGHT=128; + +struct WorldConfig +{ + Matrix4f mvp; +}world; + +constexpr uint32_t VERTEX_COUNT=4; + +constexpr float vertex_data[VERTEX_COUNT][2]= +{ + {SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.25}, + {SCREEN_WIDTH*0.75, SCREEN_HEIGHT*0.25}, + {SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.75}, + {SCREEN_WIDTH*0.75, SCREEN_HEIGHT*0.75} +}; + +constexpr uint32_t INDEX_COUNT=6; + +constexpr uint16 index_data[INDEX_COUNT]= +{ + 0,1,3, + 0,3,2 +}; + +class TestApp:public VulkanApplicationFramework +{ +private: + + uint swap_chain_count=0; + + vulkan::Material * material =nullptr; + vulkan::Texture2D * texture =nullptr; + vulkan::DescriptorSets * desciptor_sets =nullptr; + vulkan::Renderable * render_obj =nullptr; + vulkan::Buffer * ubo_mvp =nullptr; + + vulkan::Pipeline * pipeline =nullptr; + vulkan::CommandBuffer ** cmd_buf =nullptr; + + vulkan::VertexBuffer * vertex_buffer =nullptr; + vulkan::IndexBuffer * index_buffer =nullptr; + +public: + + ~TestApp() + { + SAFE_CLEAR(index_buffer); + SAFE_CLEAR(vertex_buffer); + SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); + SAFE_CLEAR(pipeline); + SAFE_CLEAR(ubo_mvp); + SAFE_CLEAR(render_obj); + SAFE_CLEAR(desciptor_sets); + SAFE_CLEAR(texture); + SAFE_CLEAR(material); + } + +private: + + bool InitMaterial() + { + material=shader_manage->CreateMaterial(OS_TEXT("OnlyPosition.vert.spv"), + OS_TEXT("FlatColor.frag.spv")); + if(!material) + return(false); + + render_obj=material->CreateRenderable(); + desciptor_sets=material->CreateDescriptorSets(); + + texture=vulkan::LoadTGATexture(OS_TEXT("lena.tga"),device); + return(true); + } + + bool InitUBO() + { + const VkExtent2D extent=device->GetExtent(); + + world.mvp=ortho(extent.width,extent.height); + + ubo_mvp=device->CreateUBO(sizeof(WorldConfig),&world); + + if(!ubo_mvp) + return(false); + + return desciptor_sets->UpdateUBO(material->GetUBO("world"),*ubo_mvp); + } + + void InitVBO() + { + vertex_buffer =device->CreateVBO(FMT_RG32F,VERTEX_COUNT,vertex_data); + index_buffer =device->CreateIBO16(INDEX_COUNT,index_data); + + render_obj->Set("Vertex",vertex_buffer); + render_obj->Set(index_buffer); + } + + bool InitPipeline() + { + vulkan::PipelineCreater * + pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass(),device->GetExtent()); + pipeline_creater->SetDepthTest(false); + pipeline_creater->SetDepthWrite(false); + pipeline_creater->CloseCullFace(); + pipeline_creater->Set(PRIM_TRIANGLES); + + pipeline=pipeline_creater->Create(); + + delete pipeline_creater; + pipeline_creater=nullptr; + + return pipeline; + } + + bool InitCommandBuffer() + { + cmd_buf=hgl_zero_new(swap_chain_count); + + for(uint i=0;iCreateCommandBuffer(); + + if(!cmd_buf[i]) + return(false); + + cmd_buf[i]->Begin(); + cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); + cmd_buf[i]->Bind(pipeline); + cmd_buf[i]->Bind(desciptor_sets); + cmd_buf[i]->Bind(render_obj); + cmd_buf[i]->DrawIndexed(INDEX_COUNT); + cmd_buf[i]->EndRenderPass(); + cmd_buf[i]->End(); + } + + return(true); + } + +public: + + bool Init() + { + if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + swap_chain_count=device->GetSwapChainImageCount(); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + InitVBO(); + + if(!InitPipeline()) + return(false); + + if(!InitCommandBuffer()) + return(false); + + return(true); + } + + void Draw() override + { + const uint32_t frame_index=device->GetCurrentFrameIndices(); + + const vulkan::CommandBuffer *cb=cmd_buf[frame_index]; + + Submit(*cb); + } +};//class TestApp:public VulkanApplicationFramework + +int main(int,char **) +{ +#ifdef _DEBUG + if(!vulkan::CheckStrideBytesByFormat()) + return 0xff; +#endif// + + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/inc/hgl/graph/vulkan/VKFormat.h b/inc/hgl/graph/vulkan/VKFormat.h index 6c409f07..19b847b0 100644 --- a/inc/hgl/graph/vulkan/VKFormat.h +++ b/inc/hgl/graph/vulkan/VKFormat.h @@ -3,6 +3,15 @@ #include +#define FMT_RG4UN VK_FORMAT_R4G4_UNORM_PACK8 +#define FMT_RGBA4 VK_FORMAT_R4G4B4A4_UNORM_PACK16 +#define FMT_BGRA4 VK_FORMAT_B4G4R4A4_UNORM_PACK16 +#define FMT_RGB565 VK_FORMAT_R5G6B5_UNORM_PACK16 +#define FMT_BGR565 VK_FORMAT_B5G6R5_UNORM_PACK16 +#define FMT_RGB5A1 VK_FORMAT_R5G5B5A1_UNORM_PACK16 +#define FMT_BGR5A1 VK_FORMAT_B5G5R5A1_UNORM_PACK16 +#define FMT_A1RGB5 VK_FORMAT_A1R5G5B5_UNORM_PACK16 + #define FMT_R8UN VK_FORMAT_R8_UNORM #define FMT_R8SN VK_FORMAT_R8_SNORM #define FMT_R8U VK_FORMAT_R8_UINT diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h index 8bf57f48..af472986 100644 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h +++ b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h @@ -32,6 +32,7 @@ public: Bind(sr[i],(VkDescriptorType)i,stage); } +//以下代码不再需要,使用一个void Bind(const ShaderResource &sr,VkShaderStageFlagBits stage)即可全部替代,而且更方便,但以此为提示 // //#define DESC_SET_BIND_FUNC(name,vkname) void Bind##name(const uint32_t binding,VkShaderStageFlagBits stage_flag){Bind(binding,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);} \ // void Bind##name(const uint32_t *binding,const uint32_t count,VkShaderStageFlagBits stage_flag){Bind(binding,count,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);} diff --git a/src/RenderDevice/Vulkan/VKDeviceTexture.cpp b/src/RenderDevice/Vulkan/VKDeviceTexture.cpp index 6733fb6f..4435d1ae 100644 --- a/src/RenderDevice/Vulkan/VKDeviceTexture.cpp +++ b/src/RenderDevice/Vulkan/VKDeviceTexture.cpp @@ -22,12 +22,26 @@ Texture2D *Device::CreateTexture2D(const VkFormat video_format,void *data,uint32 { if(!data||width<=1||height<=1)return(nullptr); - if(force_linear) - { - const VkFormatProperties fp=attr->physical_device->GetFormatProperties(video_format); + const VkFormatProperties fp=attr->physical_device->GetFormatProperties(video_format); - if(!(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) //如果不能用线性存储 - force_linear=false; + if(fp.optimalTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) + { + if(force_linear) + { + if(!(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) + force_linear=false; + } + } + else //不能用优化存储,这种现像好像不存在啊 + { + if(!(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) + { + //也不能用线性储存??WTF ? + return(nullptr); + } + + force_linear=true; + return(nullptr); //这个我们暂时不支持 } TextureData *tex_data=new TextureData(); @@ -49,7 +63,7 @@ Texture2D *Device::CreateTexture2D(const VkFormat video_format,void *data,uint32 Buffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data); - VkBufferImageCopy buffer_image_copy; + VkBufferImageCopy buffer_image_copy{}; buffer_image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; buffer_image_copy.imageSubresource.mipLevel = 0; buffer_image_copy.imageSubresource.baseArrayLayer = 0; @@ -63,7 +77,7 @@ Texture2D *Device::CreateTexture2D(const VkFormat video_format,void *data,uint32 VkDeviceMemory device_memory; - VkImageCreateInfo imageCreateInfo; + VkImageCreateInfo imageCreateInfo{}; imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; imageCreateInfo.format = video_format; @@ -78,8 +92,8 @@ Texture2D *Device::CreateTexture2D(const VkFormat video_format,void *data,uint32 imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; VK_CHECK_RESULT(vkCreateImage(attr->device, &imageCreateInfo, nullptr, &tex_data->image)) - VkMemoryAllocateInfo memAllocInfo; - VkMemoryRequirements memReqs; + VkMemoryAllocateInfo memAllocInfo{}; + VkMemoryRequirements memReqs{}; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; @@ -97,7 +111,7 @@ Texture2D *Device::CreateTexture2D(const VkFormat video_format,void *data,uint32 subresourceRange.levelCount = 1; subresourceRange.layerCount = 1; - VkImageMemoryBarrier imageMemoryBarrier; + VkImageMemoryBarrier imageMemoryBarrier{}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; diff --git a/src/RenderDevice/Vulkan/VKShaderModule.cpp b/src/RenderDevice/Vulkan/VKShaderModule.cpp index 1f4901ea..de2f03e0 100644 --- a/src/RenderDevice/Vulkan/VKShaderModule.cpp +++ b/src/RenderDevice/Vulkan/VKShaderModule.cpp @@ -28,7 +28,7 @@ ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo * EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER],sp->GetUBO()); EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER],sp->GetSSBO()); -// EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_SAMPLER],sp->GetSampler()); + EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE],sp->GetSampler()); } ShaderModule::~ShaderModule() diff --git a/src/RenderDevice/Vulkan/VKShaderParse.h b/src/RenderDevice/Vulkan/VKShaderParse.h index 18985d17..e9294555 100644 --- a/src/RenderDevice/Vulkan/VKShaderParse.h +++ b/src/RenderDevice/Vulkan/VKShaderParse.h @@ -31,10 +31,10 @@ public: SHADER_PARSE_GET_RESOURCE(SSBO, storage_buffers) SHADER_PARSE_GET_RESOURCE(StageInputs, stage_inputs) SHADER_PARSE_GET_RESOURCE(StageOutputs, stage_outputs) + SHADER_PARSE_GET_RESOURCE(Sampler, sampled_images) //SmallVector subpass_inputs; //SmallVector storage_images; - //SmallVector sampled_images; //SmallVector atomic_counters; //SmallVector acceleration_structures; //SmallVector push_constant_buffers;