将VertexInput拆分出VertexInputState。

VertexInputState传递给Material,未来可能改由Material创建,提供需要绑定的数据流格式。
VertexInput用于实际的缓冲区绑定
This commit is contained in:
HuYingzhuo 2019-04-25 16:02:13 +08:00
parent 09a2566282
commit e35fbf9a1a
5 changed files with 143 additions and 86 deletions

View File

@ -162,15 +162,12 @@ bool PipelineCreater::Set(const Shader *s)
return(true); return(true);
} }
bool PipelineCreater::Set(const VertexInput *vi) bool PipelineCreater::Set(const VertexInputState *vis)
{ {
if(!vi)return(false); if(!vis)
if(vi->GetCount()<=0)return(false); return(false);
vertex_input=vi;
vis_create_info=vertex_input->GetPipelineVertexInputStateCreateInfo();
vis->Write(vis_create_info);
return(true); return(true);
} }

View File

@ -6,6 +6,7 @@
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class Device; class Device;
class RenderPass; class RenderPass;
class VertexInputState;
class Pipeline class Pipeline
{ {
@ -59,7 +60,7 @@ public:
~PipelineCreater()=default; ~PipelineCreater()=default;
bool Set(const Shader *); bool Set(const Shader *);
bool Set(const VertexInput *); bool Set(const VertexInputState *);
bool Set(const VkPrimitiveTopology,bool=false); bool Set(const VkPrimitiveTopology,bool=false);
bool Set(VkPipelineLayout pl); bool Set(VkPipelineLayout pl);

View File

@ -2,46 +2,75 @@
#include"VKBuffer.h" #include"VKBuffer.h"
VK_NAMESPACE_BEGIN 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) const int binding_index=binding_list.GetCount(); //参考opengl vab,binding_index必须从0开始紧密排列。对应在vkCmdBindVertexBuffer中的缓冲区索引
return(false);
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; VkVertexInputBindingDescription *binding=binding_list.GetData()+binding_index;
VkVertexInputAttributeDescription attrib; VkVertexInputAttributeDescription *attrib=attribute_list.GetData()+binding_index;
binding.binding=binding_index; binding->binding=binding_index;
binding.stride=buf->GetStride(); binding->stride=GetStrideByFormat(format);
binding.inputRate=instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; 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->binding=binding_index;
attrib.location=location; attrib->location=shader_location;
attrib.format=buf->GetFormat(); attrib->format=format;
attrib.offset=offset; attrib->offset=offset;
}
vib_list.Add(new VertexInputBuffer(binding,attrib,buf)); void VertexInputState::Write(VkPipelineVertexInputStateCreateInfo &vis) const
buf_list.Add(*buf); {
buf_offset.Add(offset); vis.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
binding_list.Add(binding); vis.vertexBindingDescriptionCount = binding_list.GetCount();
attribute_list.Add(attrib); 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<VkBuffer>(buf_count);
buf_offset=hgl_zero_new<VkDeviceSize>(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); 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 VK_NAMESPACE_END

View File

@ -6,64 +6,70 @@ VK_NAMESPACE_BEGIN
class VertexBuffer; class VertexBuffer;
class IndexBuffer; class IndexBuffer;
/**
* <br>
* Pipeline的
*/
class VertexInputState
{
List<VkVertexInputBindingDescription> binding_list;
List<VkVertexInputAttributeDescription> 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<br> * OpenGL的VAB<br>
* BUFFER中包括多种数据 * BUFFER中包括多种数据
*/ */
class VertexInput class VertexInput
{ {
struct VertexInputBuffer VertexInputState *vis;
{
//按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<VertexInputBuffer> vib_list;
List<VkBuffer> buf_list;
List<VkDeviceSize> buf_offset;
List<VkVertexInputBindingDescription> binding_list;
List<VkVertexInputAttributeDescription> attribute_list;
uint32_t buf_count=0;
VkBuffer *buf_list=nullptr;
VkDeviceSize *buf_offset=nullptr;
IndexBuffer *indices_buffer=nullptr; IndexBuffer *indices_buffer=nullptr;
VkDeviceSize indices_offset=0; VkDeviceSize indices_offset=0;
public: public:
VertexInput()=default; VertexInput(VertexInputState *);
virtual ~VertexInput()=default; virtual ~VertexInput();
bool Add(uint32_t location,VertexBuffer *,bool instance=false,VkDeviceSize offset=0); bool Set(uint32_t index,VertexBuffer *,VkDeviceSize offset=0);
bool AddIndices(IndexBuffer *ib,VkDeviceSize offset=0) bool Set(IndexBuffer *ib,VkDeviceSize offset=0)
{ {
if(!ib)return(false); if(!ib)return(false);
indices_buffer=ib; indices_buffer=ib;
indices_offset=offset; indices_offset=offset;
return(true);
} }
public: public:
const uint GetCount ()const{return buf_list.GetCount();} const uint32_t GetCount ()const{return buf_count;}
const VkBuffer * GetBuffer ()const{return buf_list.GetData();} const VkBuffer * GetBuffer ()const{return buf_list;}
const VkDeviceSize * GetOffset ()const{return buf_offset.GetData();} 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 VkDeviceSize GetIndexOffset()const{return indices_offset;}
const VkPipelineVertexInputStateCreateInfo GetPipelineVertexInputStateCreateInfo()const;
};//class VertexInput };//class VertexInput
VK_NAMESPACE_END VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_VERTEX_INPUT_INCLUDE #endif//HGL_GRAPH_VULKAN_VERTEX_INPUT_INCLUDE

View File

@ -102,6 +102,9 @@ vulkan::Buffer *CreateUBO(vulkan::Device *dev)
return ubo; return ubo;
} }
constexpr uint32_t SHADER_LOCATION_POSITION =0; //对应shader中的layout(locaiton=0暂时这样写
constexpr uint32_t SHADER_LOCATION_COLOR =1;
constexpr float vertex_data[]= constexpr float vertex_data[]=
{ {
SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25, 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 }; 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 *vertex_buffer=nullptr;
vulkan::VertexBuffer *color_buffer=nullptr; vulkan::VertexBuffer *color_buffer=nullptr;
vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev) vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev,vulkan::VertexInputState *vis)
{ {
vertex_buffer=dev->CreateVBO(FMT_RG32F,3,vertex_data); vertex_buffer =dev->CreateVBO(FMT_RG32F, 3,vertex_data);
color_buffer=dev->CreateVBO(FMT_RGB32F,3,color_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暂时这样写 vi->Set(SHADER_LOCATION_POSITION, vertex_buffer);
constexpr uint32_t color_shader_location=1; vi->Set(SHADER_LOCATION_COLOR, color_buffer);
vi->Add(position_shader_location, vertex_buffer);
vi->Add(color_shader_location, color_buffer);
return vi; return vi;
} }
@ -139,6 +149,17 @@ void wait_seconds(int seconds) {
#endif #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 **) int main(int,char **)
{ {
#ifdef _DEBUG #ifdef _DEBUG
@ -180,7 +201,9 @@ int main(int,char **)
vulkan::Buffer *ubo=CreateUBO(device); vulkan::Buffer *ubo=CreateUBO(device);
vulkan::VertexInput *vi=CreateVertexBuffer(device); vulkan::VertexInputState *vis=InitVertexInput();
vulkan::VertexInput *vi=CreateVertexBuffer(device,vis);
vulkan::PipelineCreater pc(device); vulkan::PipelineCreater pc(device);
@ -201,7 +224,7 @@ int main(int,char **)
pc.CloseCullFace(); pc.CloseCullFace();
pc.Set(shader); pc.Set(shader);
pc.Set(vi); pc.Set(vis);
pc.Set(PRIM_TRIANGLES); pc.Set(PRIM_TRIANGLES);
pc.Set(*pl); pc.Set(*pl);
@ -236,6 +259,7 @@ int main(int,char **)
delete dsl; delete dsl;
delete vi; delete vi;
delete vis;
delete ubo; delete ubo;
delete shader; delete shader;