删除VertexInputState类,其内容并入Shader类。

VertexInputStateInstance类更名为VertexAttributeBinding
This commit is contained in:
HuYingzhuo 2019-04-26 22:34:51 +08:00
parent d3e99e6061
commit c01f46df5c
9 changed files with 159 additions and 193 deletions

View File

@ -11,7 +11,7 @@ Material::~Material()
MaterialInstance *Material::CreateInstance() MaterialInstance *Material::CreateInstance()
{ {
VertexInputStateInstance *vis_instance=vis->CreateInstance(); VertexAttributeBinding *vis_instance=shader->CreateVertexAttributeBinding();
return(new MaterialInstance(this,vis_instance)); return(new MaterialInstance(this,vis_instance));
} }

View File

@ -7,7 +7,7 @@ class Shader;
class DescriptorSetLayoutCreater; class DescriptorSetLayoutCreater;
class MaterialInstance; class MaterialInstance;
class VertexInputState; class VertexInputState;
class VertexInputStateInstance; class VertexAttributeBinding;
/** /**
* <br> * <br>
@ -16,15 +16,13 @@ class VertexInputStateInstance;
class Material class Material
{ {
Shader *shader; Shader *shader;
VertexInputState *vis;
DescriptorSetLayoutCreater *dsl_creater; DescriptorSetLayoutCreater *dsl_creater;
public: public:
Material(Shader *s,VertexInputState *state,DescriptorSetLayoutCreater *dslc) Material(Shader *s,DescriptorSetLayoutCreater *dslc)
{ {
shader=s; shader=s;
vis=state;
dsl_creater=dslc; dsl_creater=dslc;
} }
~Material(); ~Material();
@ -39,11 +37,11 @@ public:
class MaterialInstance class MaterialInstance
{ {
const Material *mat; ///<这里的是对material的完全引用不做任何修改 const Material *mat; ///<这里的是对material的完全引用不做任何修改
VertexInputStateInstance *vis_instance; ///<这里的vis是Material中vis的复制体 VertexAttributeBinding *vis_instance; ///<这里的vis是Material中vis的复制体
public: public:
MaterialInstance(Material *m,VertexInputStateInstance *vi) MaterialInstance(Material *m,VertexAttributeBinding *vi)
{ {
mat=m; mat=m;
vis_instance=vi; vis_instance=vi;

View File

@ -156,18 +156,18 @@ bool PipelineCreater::Set(const Shader *s)
shader=s; shader=s;
pipelineInfo.stageCount=shader->GetCount(); pipelineInfo.stageCount=shader->GetStageCount();
pipelineInfo.pStages=shader->GetStages(); pipelineInfo.pStages=shader->GetShaderStages();
return(true); return(true);
} }
bool PipelineCreater::Set(const VertexInputStateInstance *vis) bool PipelineCreater::Set(const VertexAttributeBinding *vab)
{ {
if(!vis) if(!vab)
return(false); return(false);
vis->Write(vis_create_info); vab->Write(vis_create_info);
return(true); return(true);
} }

View File

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

View File

@ -37,6 +37,17 @@ bool Shader::CreateVIS(const void *spv_data,const uint32_t spv_size)
spirv_cross::ShaderResources res=comp.get_shader_resources(); spirv_cross::ShaderResources res=comp.get_shader_resources();
attr_count=res.stage_inputs.size();
binding_list=new VkVertexInputBindingDescription[attr_count];
attribute_list=new VkVertexInputAttributeDescription[attr_count];
VkVertexInputBindingDescription *bind=binding_list;
VkVertexInputAttributeDescription *attr=attribute_list;
uint32_t binding_index=0;
for(auto &si:res.stage_inputs) for(auto &si:res.stage_inputs)
{ {
const spirv_cross::SPIRType & type =comp.get_type(si.type_id); const spirv_cross::SPIRType & type =comp.get_type(si.type_id);
@ -45,10 +56,28 @@ bool Shader::CreateVIS(const void *spv_data,const uint32_t spv_size)
if(format==VK_FORMAT_UNDEFINED) if(format==VK_FORMAT_UNDEFINED)
return(false); return(false);
const uint32_t location=comp.get_decoration(si.id,spv::DecorationLocation);
const UTF8String & name =comp.get_name(si.id).c_str(); const UTF8String & name =comp.get_name(si.id).c_str();
vertex_input_state->Add(name,location,format); bind->binding =binding_index; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区序列号所以这个数字必须从0开始而且紧密排列。
//在VertexInput类中buf_list需要严格按照本此binding为序列号排列
bind->stride =GetStrideByFormat(format);
bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX;
//实际使用可以一个binding绑多个attrib但我们仅支持1v1。
//一个binding是指在vertex shader中由一个vertex输入流输入数据attrib指其中的数据成分
//比如在一个流中传递{pos,color}这样两个数据就需要两个attrib
//但我们在一个流中仅支持一个attrib传递
attr->binding =binding_index;
attr->location =comp.get_decoration(si.id,spv::DecorationLocation);
attr->format =format;
attr->offset =0;
stage_input_locations.Add(name,attr);
++attr;
++bind;
++binding_index;
} }
return(true); return(true);
@ -57,13 +86,20 @@ bool Shader::CreateVIS(const void *spv_data,const uint32_t spv_size)
Shader::Shader(VkDevice dev) Shader::Shader(VkDevice dev)
{ {
device=dev; device=dev;
attr_count=0;
vertex_input_state=new VertexInputState(); binding_list=nullptr;
attribute_list=nullptr;
} }
Shader::~Shader() Shader::~Shader()
{ {
delete vertex_input_state; if(instance_set.GetCount()>0)
{
//还有在用的,这是个错误
}
SAFE_CLEAR_ARRAY(binding_list);
SAFE_CLEAR_ARRAY(attribute_list);
const int count=shader_stage_list.GetCount(); const int count=shader_stage_list.GetCount();
@ -106,14 +142,41 @@ bool Shader::Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_da
return(true); return(true);
} }
void Shader::Clear() VertexAttributeBinding *Shader::CreateVertexAttributeBinding()
{ {
shader_stage_list.Clear(); VertexAttributeBinding *vis_instance=new VertexAttributeBinding(this);
vertex_input_state->Clear();
instance_set.Add(vis_instance);
return(vis_instance);
} }
VertexInputStateInstance *Shader::CreateVertexInputStateInstance() bool Shader::Release(VertexAttributeBinding *vis_instance)
{ {
return vertex_input_state->CreateInstance(); return instance_set.Delete(vis_instance);
}
const int Shader::GetLocation(const UTF8String &name)const
{
if(name.IsEmpty())return -1;
VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,attr))
return -1;
return attr->location;
}
const int Shader::GetBinding(const UTF8String &name)const
{
if(name.IsEmpty())return -1;
VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,attr))
return -1;
return attr->binding;
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include"VK.h" #include"VK.h"
#include<hgl/type/BaseString.h>
#include<hgl/type/Map.h>
#include<hgl/type/Set.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class VertexInputState; class VertexAttributeBinding;
class VertexInputStateInstance;
/** /**
* Shader * Shader
@ -14,7 +15,15 @@ class Shader
List<VkPipelineShaderStageCreateInfo> shader_stage_list; List<VkPipelineShaderStageCreateInfo> shader_stage_list;
VertexInputState *vertex_input_state=nullptr; private:
uint32_t attr_count;
VkVertexInputBindingDescription *binding_list;
VkVertexInputAttributeDescription *attribute_list;
Map<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
Set<VertexAttributeBinding *> instance_set;
private: private:
@ -47,12 +56,26 @@ public:
ADD_NV_SHADER_FUNC(Mesh, MESH); ADD_NV_SHADER_FUNC(Mesh, MESH);
#undef ADD_NV_SHADER_FUNC #undef ADD_NV_SHADER_FUNC
void Clear(); public: //shader部分
const uint32_t GetCount ()const{return shader_stage_list.GetCount();} const uint32_t GetStageCount ()const{return shader_stage_list.GetCount();}
const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();} const VkPipelineShaderStageCreateInfo * GetShaderStages ()const{return shader_stage_list.GetData();}
const VertexInputState *GetVertexInputState()const{return vertex_input_state;} public: //Vertex Input部分
VertexInputStateInstance *CreateVertexInputStateInstance();
VertexAttributeBinding * CreateVertexAttributeBinding();
bool Release(VertexAttributeBinding *);
const uint32_t GetInstanceCount()const{return instance_set.GetCount();}
const uint32_t GetAttrCount()const{return attr_count;}
const int GetLocation (const UTF8String &)const;
const int GetBinding (const UTF8String &)const;
const VkVertexInputBindingDescription * GetDescList ()const{return binding_list;}
const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list;}
const VkVertexInputBindingDescription * GetDesc (const uint32_t index)const{return (index>=attr_count?nullptr:binding_list+index);}
const VkVertexInputAttributeDescription * GetAttr (const uint32_t index)const{return (index>=attr_count?nullptr:attribute_list+index);}
};//class ShaderCreater };//class ShaderCreater
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -1,90 +1,13 @@
#include"VKVertexInput.h" #include"VKVertexInput.h"
#include"VKBuffer.h" #include"VKBuffer.h"
#include"VKShader.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
VertexInputState::~VertexInputState() VertexAttributeBinding::VertexAttributeBinding(Shader *s)
{ {
if(instance_set.GetCount()>0) shader=s;
{
//还有在用的,这是个错误
}
}
int VertexInputState::Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset,bool instance) const int count=shader->GetAttrCount();
{
//binding对应在vkCmdBindVertexBuffer中设置的缓冲区序列号所以这个数字必须从0开始而且紧密排列。
//在VertexInput类中buf_list需要严格按照本类产生的binding为序列号
const int binding_index=binding_list.GetCount(); //参考opengl vab,binding_index必须从0开始紧密排列。对应在vkCmdBindVertexBuffer中的缓冲区索引
binding_list.SetCount(binding_index+1);
attribute_list.SetCount(binding_index+1);
VkVertexInputBindingDescription *binding=binding_list.GetData()+binding_index;
VkVertexInputAttributeDescription *attrib=attribute_list.GetData()+binding_index;
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=shader_location;
attrib->format=format;
attrib->offset=offset;
stage_input_locations.Add(name,attrib);
return binding_index;
}
const int VertexInputState::GetLocation(const UTF8String &name)const
{
if(name.IsEmpty())return -1;
VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,attr))
return -1;
return attr->location;
}
const int VertexInputState::GetBinding(const UTF8String &name)const
{
if(name.IsEmpty())return -1;
VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,attr))
return -1;
return attr->binding;
}
VertexInputStateInstance *VertexInputState::CreateInstance()
{
VertexInputStateInstance *vis_instance=new VertexInputStateInstance(this);
instance_set.Add(vis_instance);
return(vis_instance);
}
bool VertexInputState::Release(VertexInputStateInstance *vis_instance)
{
return instance_set.Delete(vis_instance);
}
VertexInputStateInstance::VertexInputStateInstance(VertexInputState *_vis)
{
vis=_vis;
const int count=vis->GetCount();
if(count<=0) if(count<=0)
{ {
@ -92,46 +15,51 @@ VertexInputStateInstance::VertexInputStateInstance(VertexInputState *_vis)
return; return;
} }
binding_list=hgl_copy_new(count,vis->GetDescList()); binding_list=hgl_copy_new(count,shader->GetDescList());
} }
VertexInputStateInstance::~VertexInputStateInstance() VertexAttributeBinding::~VertexAttributeBinding()
{ {
delete[] binding_list; delete[] binding_list;
vis->Release(this); shader->Release(this);
} }
bool VertexInputStateInstance::SetInstance(const uint index,bool instance) bool VertexAttributeBinding::SetInstance(const uint index,bool instance)
{ {
if(index>=vis->GetCount())return(false); if(index>=shader->GetAttrCount())return(false);
binding_list[index].inputRate=instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; binding_list[index].inputRate=instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX;
return(true); return(true);
} }
void VertexInputStateInstance::Write(VkPipelineVertexInputStateCreateInfo &vis_create_info) const bool VertexAttributeBinding::SetInstance(const UTF8String &name,bool instance)
{
return SetInstance(shader->GetBinding(name),instance);
}
void VertexAttributeBinding::Write(VkPipelineVertexInputStateCreateInfo &vis_create_info) const
{ {
vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
const uint32_t count=vis->GetCount(); const uint32_t count=shader->GetAttrCount();
vis_create_info.vertexBindingDescriptionCount = count; vis_create_info.vertexBindingDescriptionCount = count;
vis_create_info.pVertexBindingDescriptions = binding_list; vis_create_info.pVertexBindingDescriptions = binding_list;
vis_create_info.vertexAttributeDescriptionCount = count; vis_create_info.vertexAttributeDescriptionCount = count;
vis_create_info.pVertexAttributeDescriptions = vis->GetAttrList(); vis_create_info.pVertexAttributeDescriptions = shader->GetAttrList();
} }
VertexInput::VertexInput(const VertexInputState *state) VertexInput::VertexInput(const Shader *s)
{ {
vis=state; shader=s;
if(!vis) if(!shader)
return; return;
buf_count=vis->GetCount(); buf_count=shader->GetAttrCount();
buf_list=hgl_zero_new<VkBuffer>(buf_count); buf_list=hgl_zero_new<VkBuffer>(buf_count);
buf_offset=hgl_zero_new<VkDeviceSize>(buf_count); buf_offset=hgl_zero_new<VkDeviceSize>(buf_count);
@ -147,8 +75,8 @@ bool VertexInput::Set(const int index,VertexBuffer *buf,VkDeviceSize offset)
{ {
if(index<0||index>=buf_count)return(false); if(index<0||index>=buf_count)return(false);
const VkVertexInputBindingDescription *desc=vis->GetDesc(index); const VkVertexInputBindingDescription *desc=shader->GetDesc(index);
const VkVertexInputAttributeDescription *attr=vis->GetAttr(index); const VkVertexInputAttributeDescription *attr=shader->GetAttr(index);
if(buf->GetFormat()!=attr->format)return(false); if(buf->GetFormat()!=attr->format)return(false);
if(buf->GetStride()!=desc->stride)return(false); if(buf->GetStride()!=desc->stride)return(false);
@ -158,4 +86,9 @@ bool VertexInput::Set(const int index,VertexBuffer *buf,VkDeviceSize offset)
return(true); return(true);
} }
bool VertexInput::Set(const UTF8String &name,VertexBuffer *vb,VkDeviceSize offset)
{
return Set(shader->GetBinding(name),vb,offset);
}
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -3,83 +3,32 @@
#include"VK.h" #include"VK.h"
#include<hgl/type/BaseString.h> #include<hgl/type/BaseString.h>
#include<hgl/type/Map.h>
#include<hgl/type/Set.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class VertexBuffer; class VertexBuffer;
class IndexBuffer; class IndexBuffer;
class VertexInputStateInstance; class Shader;
/**
* <br>
* Pipeline的<br>
* Material中pipeline使用
*/
class VertexInputState
{
List<VkVertexInputBindingDescription> binding_list;
List<VkVertexInputAttributeDescription> attribute_list;
Map<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
Set<VertexInputStateInstance *> instance_set;
private:
friend class Shader;
VertexInputState()=default;
~VertexInputState();
int Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset=0,bool instance=false);
public:
void Clear()
{
binding_list.Clear();
attribute_list.Clear();
}
const uint32_t GetCount ()const{return binding_list.GetCount();}
const int GetLocation (const UTF8String &)const;
const int GetBinding (const UTF8String &)const;
const VkVertexInputBindingDescription * GetDescList ()const{return binding_list.GetData();}
const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list.GetData();}
const VkVertexInputBindingDescription * GetDesc (const int index)const{return (index<0||index>=binding_list.GetCount()?nullptr:binding_list.GetData()+index);}
const VkVertexInputAttributeDescription * GetAttr (const int index)const{return (index<0||index>=attribute_list.GetCount()?nullptr:attribute_list.GetData()+index);}
public:
VertexInputStateInstance * CreateInstance();
bool Release(VertexInputStateInstance *);
const uint32_t GetInstanceCount()const{return instance_set.GetCount();}
};//class VertexInputState
/** /**
* <br> * <br>
* MaterialInstance,(instance) * MaterialInstance,(instance)
*/ */
class VertexInputStateInstance class VertexAttributeBinding
{ {
VertexInputState *vis; Shader *shader;
VkVertexInputBindingDescription *binding_list; VkVertexInputBindingDescription *binding_list;
private: private:
friend class VertexInputState; friend class Shader;
VertexInputStateInstance(VertexInputState *); VertexAttributeBinding(Shader *);
public: public:
~VertexInputStateInstance(); ~VertexAttributeBinding();
bool SetInstance(const uint index,bool instance); bool SetInstance(const uint index,bool instance);
bool SetInstance(const UTF8String &name,bool instance){return SetInstance(vis->GetBinding(name),instance);} bool SetInstance(const UTF8String &name,bool instance);
void Write(VkPipelineVertexInputStateCreateInfo &vis)const; void Write(VkPipelineVertexInputStateCreateInfo &vis)const;
};//class VertexInputStateInstance };//class VertexInputStateInstance
@ -90,7 +39,7 @@ public:
*/ */
class VertexInput class VertexInput
{ {
const VertexInputState *vis; const Shader *shader;
int buf_count=0; int buf_count=0;
VkBuffer *buf_list=nullptr; VkBuffer *buf_list=nullptr;
@ -101,11 +50,11 @@ class VertexInput
public: public:
VertexInput(const VertexInputState *); VertexInput(const Shader *);
virtual ~VertexInput(); virtual ~VertexInput();
bool Set(const int binding, VertexBuffer *vb,VkDeviceSize offset=0); bool Set(const int binding, VertexBuffer *vb,VkDeviceSize offset=0);
bool Set(const UTF8String &name,VertexBuffer *vb,VkDeviceSize offset=0){return Set(vis->GetBinding(name),vb,offset);} bool Set(const UTF8String &name,VertexBuffer *vb,VkDeviceSize offset=0);
bool Set(IndexBuffer *ib,VkDeviceSize offset=0) bool Set(IndexBuffer *ib,VkDeviceSize offset=0)
{ {

View File

@ -113,12 +113,12 @@ constexpr float color_data[]={1,0,0, 0,1,0, 0,0,1 };
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,const vulkan::VertexInputState *vis) vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev,const vulkan::Shader *shader)
{ {
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(vis); vulkan::VertexInput *vi=new vulkan::VertexInput(shader);
vi->Set("Vertex", vertex_buffer); vi->Set("Vertex", vertex_buffer);
vi->Set("Color", color_buffer); vi->Set("Color", color_buffer);
@ -188,9 +188,9 @@ int main(int,char **)
vulkan::Buffer *ubo=CreateUBO(device); vulkan::Buffer *ubo=CreateUBO(device);
vulkan::VertexInputStateInstance *vis_instance=shader->CreateVertexInputStateInstance(); vulkan::VertexAttributeBinding *vis_instance=shader->CreateVertexAttributeBinding();
vulkan::VertexInput *vi=CreateVertexBuffer(device,shader->GetVertexInputState()); vulkan::VertexInput *vi=CreateVertexBuffer(device,shader);
vulkan::PipelineCreater pc(device); vulkan::PipelineCreater pc(device);