VertexInput拆分为VertexInptuState,VertexInputStateInstance

This commit is contained in:
HuYingzhuo 2019-04-26 21:43:22 +08:00
parent 0e4caaeaec
commit 3bd896e997
9 changed files with 156 additions and 65 deletions

View File

@ -1,6 +1,7 @@
#include"VKMaterial.h" #include"VKMaterial.h"
#include"VKDescriptorSets.h" #include"VKDescriptorSets.h"
#include"VKShader.h" #include"VKShader.h"
#include"VKVertexInput.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
Material::~Material() Material::~Material()
{ {
@ -10,6 +11,13 @@ Material::~Material()
MaterialInstance *Material::CreateInstance() MaterialInstance *Material::CreateInstance()
{ {
return(nullptr); VertexInputStateInstance *vis_instance=vis->CreateInstance();
return(new MaterialInstance(this,vis_instance));
}
MaterialInstance::~MaterialInstance()
{
delete vis_instance;
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

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

View File

@ -162,7 +162,7 @@ bool PipelineCreater::Set(const Shader *s)
return(true); return(true);
} }
bool PipelineCreater::Set(const VertexInputState *vis) bool PipelineCreater::Set(const VertexInputStateInstance *vis)
{ {
if(!vis) if(!vis)
return(false); return(false);

View File

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

View File

@ -1,4 +1,4 @@
#include"VKShader.h" #include"VKShader.h"
#include"VKVertexInput.h" #include"VKVertexInput.h"
#include"spirv_cross.hpp" #include"spirv_cross.hpp"
@ -111,4 +111,9 @@ void Shader::Clear()
shader_stage_list.Clear(); shader_stage_list.Clear();
vertex_input_state->Clear(); vertex_input_state->Clear();
} }
VertexInputStateInstance *Shader::CreateVertexInputStateInstance()
{
return vertex_input_state->CreateInstance();
}
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -1,12 +1,12 @@
#pragma once #pragma once
#include"VK.h" #include"VK.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class VertexInputState; class VertexInputState;
class VertexInputStateInstance;
/** /**
* Shader * Shader
*/ */
class Shader class Shader
{ {
@ -52,6 +52,7 @@ public:
const uint32_t GetCount ()const{return shader_stage_list.GetCount();} const uint32_t GetCount ()const{return shader_stage_list.GetCount();}
const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();} const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();}
VertexInputState *GetVIS(){return vertex_input_state;} const VertexInputState *GetVertexInputState()const{return vertex_input_state;}
VertexInputStateInstance *CreateVertexInputStateInstance();
};//class ShaderCreater };//class ShaderCreater
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -2,9 +2,19 @@
#include"VKBuffer.h" #include"VKBuffer.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
VertexInputState::~VertexInputState()
{
if(instance_set.GetCount()>0)
{
//还有在用的,这是个错误
}
}
int VertexInputState::Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset,bool instance) 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中的缓冲区索引 const int binding_index=binding_list.GetCount(); //参考opengl vab,binding_index必须从0开始紧密排列。对应在vkCmdBindVertexBuffer中的缓冲区索引
binding_list.SetCount(binding_index+1); binding_list.SetCount(binding_index+1);
@ -27,7 +37,7 @@ int VertexInputState::Add(const UTF8String &name,const uint32_t shader_location,
attrib->format=format; attrib->format=format;
attrib->offset=offset; attrib->offset=offset;
stage_input_locations.Add(name,StageInput(binding_index,shader_location,format)); stage_input_locations.Add(name,attrib);
return binding_index; return binding_index;
} }
@ -36,38 +46,85 @@ const int VertexInputState::GetLocation(const UTF8String &name)const
{ {
if(name.IsEmpty())return -1; if(name.IsEmpty())return -1;
StageInput si; VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,si)) if(!stage_input_locations.Get(name,attr))
return -1; return -1;
return si.location; return attr->location;
} }
const int VertexInputState::GetBinding(const UTF8String &name)const const int VertexInputState::GetBinding(const UTF8String &name)const
{ {
if(name.IsEmpty())return -1; if(name.IsEmpty())return -1;
StageInput si; VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,si)) if(!stage_input_locations.Get(name,attr))
return -1; return -1;
return si.binding; return attr->binding;
} }
void VertexInputState::Write(VkPipelineVertexInputStateCreateInfo &vis) const VertexInputStateInstance *VertexInputState::CreateInstance()
{ {
vis.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; VertexInputStateInstance *vis_instance=new VertexInputStateInstance(this);
vis.vertexBindingDescriptionCount = binding_list.GetCount(); instance_set.Add(vis_instance);
vis.pVertexBindingDescriptions = binding_list.GetData();
vis.vertexAttributeDescriptionCount = attribute_list.GetCount(); return(vis_instance);
vis.pVertexAttributeDescriptions = attribute_list.GetData();
} }
VertexInput::VertexInput(VertexInputState *state) 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)
{
binding_list=nullptr;
return;
}
binding_list=hgl_copy_new(count,vis->GetDescList());
}
VertexInputStateInstance::~VertexInputStateInstance()
{
delete[] binding_list;
vis->Release(this);
}
bool VertexInputStateInstance::SetInstance(const uint index,bool instance)
{
if(index>=vis->GetCount())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
{
vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
const uint32_t count=vis->GetCount();
vis_create_info.vertexBindingDescriptionCount = count;
vis_create_info.pVertexBindingDescriptions = binding_list;
vis_create_info.vertexAttributeDescriptionCount = count;
vis_create_info.pVertexAttributeDescriptions = vis->GetAttrList();
}
VertexInput::VertexInput(const VertexInputState *state)
{ {
vis=state; vis=state;
@ -86,12 +143,12 @@ VertexInput::~VertexInput()
delete[] buf_list; delete[] buf_list;
} }
bool VertexInput::Set(int index,VertexBuffer *buf,VkDeviceSize offset) 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);
VkVertexInputBindingDescription *desc=vis->GetDesc(index); const VkVertexInputBindingDescription *desc=vis->GetDesc(index);
VkVertexInputAttributeDescription *attr=vis->GetAttr(index); const VkVertexInputAttributeDescription *attr=vis->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);

View File

@ -4,44 +4,30 @@
#include"VK.h" #include"VK.h"
#include<hgl/type/BaseString.h> #include<hgl/type/BaseString.h>
#include<hgl/type/Map.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;
/** /**
* <br> * <br>
* Pipeline的 * Pipeline的<br>
* Material中pipeline使用
*/ */
class VertexInputState class VertexInputState
{ {
List<VkVertexInputBindingDescription> binding_list; List<VkVertexInputBindingDescription> binding_list;
List<VkVertexInputAttributeDescription> attribute_list; List<VkVertexInputAttributeDescription> attribute_list;
struct StageInput Map<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
{
int binding;
VkFormat format;
uint32_t location; Set<VertexInputStateInstance *> instance_set;
public:
StageInput(){}
StageInput(const int b,const uint32_t l,const VkFormat f)
{
binding=b;
location=l;
format=f;
}
CompOperatorMemcmp(const StageInput &);
};//struct StageInput
Map<UTF8String,StageInput> stage_input_locations;
public: public:
VertexInputState()=default; VertexInputState()=default;
~VertexInputState()=default; ~VertexInputState();
int Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset=0,bool instance=false); int Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset=0,bool instance=false);
@ -55,23 +41,54 @@ public:
const uint32_t GetCount ()const{return binding_list.GetCount();} const uint32_t GetCount ()const{return binding_list.GetCount();}
const int GetLocation (const UTF8String &)const; const int GetLocation (const UTF8String &)const;
const int GetBinding (const UTF8String &)const; const int GetBinding (const UTF8String &)const;
VkVertexInputBindingDescription * GetDesc(const int index){return (index<0||index>=binding_list.GetCount()?nullptr:binding_list.GetData()+index);} const VkVertexInputBindingDescription * GetDescList ()const{return binding_list.GetData();}
VkVertexInputAttributeDescription * GetAttr(const int index){return (index<0||index>=attribute_list.GetCount()?nullptr:attribute_list.GetData()+index);} const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list.GetData();}
void Write(VkPipelineVertexInputStateCreateInfo &vis)const; const VkVertexInputBindingDescription * GetDesc (const int index)const{return (index<0||index>=binding_list.GetCount()?nullptr:binding_list.GetData()+index);}
};//class VertexInputStateCreater 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
/** /**
* OpenGL的VAB<br> * <br>
* BUFFER中包括多种数据 * MaterialInstance,(instance)
*/
class VertexInputStateInstance
{
VertexInputState *vis;
VkVertexInputBindingDescription *binding_list;
private:
friend class VertexInputState;
VertexInputStateInstance(VertexInputState *);
public:
~VertexInputStateInstance();
bool SetInstance(const uint index,bool instance);
bool SetInstance(const UTF8String &name,bool instance){return SetInstance(vis->GetBinding(name),instance);}
void Write(VkPipelineVertexInputStateCreateInfo &vis)const;
};//class VertexInputStateInstance
/**
* buffer绑定CommandBuffer使用<br>
* Buffer中包括多种数据
*/ */
class VertexInput class VertexInput
{ {
VertexInputState *vis; const VertexInputState *vis;
int buf_count=0; int buf_count=0;
VkBuffer *buf_list=nullptr; VkBuffer *buf_list=nullptr;
@ -82,10 +99,10 @@ class VertexInput
public: public:
VertexInput(VertexInputState *); VertexInput(const VertexInputState *);
virtual ~VertexInput(); virtual ~VertexInput();
bool Set(int binding,VertexBuffer *,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){return Set(vis->GetBinding(name),vb,offset);}
bool Set(IndexBuffer *ib,VkDeviceSize offset=0) bool Set(IndexBuffer *ib,VkDeviceSize offset=0)

View File

@ -113,7 +113,7 @@ 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,vulkan::VertexInputState *vis) vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev,const 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);
@ -188,9 +188,9 @@ int main(int,char **)
vulkan::Buffer *ubo=CreateUBO(device); vulkan::Buffer *ubo=CreateUBO(device);
vulkan::VertexInputState *vis=shader->GetVIS(); vulkan::VertexInputStateInstance *vis_instance=shader->CreateVertexInputStateInstance();
vulkan::VertexInput *vi=CreateVertexBuffer(device,vis); vulkan::VertexInput *vi=CreateVertexBuffer(device,shader->GetVertexInputState());
vulkan::PipelineCreater pc(device); vulkan::PipelineCreater pc(device);
@ -211,7 +211,7 @@ int main(int,char **)
pc.CloseCullFace(); pc.CloseCullFace();
pc.Set(shader); pc.Set(shader);
pc.Set(vis); pc.Set(vis_instance);
pc.Set(PRIM_TRIANGLES); pc.Set(PRIM_TRIANGLES);
pc.Set(*pl); pc.Set(*pl);