diff --git a/example/Vulkan/VKMaterial.cpp b/example/Vulkan/VKMaterial.cpp
index a05516a0..a3a0ea21 100644
--- a/example/Vulkan/VKMaterial.cpp
+++ b/example/Vulkan/VKMaterial.cpp
@@ -11,7 +11,7 @@ Material::~Material()
MaterialInstance *Material::CreateInstance()
{
- VertexInputStateInstance *vis_instance=vis->CreateInstance();
+ VertexAttributeBinding *vis_instance=shader->CreateVertexAttributeBinding();
return(new MaterialInstance(this,vis_instance));
}
diff --git a/example/Vulkan/VKMaterial.h b/example/Vulkan/VKMaterial.h
index 0c8de14e..10ec4d38 100644
--- a/example/Vulkan/VKMaterial.h
+++ b/example/Vulkan/VKMaterial.h
@@ -7,7 +7,7 @@ class Shader;
class DescriptorSetLayoutCreater;
class MaterialInstance;
class VertexInputState;
-class VertexInputStateInstance;
+class VertexAttributeBinding;
/**
* 材质类
@@ -16,15 +16,13 @@ class VertexInputStateInstance;
class Material
{
Shader *shader;
- VertexInputState *vis;
DescriptorSetLayoutCreater *dsl_creater;
public:
- Material(Shader *s,VertexInputState *state,DescriptorSetLayoutCreater *dslc)
+ Material(Shader *s,DescriptorSetLayoutCreater *dslc)
{
shader=s;
- vis=state;
dsl_creater=dslc;
}
~Material();
@@ -39,11 +37,11 @@ public:
class MaterialInstance
{
const Material *mat; ///<这里的是对material的完全引用,不做任何修改
- VertexInputStateInstance *vis_instance; ///<这里的vis是Material中vis的复制体
+ VertexAttributeBinding *vis_instance; ///<这里的vis是Material中vis的复制体
public:
- MaterialInstance(Material *m,VertexInputStateInstance *vi)
+ MaterialInstance(Material *m,VertexAttributeBinding *vi)
{
mat=m;
vis_instance=vi;
diff --git a/example/Vulkan/VKPipeline.cpp b/example/Vulkan/VKPipeline.cpp
index 511f1fff..1cdefadc 100644
--- a/example/Vulkan/VKPipeline.cpp
+++ b/example/Vulkan/VKPipeline.cpp
@@ -156,18 +156,18 @@ bool PipelineCreater::Set(const Shader *s)
shader=s;
- pipelineInfo.stageCount=shader->GetCount();
- pipelineInfo.pStages=shader->GetStages();
+ pipelineInfo.stageCount=shader->GetStageCount();
+ pipelineInfo.pStages=shader->GetShaderStages();
return(true);
}
-bool PipelineCreater::Set(const VertexInputStateInstance *vis)
+bool PipelineCreater::Set(const VertexAttributeBinding *vab)
{
- if(!vis)
+ if(!vab)
return(false);
- vis->Write(vis_create_info);
+ vab->Write(vis_create_info);
return(true);
}
diff --git a/example/Vulkan/VKPipeline.h b/example/Vulkan/VKPipeline.h
index bef10740..5dc13962 100644
--- a/example/Vulkan/VKPipeline.h
+++ b/example/Vulkan/VKPipeline.h
@@ -6,7 +6,7 @@
VK_NAMESPACE_BEGIN
class Device;
class RenderPass;
-class VertexInputStateInstance;
+class VertexAttributeBinding;
class Pipeline
{
@@ -60,7 +60,7 @@ public:
~PipelineCreater()=default;
bool Set(const Shader *);
- bool Set(const VertexInputStateInstance *);
+ bool Set(const VertexAttributeBinding *);
bool Set(const VkPrimitiveTopology,bool=false);
bool Set(VkPipelineLayout pl);
diff --git a/example/Vulkan/VKShader.cpp b/example/Vulkan/VKShader.cpp
index e557a7e2..9c7a82e9 100644
--- a/example/Vulkan/VKShader.cpp
+++ b/example/Vulkan/VKShader.cpp
@@ -37,6 +37,17 @@ bool Shader::CreateVIS(const void *spv_data,const uint32_t spv_size)
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)
{
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)
return(false);
- const uint32_t location=comp.get_decoration(si.id,spv::DecorationLocation);
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);
@@ -57,13 +86,20 @@ bool Shader::CreateVIS(const void *spv_data,const uint32_t spv_size)
Shader::Shader(VkDevice dev)
{
device=dev;
-
- vertex_input_state=new VertexInputState();
+ attr_count=0;
+ binding_list=nullptr;
+ attribute_list=nullptr;
}
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();
@@ -106,14 +142,41 @@ bool Shader::Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_da
return(true);
}
-void Shader::Clear()
+VertexAttributeBinding *Shader::CreateVertexAttributeBinding()
{
- shader_stage_list.Clear();
- vertex_input_state->Clear();
+ VertexAttributeBinding *vis_instance=new VertexAttributeBinding(this);
+
+ 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
diff --git a/example/Vulkan/VKShader.h b/example/Vulkan/VKShader.h
index 86e7981f..9de681d9 100644
--- a/example/Vulkan/VKShader.h
+++ b/example/Vulkan/VKShader.h
@@ -1,9 +1,10 @@
#pragma once
#include"VK.h"
-
+#include
+#include
+#include
VK_NAMESPACE_BEGIN
-class VertexInputState;
-class VertexInputStateInstance;
+class VertexAttributeBinding;
/**
* Shader 创建器
@@ -14,7 +15,15 @@ class Shader
List shader_stage_list;
- VertexInputState *vertex_input_state=nullptr;
+private:
+
+ uint32_t attr_count;
+ VkVertexInputBindingDescription *binding_list;
+ VkVertexInputAttributeDescription *attribute_list;
+
+ Map stage_input_locations;
+
+ Set instance_set;
private:
@@ -47,12 +56,26 @@ public:
ADD_NV_SHADER_FUNC(Mesh, MESH);
#undef ADD_NV_SHADER_FUNC
- void Clear();
+public: //shader部分
- const uint32_t GetCount ()const{return shader_stage_list.GetCount();}
- const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();}
+ const uint32_t GetStageCount ()const{return shader_stage_list.GetCount();}
+ const VkPipelineShaderStageCreateInfo * GetShaderStages ()const{return shader_stage_list.GetData();}
- const VertexInputState *GetVertexInputState()const{return vertex_input_state;}
- VertexInputStateInstance *CreateVertexInputStateInstance();
+public: //Vertex Input部分
+
+ 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
VK_NAMESPACE_END
diff --git a/example/Vulkan/VKVertexInput.cpp b/example/Vulkan/VKVertexInput.cpp
index 2ed4416e..91a631ee 100644
--- a/example/Vulkan/VKVertexInput.cpp
+++ b/example/Vulkan/VKVertexInput.cpp
@@ -1,90 +1,13 @@
#include"VKVertexInput.h"
#include"VKBuffer.h"
+#include"VKShader.h"
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)
-{
- //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();
+ const int count=shader->GetAttrCount();
if(count<=0)
{
@@ -92,46 +15,51 @@ VertexInputStateInstance::VertexInputStateInstance(VertexInputState *_vis)
return;
}
- binding_list=hgl_copy_new(count,vis->GetDescList());
+ binding_list=hgl_copy_new(count,shader->GetDescList());
}
-VertexInputStateInstance::~VertexInputStateInstance()
+VertexAttributeBinding::~VertexAttributeBinding()
{
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;
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;
- const uint32_t count=vis->GetCount();
+ const uint32_t count=shader->GetAttrCount();
vis_create_info.vertexBindingDescriptionCount = count;
vis_create_info.pVertexBindingDescriptions = binding_list;
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;
- buf_count=vis->GetCount();
+ buf_count=shader->GetAttrCount();
buf_list=hgl_zero_new(buf_count);
buf_offset=hgl_zero_new(buf_count);
@@ -147,8 +75,8 @@ bool VertexInput::Set(const int index,VertexBuffer *buf,VkDeviceSize offset)
{
if(index<0||index>=buf_count)return(false);
- const VkVertexInputBindingDescription *desc=vis->GetDesc(index);
- const VkVertexInputAttributeDescription *attr=vis->GetAttr(index);
+ const VkVertexInputBindingDescription *desc=shader->GetDesc(index);
+ const VkVertexInputAttributeDescription *attr=shader->GetAttr(index);
if(buf->GetFormat()!=attr->format)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);
}
+
+bool VertexInput::Set(const UTF8String &name,VertexBuffer *vb,VkDeviceSize offset)
+{
+ return Set(shader->GetBinding(name),vb,offset);
+}
VK_NAMESPACE_END
diff --git a/example/Vulkan/VKVertexInput.h b/example/Vulkan/VKVertexInput.h
index b77e66d2..8e964610 100644
--- a/example/Vulkan/VKVertexInput.h
+++ b/example/Vulkan/VKVertexInput.h
@@ -3,83 +3,32 @@
#include"VK.h"
#include
-#include
-#include
VK_NAMESPACE_BEGIN
class VertexBuffer;
class IndexBuffer;
-class VertexInputStateInstance;
-
-/**
- * 顶点输入状态
- * 顶点输入状态用于记录数据是如果传递给Pipeline的,并不包含具体数据
- * 本类对象用于存放在Material中,只记录格式,并不能直接供pipeline使用
- */
-class VertexInputState
-{
- List binding_list;
- List attribute_list;
-
- Map stage_input_locations;
-
- Set 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
+class Shader;
/**
* 顶点输入状态实例
* 本对象用于传递给MaterialInstance,用于已经确定好顶点格式的情况下,依然可修改部分设定(如instance)。
*/
-class VertexInputStateInstance
+class VertexAttributeBinding
{
- VertexInputState *vis;
+ Shader *shader;
VkVertexInputBindingDescription *binding_list;
private:
- friend class VertexInputState;
+ friend class Shader;
- VertexInputStateInstance(VertexInputState *);
+ VertexAttributeBinding(Shader *);
public:
- ~VertexInputStateInstance();
+ ~VertexAttributeBinding();
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;
};//class VertexInputStateInstance
@@ -90,7 +39,7 @@ public:
*/
class VertexInput
{
- const VertexInputState *vis;
+ const Shader *shader;
int buf_count=0;
VkBuffer *buf_list=nullptr;
@@ -101,11 +50,11 @@ class VertexInput
public:
- VertexInput(const VertexInputState *);
+ VertexInput(const Shader *);
virtual ~VertexInput();
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)
{
diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp
index b235fd7e..6d16934a 100644
--- a/example/Vulkan/main.cpp
+++ b/example/Vulkan/main.cpp
@@ -113,12 +113,12 @@ constexpr float color_data[]={1,0,0, 0,1,0, 0,0,1 };
vulkan::VertexBuffer *vertex_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);
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("Color", color_buffer);
@@ -188,9 +188,9 @@ int main(int,char **)
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);