diff --git a/example/Vulkan/VKPipeline.cpp b/example/Vulkan/VKPipeline.cpp index ffdf7a42..e7e71ae6 100644 --- a/example/Vulkan/VKPipeline.cpp +++ b/example/Vulkan/VKPipeline.cpp @@ -162,15 +162,12 @@ bool PipelineCreater::Set(const Shader *s) return(true); } -bool PipelineCreater::Set(const VertexInput *vi) +bool PipelineCreater::Set(const VertexInputState *vis) { - if(!vi)return(false); - if(vi->GetCount()<=0)return(false); - - vertex_input=vi; - - vis_create_info=vertex_input->GetPipelineVertexInputStateCreateInfo(); + if(!vis) + return(false); + vis->Write(vis_create_info); return(true); } diff --git a/example/Vulkan/VKPipeline.h b/example/Vulkan/VKPipeline.h index 3b1fe4bb..4bb49708 100644 --- a/example/Vulkan/VKPipeline.h +++ b/example/Vulkan/VKPipeline.h @@ -6,6 +6,7 @@ VK_NAMESPACE_BEGIN class Device; class RenderPass; +class VertexInputState; class Pipeline { @@ -59,7 +60,7 @@ public: ~PipelineCreater()=default; bool Set(const Shader *); - bool Set(const VertexInput *); + bool Set(const VertexInputState *); bool Set(const VkPrimitiveTopology,bool=false); bool Set(VkPipelineLayout pl); diff --git a/example/Vulkan/VKVertexInput.cpp b/example/Vulkan/VKVertexInput.cpp index 495a6df7..bc6f214f 100644 --- a/example/Vulkan/VKVertexInput.cpp +++ b/example/Vulkan/VKVertexInput.cpp @@ -2,46 +2,75 @@ #include"VKBuffer.h" VK_NAMESPACE_BEGIN -bool VertexInput::Add(uint32_t location,VertexBuffer *buf,bool instance,VkDeviceSize offset) + +void VertexInputState::Add(const uint32_t shader_location,const VkFormat format,uint32_t offset,bool instance) { - if(!buf) - return(false); + const int binding_index=binding_list.GetCount(); //参考opengl vab,binding_index必须从0开始,紧密排列。对应在vkCmdBindVertexBuffer中的缓冲区索引 - const int binding_index=vib_list.GetCount(); //参考opengl vab,binding_index必须从0开始,紧密排列。对应在vkCmdBindVertexBuffer中的缓冲区索引 + binding_list.SetCount(binding_index+1); + attribute_list.SetCount(binding_index+1); - VkVertexInputBindingDescription binding; - VkVertexInputAttributeDescription attrib; + VkVertexInputBindingDescription *binding=binding_list.GetData()+binding_index; + VkVertexInputAttributeDescription *attrib=attribute_list.GetData()+binding_index; - binding.binding=binding_index; - binding.stride=buf->GetStride(); - binding.inputRate=instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; + binding->binding=binding_index; + binding->stride=GetStrideByFormat(format); + binding->inputRate=instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; + + //实际使用可以一个binding绑多个attrib,但我们仅支持1v1。 + //一个binding是指在vertex shader中,由一个vertex输入流输入数据,attrib指其中的数据成分 + //比如在一个流中传递{pos,color}这样两个数据,就需要两个attrib + //但我们在一个流中,仅支持一个attrib传递 - attrib.binding=binding_index; - attrib.location=location; - attrib.format=buf->GetFormat(); - attrib.offset=offset; + attrib->binding=binding_index; + attrib->location=shader_location; + attrib->format=format; + attrib->offset=offset; +} - vib_list.Add(new VertexInputBuffer(binding,attrib,buf)); - buf_list.Add(*buf); - buf_offset.Add(offset); +void VertexInputState::Write(VkPipelineVertexInputStateCreateInfo &vis) const +{ + vis.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - binding_list.Add(binding); - attribute_list.Add(attrib); + vis.vertexBindingDescriptionCount = binding_list.GetCount(); + vis.pVertexBindingDescriptions = binding_list.GetData(); + + vis.vertexAttributeDescriptionCount = attribute_list.GetCount(); + vis.pVertexAttributeDescriptions = attribute_list.GetData(); +} + +VertexInput::VertexInput(VertexInputState *state) +{ + vis=state; + + if(!vis) + return; + + buf_count=vis->GetCount(); + + buf_list=hgl_zero_new(buf_count); + buf_offset=hgl_zero_new(buf_count); +} + +VertexInput::~VertexInput() +{ + delete[] buf_offset; + delete[] buf_list; +} + +bool VertexInput::Set(uint32_t index,VertexBuffer *buf,VkDeviceSize offset) +{ + if(index<0||index>=buf_count)return(false); + + VkVertexInputBindingDescription *desc=vis->GetDesc(index); + VkVertexInputAttributeDescription *attr=vis->GetAttr(index); + + if(buf->GetFormat()!=attr->format)return(false); + if(buf->GetStride()!=desc->stride)return(false); + + buf_list[index]=*buf; + buf_offset[index]=offset; return(true); } - -const VkPipelineVertexInputStateCreateInfo VertexInput::GetPipelineVertexInputStateCreateInfo()const -{ - VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; - vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - - vertexInputInfo.vertexBindingDescriptionCount = binding_list.GetCount(); - vertexInputInfo.pVertexBindingDescriptions = binding_list.GetData(); - - vertexInputInfo.vertexAttributeDescriptionCount = attribute_list.GetCount(); - vertexInputInfo.pVertexAttributeDescriptions = attribute_list.GetData(); - - return vertexInputInfo; -} VK_NAMESPACE_END diff --git a/example/Vulkan/VKVertexInput.h b/example/Vulkan/VKVertexInput.h index 826bca3f..3098c782 100644 --- a/example/Vulkan/VKVertexInput.h +++ b/example/Vulkan/VKVertexInput.h @@ -6,64 +6,70 @@ VK_NAMESPACE_BEGIN class VertexBuffer; class IndexBuffer; +/** + * 顶点输入状态
+ * 顶点输入状态用于记录数据是如果传递给Pipeline的,并不包含具体数据 + */ +class VertexInputState +{ + List binding_list; + List attribute_list; + +public: + + VertexInputState()=default; + ~VertexInputState()=default; + + void Add(const uint32_t shader_location,const VkFormat format,uint32_t offset=0,bool instance=false); + +public: + + const uint32_t GetCount()const{return binding_list.GetCount();} + + VkVertexInputBindingDescription * GetDesc(const int index){return (index<0||index>=binding_list.GetCount()?nullptr:binding_list.GetData()+index);} + VkVertexInputAttributeDescription * GetAttr(const int index){return (index<0||index>=attribute_list.GetCount()?nullptr:attribute_list.GetData()+index);} + + void Write(VkPipelineVertexInputStateCreateInfo &vis)const; +};//class VertexInputStateCreater + /** * 顶点输入配置,类似于OpenGL的VAB
* 注:本引擎不支持一个BUFFER中包括多种数据 */ class VertexInput { - struct VertexInputBuffer - { - //按API,可以一个binding绑多个attrib,但我们仅支持1v1 - - VkVertexInputBindingDescription binding; - VkVertexInputAttributeDescription attrib; - VertexBuffer *buffer; - - public: - - VertexInputBuffer(VkVertexInputBindingDescription bind,VkVertexInputAttributeDescription attr,VertexBuffer *buf) - { - binding=bind; - attrib=attr; - buffer=buf; - } - }; - - ObjectList vib_list; - List buf_list; - List buf_offset; - - List binding_list; - List attribute_list; + VertexInputState *vis; + uint32_t buf_count=0; + VkBuffer *buf_list=nullptr; + VkDeviceSize *buf_offset=nullptr; + IndexBuffer *indices_buffer=nullptr; VkDeviceSize indices_offset=0; public: - VertexInput()=default; - virtual ~VertexInput()=default; + VertexInput(VertexInputState *); + virtual ~VertexInput(); - bool Add(uint32_t location,VertexBuffer *,bool instance=false,VkDeviceSize offset=0); - bool AddIndices(IndexBuffer *ib,VkDeviceSize offset=0) + bool Set(uint32_t index,VertexBuffer *,VkDeviceSize offset=0); + bool Set(IndexBuffer *ib,VkDeviceSize offset=0) { if(!ib)return(false); indices_buffer=ib; indices_offset=offset; + return(true); } public: - const uint GetCount ()const{return buf_list.GetCount();} - const VkBuffer * GetBuffer ()const{return buf_list.GetData();} - const VkDeviceSize * GetOffset ()const{return buf_offset.GetData();} + const uint32_t GetCount ()const{return buf_count;} + const VkBuffer * GetBuffer ()const{return buf_list;} + const VkDeviceSize * GetOffset ()const{return buf_offset;} - IndexBuffer * GetIndexBuffer()const{return indices_buffer;} + IndexBuffer * GetIndexBuffer() {return indices_buffer;} const VkDeviceSize GetIndexOffset()const{return indices_offset;} - - const VkPipelineVertexInputStateCreateInfo GetPipelineVertexInputStateCreateInfo()const; };//class VertexInput VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_VERTEX_INPUT_INCLUDE diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index b82a2d01..334041d4 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -102,6 +102,9 @@ vulkan::Buffer *CreateUBO(vulkan::Device *dev) return ubo; } +constexpr uint32_t SHADER_LOCATION_POSITION =0; //对应shader中的layout(locaiton=0,暂时这样写 +constexpr uint32_t SHADER_LOCATION_COLOR =1; + constexpr float vertex_data[]= { SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25, @@ -110,21 +113,28 @@ constexpr float vertex_data[]= }; constexpr float color_data[]={1,0,0, 0,1,0, 0,0,1 }; +vulkan::VertexInputState *InitVertexInput() +{ + vulkan::VertexInputState *vis=new vulkan::VertexInputState(); + + vis->Add(SHADER_LOCATION_POSITION, FMT_RG32F); + vis->Add(SHADER_LOCATION_COLOR, FMT_RGB32F); + + return vis; +} + vulkan::VertexBuffer *vertex_buffer=nullptr; vulkan::VertexBuffer *color_buffer=nullptr; -vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev) -{ - vertex_buffer=dev->CreateVBO(FMT_RG32F,3,vertex_data); - color_buffer=dev->CreateVBO(FMT_RGB32F,3,color_data); +vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev,vulkan::VertexInputState *vis) +{ + vertex_buffer =dev->CreateVBO(FMT_RG32F, 3,vertex_data); + color_buffer =dev->CreateVBO(FMT_RGB32F, 3,color_data); - vulkan::VertexInput *vi=new vulkan::VertexInput(); + vulkan::VertexInput *vi=new vulkan::VertexInput(vis); - constexpr uint32_t position_shader_location=0; //对应shader中的layout(locaiton=0,暂时这样写 - constexpr uint32_t color_shader_location=1; - - vi->Add(position_shader_location, vertex_buffer); - vi->Add(color_shader_location, color_buffer); + vi->Set(SHADER_LOCATION_POSITION, vertex_buffer); + vi->Set(SHADER_LOCATION_COLOR, color_buffer); return vi; } @@ -139,6 +149,17 @@ void wait_seconds(int seconds) { #endif } +//class ExampleFramework +//{ +// Window *win=nullptr; +// vulkan::Instance *inst=nullptr; +// vulkan::Device *device=nullptr; +// vulkan::Shader *shader=nullptr; +// vulkan::Buffer *ubo_mvp=nullptr; +// vulkan::VertexInput *vi=nullptr; +// vulkan::PipelineCreater +//};// + int main(int,char **) { #ifdef _DEBUG @@ -180,7 +201,9 @@ int main(int,char **) vulkan::Buffer *ubo=CreateUBO(device); - vulkan::VertexInput *vi=CreateVertexBuffer(device); + vulkan::VertexInputState *vis=InitVertexInput(); + + vulkan::VertexInput *vi=CreateVertexBuffer(device,vis); vulkan::PipelineCreater pc(device); @@ -201,7 +224,7 @@ int main(int,char **) pc.CloseCullFace(); pc.Set(shader); - pc.Set(vi); + pc.Set(vis); pc.Set(PRIM_TRIANGLES); pc.Set(*pl); @@ -236,6 +259,7 @@ int main(int,char **) delete dsl; delete vi; + delete vis; delete ubo; delete shader;