diff --git a/example/Vulkan/FlatColor.vert b/example/Vulkan/FlatColor.vert index e6365cfa..2367742d 100644 --- a/example/Vulkan/FlatColor.vert +++ b/example/Vulkan/FlatColor.vert @@ -3,11 +3,16 @@ layout(location = 0) in vec2 Vertex; layout(location = 1) in vec3 Color; +layout (binding = 0) uniform UBO +{ + mat4 MVP; +} ubo; + layout(location = 0) out vec4 FragmentColor; void main() { FragmentColor=vec4(Color,1.0); - gl_Position=vec4(Vertex,0.0,1.0); + gl_Position=vec4(Vertex,0.0,1.0)*ubo.MVP; } diff --git a/example/Vulkan/VKBuffer.h b/example/Vulkan/VKBuffer.h index 6a4900d7..23b29f87 100644 --- a/example/Vulkan/VKBuffer.h +++ b/example/Vulkan/VKBuffer.h @@ -33,7 +33,9 @@ public: virtual ~Buffer(); - VkBuffer GetBuffer(){return buf.buffer;} + operator VkBuffer (){return buf.buffer;} + operator VkDeviceMemory (){return buf.memory;} + operator VkDescriptorBufferInfo * (){return &buf.info;} virtual uint8_t *Map(uint32_t start=0,uint32_t size=0); void Unmap(); diff --git a/example/Vulkan/VKDescriptorSets.cpp b/example/Vulkan/VKDescriptorSets.cpp index 20cab003..e009ccd8 100644 --- a/example/Vulkan/VKDescriptorSets.cpp +++ b/example/Vulkan/VKDescriptorSets.cpp @@ -2,55 +2,66 @@ #include"VKDevice.h" VK_NAMESPACE_BEGIN -DescriptorSets::~DescriptorSets() +namespace { - // 这里注释掉是因为从来不见那里的范便有FREE过,但又有vkFreeDescriptorSets这个函数。如发现此注释,请使用工具查是否有资源泄露 + void DestroyDescriptorSetLayout(VkDevice device,List &dsl_list) { - //const int count=desc_sets.GetCount(); + const int count=dsl_list.GetCount(); - //if(count>0) - // vkFreeDescriptorSets(device->GetDevice(),device->GetDescriptorPool(),count,desc_sets.GetData()); + if(count>0) + { + VkDescriptorSetLayout *dsl=dsl_list.GetData(); + + for(int i=0;i0) - { - VkDescriptorSetLayout *dsl=desc_set_layout_list.GetData(); + //if(count>0) + // vkFreeDescriptorSets(device->GetDevice(),device->GetDescriptorPool(),count,desc_sets.GetData()); + //} - for(int i=0;iGetDevice(),*dsl,nullptr); - ++dsl; - } - } + DestroyDescriptorSetLayout(*device,desc_set_layout_list); } -DescriptorSets *DescriptorSetLayout::CreateSets()const +bool DescriptorSetLayout::UpdateBuffer(const uint32_t binding,const VkDescriptorBufferInfo *buf_info) { - const int count=desc_set_layout_list.GetCount(); + int index; + + if(!binding_index.Get(binding,index)) + return(false); - if(count<=0) - return(nullptr); + VkDescriptorSet set; + if(!desc_sets.Get(index,set)) + return(false); + // Update the descriptor set determining the shader binding points + // For every binding point used in a shader there needs to be one + // descriptor set matching that binding point - VkDescriptorSetAllocateInfo alloc_info[1]; - alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info[0].pNext = nullptr; - alloc_info[0].descriptorPool = device->GetDescriptorPool(); - alloc_info[0].descriptorSetCount = count; - alloc_info[0].pSetLayouts = desc_set_layout_list.GetData(); + VkWriteDescriptorSet writeDescriptorSet = {}; - List desc_set; + // Binding 0 : Uniform buffer + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = set; + writeDescriptorSet.descriptorCount = 1; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + writeDescriptorSet.pBufferInfo = buf_info; + writeDescriptorSet.dstBinding = binding; - desc_set.SetCount(count); - - if(vkAllocateDescriptorSets(device->GetDevice(), alloc_info, desc_set.GetData())!=VK_SUCCESS) - return(nullptr); - - return(new DescriptorSets(device,desc_set)); + vkUpdateDescriptorSets(device->GetDevice(), 1, &writeDescriptorSet, 0, nullptr); + return(true); } void DescriptorSetLayoutCreater::Bind(const uint32_t binding,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags) @@ -62,7 +73,9 @@ void DescriptorSetLayoutCreater::Bind(const uint32_t binding,VkDescriptorType de layout_binding.stageFlags = stageFlags; layout_binding.pImmutableSamplers = nullptr; - layout_binding_list.Add(layout_binding); + const int index=layout_binding_list.Add(layout_binding); + + binding_index.Add(binding,index); } DescriptorSetLayout *DescriptorSetLayoutCreater::Create() @@ -84,6 +97,23 @@ DescriptorSetLayout *DescriptorSetLayoutCreater::Create() if(vkCreateDescriptorSetLayout(device->GetDevice(),&descriptor_layout, nullptr, dsl_list.GetData())!=VK_SUCCESS) return(nullptr); - return(new DescriptorSetLayout(device,dsl_list)); + VkDescriptorSetAllocateInfo alloc_info; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.pNext = nullptr; + alloc_info.descriptorPool = device->GetDescriptorPool(); + alloc_info.descriptorSetCount = count; + alloc_info.pSetLayouts = dsl_list.GetData(); + + List desc_set; + + desc_set.SetCount(count); + + if(vkAllocateDescriptorSets(device->GetDevice(), &alloc_info, desc_set.GetData())!=VK_SUCCESS) + { + DestroyDescriptorSetLayout(*device,dsl_list); + return(nullptr); + } + + return(new DescriptorSetLayout(device,dsl_list,desc_set,binding_index)); } VK_NAMESPACE_END diff --git a/example/Vulkan/VKDescriptorSets.h b/example/Vulkan/VKDescriptorSets.h index f9f8c8e1..b4d8e363 100644 --- a/example/Vulkan/VKDescriptorSets.h +++ b/example/Vulkan/VKDescriptorSets.h @@ -2,41 +2,37 @@ #define HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE #include"VK.h" +#include VK_NAMESPACE_BEGIN class Device; -class DescriptorSets -{ - Device *device; - List desc_sets; - -public: - - DescriptorSets(Device *dev,List &ds):device(dev),desc_sets(ds){} - ~DescriptorSets(); - - const uint32_t GetCount()const{return desc_sets.GetCount();} - const VkDescriptorSet * GetData()const{return desc_sets.GetData();} -};//class DescriptorSets class DescriptorSetLayout { Device *device; List desc_set_layout_list; + List desc_sets; + + Map binding_index; public: - DescriptorSetLayout(Device *dev,const List &dsl_list) + DescriptorSetLayout(Device *dev,const List &dsl_list,List &ds_list, + Map &bi) { device=dev; desc_set_layout_list=dsl_list; + desc_sets=ds_list; + binding_index=bi; } ~DescriptorSetLayout(); - const uint32_t GetCount()const{return desc_set_layout_list.GetCount();} - const VkDescriptorSetLayout * GetData ()const{return desc_set_layout_list.GetData();} + const uint32_t GetCount ()const{return desc_set_layout_list.GetCount();} + const VkDescriptorSetLayout * GetLayouts ()const{return desc_set_layout_list.GetData();} - DescriptorSets *CreateSets()const; + const List & GetSets ()const{return desc_sets;} + + bool UpdateBuffer(const uint32_t binding,const VkDescriptorBufferInfo *buf_info); };//class DescriptorSetLayout /** @@ -49,6 +45,8 @@ class DescriptorSetLayoutCreater List layout_binding_list; + Map binding_index; + public: DescriptorSetLayoutCreater(Device *dev):device(dev){} diff --git a/example/Vulkan/VKInstance.cpp b/example/Vulkan/VKInstance.cpp index 918c38b7..03e61bf8 100644 --- a/example/Vulkan/VKInstance.cpp +++ b/example/Vulkan/VKInstance.cpp @@ -133,7 +133,7 @@ Instance *CreateInstance(const UTF8String &app_name) "VK_LAYER_LUNARG_standard_validation", "VK_LAYER_LUNARG_parameter_validation", // "VK_LAYER_LUNARG_vktrace", -// "VK_LAYER_RENDERDOC_Capture", + "VK_LAYER_RENDERDOC_Capture", // "VK_LAYER_KHRONOS_validation", diff --git a/example/Vulkan/VKPipelineLayout.cpp b/example/Vulkan/VKPipelineLayout.cpp index 524390bf..2bd1d0cd 100644 --- a/example/Vulkan/VKPipelineLayout.cpp +++ b/example/Vulkan/VKPipelineLayout.cpp @@ -11,7 +11,7 @@ PipelineLayout::~PipelineLayout() PipelineLayout *CreatePipelineLayout(VkDevice dev,const DescriptorSetLayout *dsl) { const uint32_t layout_count=(dsl?dsl->GetCount():0); - const VkDescriptorSetLayout *layouts=(layout_count>0?dsl->GetData():nullptr); + const VkDescriptorSetLayout *layouts=(layout_count>0?dsl->GetLayouts():nullptr); VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {}; pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; @@ -26,8 +26,6 @@ PipelineLayout *CreatePipelineLayout(VkDevice dev,const DescriptorSetLayout *dsl if(vkCreatePipelineLayout(dev, &pPipelineLayoutCreateInfo, nullptr, &pipeline_layout)!=VK_SUCCESS) return(nullptr); - DescriptorSets *desc_sets=(layout_count>0?dsl->CreateSets():nullptr); - - return(new PipelineLayout(dev,pipeline_layout,desc_sets)); + return(new PipelineLayout(dev,pipeline_layout,dsl->GetSets())); } VK_NAMESPACE_END diff --git a/example/Vulkan/VKPipelineLayout.h b/example/Vulkan/VKPipelineLayout.h index 785a415f..5057cde2 100644 --- a/example/Vulkan/VKPipelineLayout.h +++ b/example/Vulkan/VKPipelineLayout.h @@ -9,13 +9,13 @@ class PipelineLayout VkDevice device; VkPipelineLayout layout; - const DescriptorSets *desc_sets; + List desc_sets; private: friend PipelineLayout *CreatePipelineLayout(VkDevice dev,const DescriptorSetLayout *dsl); - PipelineLayout(VkDevice dev,VkPipelineLayout pl,const DescriptorSets *ds){device=dev;layout=pl;desc_sets=ds;} + PipelineLayout(VkDevice dev,VkPipelineLayout pl,const List &ds){device=dev;layout=pl;desc_sets=ds;} public: @@ -23,8 +23,8 @@ public: operator VkPipelineLayout (){return layout;} - const uint32_t GetDescriptorSetCount ()const{return desc_sets?desc_sets->GetCount():0;} - const VkDescriptorSet * GetDescriptorSets ()const{return desc_sets?desc_sets->GetData():nullptr;} + const uint32_t GetDescriptorSetCount ()const{return desc_sets.GetCount();} + const VkDescriptorSet * GetDescriptorSets ()const{return desc_sets.GetData();} };//class PipelineLayout PipelineLayout *CreatePipelineLayout(VkDevice dev,const DescriptorSetLayout *dsl); diff --git a/example/Vulkan/VKVertexInput.cpp b/example/Vulkan/VKVertexInput.cpp index 5f50aa15..495a6df7 100644 --- a/example/Vulkan/VKVertexInput.cpp +++ b/example/Vulkan/VKVertexInput.cpp @@ -22,7 +22,7 @@ bool VertexInput::Add(uint32_t location,VertexBuffer *buf,bool instance,VkDevice attrib.offset=offset; vib_list.Add(new VertexInputBuffer(binding,attrib,buf)); - buf_list.Add(buf->GetBuffer()); + buf_list.Add(*buf); buf_offset.Add(offset); binding_list.Add(binding); diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index 470cd426..c991b8c7 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -14,6 +14,7 @@ #include"VKSemaphore.h" #include"VKFormat.h" #include"VKFramebuffer.h" +#include #include #ifdef WIN32 @@ -24,9 +25,17 @@ using namespace hgl; using namespace hgl::graph; +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + VkShaderModule vs=nullptr; VkShaderModule fs=nullptr; +struct +{ + Matrix4f mvp; +}ubo_vs; + char *LoadFile(const char *filename,uint32_t &file_length) { std::ifstream fs; @@ -74,7 +83,33 @@ vulkan::Shader *LoadShader(VkDevice device) return(nullptr); } -constexpr float vertex_data[]={0.0f,0.5f, -0.5f,-0.5f, 0.5f,-0.5f }; +vulkan::Buffer *CreateUBO(vulkan::Device *dev,vulkan::Shader *shader) +{ + { + const VkExtent2D extent=dev->GetExtent(); + + ubo_vs.mvp=ortho2d(extent.width,extent.height); + } + + vulkan::Buffer *ubo=dev->CreateUBO(sizeof(ubo_vs)); + + uint8_t *p=ubo->Map(); + + if(p) + { + memcpy(p,&ubo_vs,sizeof(ubo_vs)); + ubo->Unmap(); + } + + return ubo; +} + +constexpr float vertex_data[]= +{ + SCREEN_WIDTH/2,SCREEN_HEIGHT/4, + SCREEN_WIDTH*3/4,SCREEN_HEIGHT*3/4, + SCREEN_WIDTH/4,SCREEN_HEIGHT*3/4 +}; constexpr float color_data[]={1,0,0, 0,1,0, 0,0,1 }; vulkan::VertexBuffer *vertex_buffer=nullptr; @@ -131,7 +166,7 @@ int main(int,char **) Window *win=CreateRenderWindow(OS_TEXT("VulkanTest")); - win->Create(1280,720); + win->Create(SCREEN_WIDTH,SCREEN_HEIGHT); vulkan::Instance *inst=vulkan::CreateInstance(U8_TEXT("VulkanTest")); @@ -156,21 +191,13 @@ int main(int,char **) std::cout<<"auto select physical device: "<GetDeviceName()<CreateUBO(1024); - - //uint8_t *p=ubo->Map(); - - //if(p) - //{ - // memset(p,0,1024); - // ubo->Unmap(); - //} - vulkan::Shader *shader=LoadShader(device->GetDevice()); if(!shader) return -3; + vulkan::Buffer *ubo=CreateUBO(device,shader); + vulkan::Semaphore *sem=device->CreateSem(); vulkan::VertexInput *vi=CreateVertexBuffer(device); @@ -178,7 +205,13 @@ int main(int,char **) vulkan::PipelineCreater pc(device); vulkan::DescriptorSetLayoutCreater dslc(device); + + dslc.BindUBO(0,VK_SHADER_STAGE_VERTEX_BIT); + vulkan::DescriptorSetLayout *dsl=dslc.Create(); + + dsl->UpdateBuffer(0,*ubo); + vulkan::PipelineLayout *pl=CreatePipelineLayout(*device,dsl); pc.Set(shader); @@ -219,7 +252,7 @@ int main(int,char **) delete sem; delete vi; -// delete ubo; + delete ubo; delete shader;