大规模重构完成,下一步将Bind VBO工作在VertexInput前由MaterialInstance检测一次格式,并将新格式赋给VkVertexInputAttributeDescription

This commit is contained in:
HuYingzhuo 2019-04-28 16:06:53 +08:00
parent 01ba519ef2
commit 8f60701a51
22 changed files with 465 additions and 434 deletions

View File

@ -6,6 +6,7 @@ ELSEIF(WIN32)
ENDIF()
SET(VULKAN_TEST_SOURCE_FILES main.cpp
AssetsManage.cpp
${RENDER_WINDOW_SOURCE}
VKFormat.cpp
VKInstance.cpp
@ -16,12 +17,10 @@ SET(VULKAN_TEST_SOURCE_FILES main.cpp
VKDeviceCreater.cpp
VKDevice.cpp
VKDeviceBuffer.cpp
VKDeviceMaterial.cpp
VKBuffer.cpp
VKDescriptorSets.cpp
VKPipelineLayout.cpp
VKRenderPass.cpp
VKShader.cpp
VKShaderModule.cpp
VKShaderModuleManage.cpp
VKVertexAttributeBinding.cpp
@ -30,10 +29,11 @@ SET(VULKAN_TEST_SOURCE_FILES main.cpp
VKSemaphore.cpp
VKFramebuffer.cpp
VKFence.cpp
#VKMaterial.cpp
VKMaterial.cpp
)
SET(VULKAN_TEST_HEADER_FILES VK.h
SET(VULKAN_TEST_HEADER_FILES AssetsManage.h
VK.h
VKFormat.h
VKPrimivate.h
VKInstance.h
@ -47,7 +47,6 @@ SET(VULKAN_TEST_HEADER_FILES VK.h
VKDescriptorSets.h
VKPipelineLayout.h
VKRenderPass.h
VKShader.h
VKShaderModule.h
VKShaderModuleManage.h
VKVertexInput.h

View File

@ -74,6 +74,29 @@ void DescriptorSetLayoutCreater::Bind(const uint32_t binding,VkDescriptorType de
binding_index.Add(binding,index);
}
void DescriptorSetLayoutCreater::Bind(const uint32_t *binding,const uint32_t count,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags)
{
const int old_count=layout_binding_list.GetCount();
layout_binding_list.SetCount(old_count+count);
VkDescriptorSetLayoutBinding *p=layout_binding_list.GetData()+old_count;
for(int i=old_count;i<old_count+count;i++)
{
p->binding = *binding;
p->descriptorType = desc_type;
p->descriptorCount = 1;
p->stageFlags = stageFlags;
p->pImmutableSamplers = nullptr;
binding_index.Add(*binding,i);
++binding;
++p;
}
}
DescriptorSetLayout *DescriptorSetLayoutCreater::Create()
{
const int count=layout_binding_list.GetCount();

View File

@ -53,8 +53,10 @@ public:
~DescriptorSetLayoutCreater()=default;
void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits);
void Bind(const uint32_t *binding,const uint32_t count,VkDescriptorType type,VkShaderStageFlagBits stage);
#define DESC_SET_BIND_FUNC(name,vkname) void Bind##name(const uint32_t binding,VkShaderStageFlagBits stage_flag){Bind(binding,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);}
#define DESC_SET_BIND_FUNC(name,vkname) void Bind##name(const uint32_t binding,VkShaderStageFlagBits stage_flag){Bind(binding,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);} \
void Bind##name(const uint32_t *binding,const uint32_t count,VkShaderStageFlagBits stage_flag){Bind(binding,count,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);}
DESC_SET_BIND_FUNC(Sampler, SAMPLER);
DESC_SET_BIND_FUNC(UBO, UNIFORM_BUFFER);

View File

@ -1,6 +1,5 @@
#include"VKDevice.h"
#include<hgl/type/Pair.h>
#include"VKBuffer.h"
#include"VKImageView.h"
#include"VKCommandBuffer.h"
//#include"VKDescriptorSet.h"
@ -8,9 +7,7 @@
#include"VKFramebuffer.h"
#include"VKFence.h"
#include"VKSemaphore.h"
#include"VKShader.h"
#include"VKShaderModuleManage.h"
#include"VKMaterial.h"
#include"VKDescriptorSets.h"
VK_NAMESPACE_BEGIN
@ -39,13 +36,10 @@ Device::Device(DeviceAttribute *da)
for(int i=0;i<sc_count;i++)
main_fb.Add(vulkan::CreateFramebuffer(this,main_rp,attr->sc_image_views[i],attr->depth.view));
}
shader_module_manage=new ShaderModuleManage(attr->device);
}
Device::~Device()
{
delete shader_module_manage;
main_fb.Clear();
delete main_rp;
@ -197,6 +191,11 @@ Semaphore *Device::CreateSem()
return(new Semaphore(attr->device,sem));
}
ShaderModuleManage *Device::CreateShaderModuleManage()
{
return(new ShaderModuleManage(this));
}
bool Device::AcquireNextImage()
{
return(vkAcquireNextImageKHR(attr->device,attr->swap_chain,UINT64_MAX,*image_acquired_semaphore,VK_NULL_HANDLE,&current_frame)==VK_SUCCESS);

View File

@ -2,6 +2,8 @@
#define HGL_GRAPH_RENDER_SURFACE_INCLUDE
#include<hgl/type/List.h>
#include<hgl/type/BaseString.h>
#include<hgl/type/Map.h>
#include"VK.h"
#include"Window.h"
#include"VKDeviceAttribute.h"
@ -18,6 +20,7 @@ class Fence;
class Semaphore;
class ShaderModule;
class ShaderModuleManage;
class VertexShaderModule;
class Material;
#define MAX_FRAMES_IN_FLIGHT 2
@ -35,9 +38,7 @@ class Device
uint32_t current_frame;
VkPresentInfoKHR present;
ShaderModuleManage *shader_module_manage;
private:
friend Device *CreateRenderDevice(VkInstance,const PhysicalDevice *,Window *);
@ -96,7 +97,7 @@ public: //Buffer
public: //materialÏà¹Ø
//Material * CreateMaterial();
ShaderModuleManage *CreateShaderModuleManage();
public: //Command Buffer Ïà¹Ø

View File

@ -1,4 +1,5 @@
#include"VKDevice.h"
#include"VKBuffer.h"
VK_NAMESPACE_BEGIN
namespace

View File

@ -1,10 +0,0 @@
#include"VKDevice.h"
VK_NAMESPACE_BEGIN
//Material *Device::CreateMaterial(Shader *shader)
//{
// DescriptorSetLayoutCreater *dslc=new DescriptorSetLayoutCreater(this);
//
// return(new Material(shader,dslc));
//}
VK_NAMESPACE_END

View File

@ -1,35 +1,119 @@
#include"VKMaterial.h"
#include"VKDevice.h"
#include"VKDescriptorSets.h"
#include"VKShader.h"
#include"VKShaderModule.h"
#include"VKVertexAttributeBinding.h"
#include"VKVertexInput.h"
VK_NAMESPACE_BEGIN
Material::Material(Device *dev,Shader *s)
Material::Material(Device *dev,ShaderModuleMap *smm)
{
device=dev;
shader=s;
device=*dev;
shader_maps=smm;
dsl_creater=new DescriptorSetLayoutCreater(dev);
const int shader_count=shader_maps->GetCount();
shader_stage_list.SetCount(shader_count);
VkPipelineShaderStageCreateInfo *p=shader_stage_list.GetData();
const ShaderModule *sm;
auto **itp=shader_maps->GetDataList();
for(int i=0;i<shader_count;i++)
{
sm=(*itp)->right;
if(sm->GetStage()==VK_SHADER_STAGE_VERTEX_BIT)
vertex_sm=(VertexShaderModule *)sm;
memcpy(p,sm->GetCreateInfo(),sizeof(VkPipelineShaderStageCreateInfo));
++p;
++itp;
{
const ShaderBindingList &ubo_list=sm->GetUBOBindingList();
dsl_creater->BindUBO(ubo_list.GetData(),ubo_list.GetCount(),sm->GetStage());
}
}
}
Material::~Material()
{
delete dsl_creater;
delete shader;
const int count=shader_stage_list.GetCount();
if(count>0)
{
VkPipelineShaderStageCreateInfo *ss=shader_stage_list.GetData();
for(int i=0;i<count;i++)
{
vkDestroyShaderModule(device,ss->module,nullptr);
++ss;
}
}
delete shader_maps;
}
MaterialInstance *Material::CreateInstance()
const int Material::GetUBOBinding(const UTF8String &name)const
{
return(new MaterialInstance(this));
int result;
const int shader_count=shader_maps->GetCount();
const ShaderModule *sm;
auto **itp=shader_maps->GetDataList();
for(int i=0;i<shader_count;i++)
{
sm=(*itp)->right;
result=sm->GetUBO(name);
if(result!=-1)
return result;
++itp;
}
return(-1);
}
MaterialInstance::MaterialInstance(Material *m)
MaterialInstance *Material::CreateInstance()const
{
if(!vertex_sm)
return(nullptr);
VertexAttributeBinding *vab=vertex_sm->CreateVertexAttributeBinding();
if(!vab)
return(nullptr);
VertexInput *vi=new VertexInput(vertex_sm);
DescriptorSetLayout *dsl=dsl_creater->Create();
return(new MaterialInstance(this,vab,vi,dsl));
}
MaterialInstance::MaterialInstance(const Material *m,VertexAttributeBinding *v,VertexInput *i,DescriptorSetLayout *d)
{
mat=m;
vab=->CreateVertexAttributeBinding();
vab=v;
desc_set_layout=d;
vi=i;
}
MaterialInstance::~MaterialInstance()
{
delete vi;
delete desc_set_layout;
delete vab;
delete dsl_creater;
}
bool MaterialInstance::UpdateUBO(const uint32_t binding,const VkDescriptorBufferInfo *buf_info)
{
return desc_set_layout->UpdateUBO(binding,buf_info);
}
void MaterialInstance::Write(VkPipelineVertexInputStateCreateInfo &vis)const
{
return vab->Write(vis);
}
VK_NAMESPACE_END

View File

@ -2,13 +2,19 @@
#define HGL_GRAPH_VULKAN_MATERIAL_INCLUDE
#include"VK.h"
#include<hgl/type/Map.h>
#include<hgl/type/BaseString.h>
VK_NAMESPACE_BEGIN
class Device;
class Shader;
class ShaderModule;
class VertexShaderModule;
class DescriptorSetLayoutCreater;
class DescriptorSetLayout;
class MaterialInstance;
class VertexAttributeBinding;
class VertexInput;
using ShaderModuleMap=hgl::Map<VkShaderStageFlagBits,const ShaderModule *>;
/**
* <br>
@ -16,16 +22,24 @@ class VertexAttributeBinding;
*/
class Material
{
Device *device;
ShaderModule *shader_modules;
VkDevice device;
ShaderModuleMap *shader_maps;
VertexShaderModule *vertex_sm;
List<VkPipelineShaderStageCreateInfo> shader_stage_list;
DescriptorSetLayoutCreater *dsl_creater;
public:
Material(Device *dev,);
Material(Device *dev,ShaderModuleMap *smm);
~Material();
MaterialInstance *CreateInstance();
const int GetUBOBinding(const UTF8String &)const;
MaterialInstance *CreateInstance()const;
const uint32_t GetStageCount ()const{return shader_stage_list.GetCount();}
const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();}
};//class Material
/**
@ -36,12 +50,29 @@ class MaterialInstance
{
const Material *mat; ///<这里的是对material的完全引用不做任何修改
VertexAttributeBinding *vab;
VertexInput *vi;
DescriptorSetLayout *desc_set_layout;
public:
MaterialInstance(Material *m);
MaterialInstance(const Material *m,VertexAttributeBinding *v,VertexInput *i,DescriptorSetLayout *d);
~MaterialInstance();
bool UpdateUBO(const uint32_t binding,const VkDescriptorBufferInfo *buf_info);
bool UpdateUBO(const UTF8String &name,const VkDescriptorBufferInfo *buf_info)
{
if(name.IsEmpty()||!buf_info)
return(false);
return UpdateUBO(mat->GetUBOBinding(name),buf_info);
}
const uint32_t GetStageCount ()const{return mat->GetStageCount();}
const VkPipelineShaderStageCreateInfo * GetStages ()const{return mat->GetStages();}
void Write(VkPipelineVertexInputStateCreateInfo &vis)const;
VertexInput * GetVI(){return vi;}
DescriptorSetLayout * GetDSL(){return desc_set_layout;}
};//class MaterialInstance
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_MATERIAL_INCLUDE

View File

@ -1,7 +1,6 @@
#include"VKPipeline.h"
#include"VKDevice.h"
#include"VKShader.h"
#include"VKVertexAttributeBinding.h"
#include"VKMaterial.h"
#include"VKRenderPass.h"
VK_NAMESPACE_BEGIN
@ -148,29 +147,20 @@ PipelineCreater::PipelineCreater(Device *dev,RenderPass *rp)
pipelineInfo.basePipelineIndex = 0;
}
bool PipelineCreater::Set(const Shader *s)
bool PipelineCreater::Set(const MaterialInstance *mi)
{
if(!s)return(false);
if(!mi)return(false);
//未来这里需要增加是否有vs/fs的检测
shader=s;
pipelineInfo.stageCount=mi->GetStageCount();
pipelineInfo.pStages=mi->GetStages();
pipelineInfo.stageCount=shader->GetStageCount();
pipelineInfo.pStages=shader->GetShaderStages();
mi->Write(vis_create_info);
return(true);
}
bool PipelineCreater::Set(const VertexAttributeBinding *vab)
{
if(!vab)
return(false);
vab->Write(vis_create_info);
return(true);
}
bool PipelineCreater::Set(const VkPrimitiveTopology topology,bool restart)
{
if(topology<VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE||topology>VK_PRIMITIVE_TOPOLOGY_END_RANGE)

View File

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

View File

@ -1,191 +0,0 @@
#include"VKShader.h"
#include"VKVertexAttributeBinding.h"
#include"spirv_cross.hpp"
VK_NAMESPACE_BEGIN
namespace
{
const VkFormat GetVecFormat(const spirv_cross::SPIRType &type)
{
constexpr VkFormat format[][4]=
{
{FMT_R8I,FMT_RG8I,FMT_RGB8I,FMT_RGBA8I}, //sbyte
{FMT_R8U,FMT_RG8U,FMT_RGB8U,FMT_RGBA8U}, //ubyte
{FMT_R16I,FMT_RG16I,FMT_RGB16I,FMT_RGBA16I},//short
{FMT_R16U,FMT_RG16U,FMT_RGB16U,FMT_RGBA16U},//ushort
{FMT_R32I,FMT_RG32I,FMT_RGB32I,FMT_RGBA32I},//int
{FMT_R32U,FMT_RG32U,FMT_RGB32U,FMT_RGBA32U},//uint
{FMT_R64I,FMT_RG64I,FMT_RGB64I,FMT_RGBA64I},//int64
{FMT_R64U,FMT_RG64U,FMT_RGB64U,FMT_RGBA64U},//uint64
{}, //atomic
{FMT_R16F,FMT_RG16F,FMT_RGB16F,FMT_RGBA16F},//half
{FMT_R32F,FMT_RG32F,FMT_RGB32F,FMT_RGBA32F},//float
{FMT_R64F,FMT_RG64F,FMT_RGB64F,FMT_RGBA64F} //double
};
if(type.basetype<spirv_cross::SPIRType::SByte
||type.basetype>spirv_cross::SPIRType::Double
||type.basetype==spirv_cross::SPIRType::AtomicCounter
||type.vecsize<1
||type.vecsize>4)
return VK_FORMAT_UNDEFINED;
return format[type.basetype-spirv_cross::SPIRType::SByte][type.vecsize-1];
}
}//namespace
bool Shader::ParseVertexShader(const void *spv_data,const uint32_t spv_size)
{
spirv_cross::Compiler comp((const uint32_t *)spv_data,spv_size/sizeof(uint32_t));
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);
const VkFormat format =GetVecFormat(type);
if(format==VK_FORMAT_UNDEFINED)
return(false);
const UTF8String & name =comp.get_name(si.id).c_str();
bind->binding =binding_index; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号所以这个数字必须从0开始而且紧密排列。
//在VertexInput类中buf_list需要严格按照本此binding为序列号排列
bind->stride =GetStrideByFormat(format);
bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX;
//binding对应的是第几个数据输入流
//实际使用一个binding可以绑定多个attrib
//比如在一个流中传递{pos,color}这样两个数据就需要两个attrib
//但在我们的设计中仅支持一个流传递一个attrib
attr->binding =binding_index;
attr->location =comp.get_decoration(si.id,spv::DecorationLocation); //此值对应shader中的layout(location=
attr->format =format;
attr->offset =0;
stage_input_locations.Add(name,attr);
++attr;
++bind;
++binding_index;
}
for(auto &ub:res.uniform_buffers)
{
const UTF8String & name =comp.get_name(ub.id).c_str();
const uint binding =comp.get_decoration(ub.id,spv::DecorationBinding);
ubo_list.Add(name,binding);
}
return(true);
}
Shader::Shader(VkDevice dev)
{
device=dev;
attr_count=0;
binding_list=nullptr;
attribute_list=nullptr;
}
Shader::~Shader()
{
if(vab_sets.GetCount()>0)
{
//还有在用的,这是个错误
}
SAFE_CLEAR_ARRAY(binding_list);
SAFE_CLEAR_ARRAY(attribute_list);
const int count=shader_stage_list.GetCount();
if(count>0)
{
VkPipelineShaderStageCreateInfo *ss=shader_stage_list.GetData();
for(int i=0;i<count;i++)
{
vkDestroyShaderModule(device,ss->module,nullptr);
++ss;
}
}
}
bool Shader::Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size)
{
if(shader_stage_bit==VK_SHADER_STAGE_VERTEX_BIT)
ParseVertexShader(spv_data,spv_size);
VkPipelineShaderStageCreateInfo shader_stage;
shader_stage.sType=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stage.pNext=nullptr;
shader_stage.pSpecializationInfo=nullptr;
shader_stage.flags=0;
shader_stage.stage=shader_stage_bit;
shader_stage.pName="main";
VkShaderModuleCreateInfo moduleCreateInfo;
moduleCreateInfo.sType=VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleCreateInfo.pNext=nullptr;
moduleCreateInfo.flags=0;
moduleCreateInfo.codeSize=spv_size;
moduleCreateInfo.pCode=(const uint32_t *)spv_data;
if(vkCreateShaderModule(device,&moduleCreateInfo,nullptr,&shader_stage.module)!=VK_SUCCESS)
return(false);
shader_stage_list.Add(shader_stage);
return(true);
}
VertexAttributeBinding *Shader::CreateVertexAttributeBinding()
{
VertexAttributeBinding *vab=new VertexAttributeBinding(this);
vab_sets.Add(vab);
return(vab);
}
bool Shader::Release(VertexAttributeBinding *vab)
{
return vab_sets.Delete(vab);
}
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

View File

@ -1,43 +0,0 @@
#pragma once
#include"VK.h"
#include<hgl/type/BaseString.h>
#include<hgl/type/Map.h>
#include<hgl/type/Set.h>
VK_NAMESPACE_BEGIN
class VertexAttributeBinding;
/**
* Shader
*/
class Shader
{
VkDevice device;
List<VkPipelineShaderStageCreateInfo> shader_stage_list;
private:
Set<VertexAttributeBinding *> vab_sets;
private:
bool ParseVertexShader(const void *,const uint32_t);
public:
Shader(VkDevice);
~Shader();
public: //shader部分
public: //Vertex Input部分
VertexAttributeBinding * CreateVertexAttributeBinding();
bool Release(VertexAttributeBinding *);
const uint32_t GetInstanceCount()const{return vab_sets.GetCount();}
};//class ShaderCreater
VK_NAMESPACE_END

View File

@ -1,16 +1,122 @@
#include"VKShaderModule.h"
#include"VKVertexAttributeBinding.h"
#include"VKShaderParse.h"
VK_NAMESPACE_BEGIN
ShaderModule::ShaderModule(int id,VkPipelineShaderStageCreateInfo *sci)
ShaderModule::ShaderModule(int id,VkPipelineShaderStageCreateInfo *sci,const ShaderParse *sp)
{
shader_id=id;
ref_count=0;
stage_create_info=sci;
ParseUBO(sp);
}
ShaderModule::~ShaderModule()
{
delete stage_create_info;
}
void ShaderModule::ParseUBO(const ShaderParse *parse)
{
for(const auto &ubo:parse->GetUBO())
{
const UTF8String & name =parse->GetName(ubo);
const uint binding =parse->GetBinding(ubo);
ubo_map.Add(name,binding);
ubo_list.Add(binding);
}
}
void VertexShaderModule::ParseVertexInput(const ShaderParse *parse)
{
const auto &stage_inputs=parse->GetStageInput();
attr_count=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(const auto &si:stage_inputs)
{
const VkFormat format =parse->GetFormat(si); //注意这个格式有可能会解析不出来(比如各种压缩格式)
const UTF8String & name =parse->GetName(si);
bind->binding =binding_index; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号所以这个数字必须从0开始而且紧密排列。
//在VertexInput类中buf_list需要严格按照本此binding为序列号排列
bind->stride =GetStrideByFormat(format);
bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX;
//binding对应的是第几个数据输入流
//实际使用一个binding可以绑定多个attrib
//比如在一个流中传递{pos,color}这样两个数据就需要两个attrib
//但在我们的设计中仅支持一个流传递一个attrib
attr->binding =binding_index;
attr->location =parse->GetLocation(si); //此值对应shader中的layout(location=
attr->format =format;
attr->offset =0;
stage_input_locations.Add(name,attr);
++attr;
++bind;
++binding_index;
}
}
VertexShaderModule::~VertexShaderModule()
{
if(vab_sets.GetCount()>0)
{
//还有在用的,这是个错误
}
SAFE_CLEAR_ARRAY(binding_list);
SAFE_CLEAR_ARRAY(attribute_list);
}
const int VertexShaderModule::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 VertexShaderModule::GetBinding(const UTF8String &name)const
{
if(name.IsEmpty())return -1;
VkVertexInputAttributeDescription *attr;
if(!stage_input_locations.Get(name,attr))
return -1;
return attr->binding;
}
VertexAttributeBinding *VertexShaderModule::CreateVertexAttributeBinding()
{
VertexAttributeBinding *vab=new VertexAttributeBinding(this);
vab_sets.Add(vab);
return(vab);
}
bool VertexShaderModule::Release(VertexAttributeBinding *vab)
{
return vab_sets.Delete(vab);
}
VK_NAMESPACE_END

View File

@ -4,7 +4,13 @@
#include"VK.h"
#include<hgl/type/BaseString.h>
#include<hgl/type/Map.h>
VK_NAMESPACE_BEGIN
using ShaderBindingList=List<uint32_t>; ///<shader绑定点列表
class ShaderParse;
/**
* Shader模块<br>
* shader数据和信息ShaderModuleManage创建和删除
@ -19,19 +25,17 @@ private:
VkPipelineShaderStageCreateInfo *stage_create_info;
uint32_t attr_count;
VkVertexInputBindingDescription *binding_list;
VkVertexInputAttributeDescription *attribute_list;
Map<UTF8String,int> ubo_map;
ShaderBindingList ubo_list;
private:
protected:
Map<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
Map<UTF8String,int> ubo_list;
void ParseUBO(const ShaderParse *);
public:
ShaderModule(int id,VkPipelineShaderStageCreateInfo *);
~ShaderModule();
ShaderModule(int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *);
virtual ~ShaderModule();
const int GetID()const{return shader_id;}
@ -47,22 +51,61 @@ public:
{
int binding;
if(ubo_list.Get(name,binding))
if(ubo_map.Get(name,binding))
return binding;
else
return -1;
}
const uint32_t GetAttrCount()const{return attr_count;}
const ShaderBindingList & GetUBOBindingList()const{return ubo_list;} ///<取得UBO绑定点列表
};//class ShaderModule
class VertexAttributeBinding;
/**
* Shader模块<br>
* shader在最前方执行shader多了VertexInput的数据
*/
class VertexShaderModule:public ShaderModule
{
uint32_t attr_count;
VkVertexInputBindingDescription *binding_list;
VkVertexInputAttributeDescription *attribute_list;
private:
Map<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
Set<VertexAttributeBinding *> vab_sets;
private:
void ParseVertexInput(const ShaderParse *);
public:
VertexShaderModule(int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *parse):ShaderModule(id,pssci,parse)
{
ParseVertexInput(parse);
}
virtual ~VertexShaderModule();
const int GetLocation (const UTF8String &)const;
const int GetBinding (const UTF8String &)const;
const uint32_t GetAttrCount()const{return attr_count;}
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 ShaderModule
public:
VertexAttributeBinding * CreateVertexAttributeBinding();
bool Release(VertexAttributeBinding *);
const uint32_t GetInstanceCount()const{return vab_sets.GetCount();}
};//class VertexShaderModule:public ShaderModule
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE

View File

@ -1,5 +1,9 @@
#include"VKShaderModuleManage.h"
#include"VKShaderModule.h"
#include"VKMaterial.h"
#include"VKDevice.h"
#include"AssetsManage.h"
#include"VKShaderParse.h"
VK_NAMESPACE_BEGIN
const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size)
@ -19,11 +23,18 @@ const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits
moduleCreateInfo.codeSize=spv_size;
moduleCreateInfo.pCode=(const uint32_t *)spv_data;
if(vkCreateShaderModule(device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS)
if(vkCreateShaderModule(*device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS)
return(nullptr);
ShaderModule *sm=new ShaderModule(shader_count,shader_stage);
ShaderModule *sm;
ShaderParse *parse=new ShaderParse(spv_data,spv_size);
if(shader_stage_bit==VK_SHADER_STAGE_VERTEX_BIT)
sm=new VertexShaderModule(shader_count,shader_stage,parse);
else
sm=new ShaderModule(shader_count,shader_stage,parse);
delete parse;
shader_list.Add(shader_count,sm);
++shader_count;
@ -31,6 +42,21 @@ const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits
return sm;
}
const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const UTF8String &filename)
{
uint32_t spv_size;
void *spv_data=LoadFileToMemory(filename,spv_size);
if(!spv_data)
return(nullptr);
const ShaderModule *sm=CreateShader(shader_stage_bit,spv_data,spv_size);
delete[] spv_data;
return sm;
}
const ShaderModule *ShaderModuleManage::GetShader(int id)
{
ShaderModule *sm;
@ -58,4 +84,20 @@ bool ShaderModuleManage::ReleaseShader(const ShaderModule *const_sm)
sm->DecRef();
return(true);
}
const Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module)const
{
if(!vertex_shader_module||!fragment_shader_module)
return(nullptr);
if(vertex_shader_module->GetStage()!=VK_SHADER_STAGE_VERTEX_BIT)return(nullptr);
if(fragment_shader_module->GetStage()!=VK_SHADER_STAGE_FRAGMENT_BIT)return(nullptr);
ShaderModuleMap *smm=new ShaderModuleMap;
smm->Add(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_module);
smm->Add(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_module);
return(new Material(device,smm));
}
VK_NAMESPACE_END

View File

@ -3,8 +3,12 @@
#include"VK.h"
#include<hgl/type/Map.h>
#include<hgl/type/BaseString.h>
VK_NAMESPACE_BEGIN
class Device;
class ShaderModule;
class VertexShaderModule;
class Material;
/**
* ShaderÄ£¿é¹ÜÀíÆ÷<br>
@ -13,14 +17,14 @@ class ShaderModule;
*/
class ShaderModuleManage
{
VkDevice device;
Device *device;
int shader_count;
Map<int,ShaderModule *> shader_list;
public:
ShaderModuleManage(VkDevice dev)
ShaderModuleManage(Device *dev)
{
device=dev;
shader_count=0;
@ -29,6 +33,7 @@ public:
~ShaderModuleManage();
const ShaderModule *CreateShader(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size);
const ShaderModule *CreateShader(const VkShaderStageFlagBits shader_stage_bit,const UTF8String &filename);
#define ADD_SHADER_FUNC(sn,vk_name) const ShaderModule *Create##sn##Shader(const void *spv_data,const uint32_t spv_size){return CreateShader(VK_SHADER_STAGE_##vk_name##_BIT,spv_data,spv_size);}
ADD_SHADER_FUNC(Vertex, VERTEX)
@ -52,6 +57,25 @@ public:
const ShaderModule *GetShader (int);
bool ReleaseShader (const ShaderModule *);
const Material * CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module)const;
const Material * CreateMaterial(const UTF8String &vertex_shader_filename,const UTF8String &fragment_shader_filename)
{
const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename);
if(!fs)
{
ReleaseShader(vs);
return(nullptr);
}
return(CreateMaterial((VertexShaderModule *)vs,fs));
}
};//class ShaderModuleManage
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE

View File

@ -1,12 +1,12 @@
#include"VKVertexAttributeBinding.h"
#include"VKShader.h"
#include"VKShaderModule.h"
VK_NAMESPACE_BEGIN
VertexAttributeBinding::VertexAttributeBinding(Shader *s)
VertexAttributeBinding::VertexAttributeBinding(VertexShaderModule *s)
{
shader=s;
vsm=s;
attr_count=shader->GetAttrCount();
attr_count=vsm->GetAttrCount();
if(attr_count<=0)
{
@ -15,8 +15,8 @@ VertexAttributeBinding::VertexAttributeBinding(Shader *s)
return;
}
binding_list=hgl_copy_new(attr_count,shader->GetDescList());
attribute_list=hgl_copy_new(attr_count,shader->GetAttrList());
binding_list=hgl_copy_new(attr_count,vsm->GetDescList());
attribute_list=hgl_copy_new(attr_count,vsm->GetAttrList());
}
VertexAttributeBinding::~VertexAttributeBinding()
@ -24,12 +24,12 @@ VertexAttributeBinding::~VertexAttributeBinding()
delete[] attribute_list;
delete[] binding_list;
shader->Release(this);
vsm->Release(this);
}
const uint VertexAttributeBinding::GetIndex(const UTF8String &name)
const uint VertexAttributeBinding::GetBinding(const UTF8String &name)
{
return shader->GetBinding(name);
return vsm->GetBinding(name);
}
bool VertexAttributeBinding::SetInstance(const uint index,bool instance)
@ -72,7 +72,7 @@ void VertexAttributeBinding::Write(VkPipelineVertexInputStateCreateInfo &vis_cre
{
vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
const uint32_t count=shader->GetAttrCount();
const uint32_t count=vsm->GetAttrCount();
vis_create_info.vertexBindingDescriptionCount = count;
vis_create_info.pVertexBindingDescriptions = binding_list;

View File

@ -6,7 +6,7 @@
VK_NAMESPACE_BEGIN
class VertexBuffer;
class IndexBuffer;
class Shader;
class VertexShaderModule;
/**
* <br>
@ -14,32 +14,32 @@ class Shader;
*/
class VertexAttributeBinding
{
Shader *shader;
VertexShaderModule *vsm;
uint32_t attr_count;
VkVertexInputBindingDescription *binding_list;
VkVertexInputAttributeDescription *attribute_list;
private:
friend class Shader;
friend class VertexShaderModule;
VertexAttributeBinding(Shader *);
VertexAttributeBinding(VertexShaderModule *);
public:
~VertexAttributeBinding();
const uint GetIndex(const UTF8String &name);
const uint GetBinding(const UTF8String &name); ///<取得一个变量的绑定点
bool SetInstance(const uint index,bool instance);
bool SetStride (const uint index,const uint32_t & stride);
bool SetFormat (const uint index,const VkFormat & format);
bool SetOffset (const uint index,const uint32_t offset);
bool SetInstance(const uint binding,bool instance);
bool SetStride (const uint binding,const uint32_t & stride);
bool SetFormat (const uint binding,const VkFormat & format);
bool SetOffset (const uint binding,const uint32_t offset);
bool SetInstance(const UTF8String &name,bool instance){return SetInstance(GetIndex(name),instance);}
bool SetStride (const UTF8String &name,const uint32_t &stride ){return SetStride (GetIndex(name),stride);}
bool SetFormat (const UTF8String &name,const VkFormat &format ){return SetFormat (GetIndex(name),format);}
bool SetOffset (const UTF8String &name,const uint32_t offset ){return SetOffset (GetIndex(name),offset);}
bool SetInstance(const UTF8String &name,bool instance){return SetInstance(GetBinding(name),instance);}
bool SetStride (const UTF8String &name,const uint32_t &stride ){return SetStride (GetBinding(name),stride);}
bool SetFormat (const UTF8String &name,const VkFormat &format ){return SetFormat (GetBinding(name),format);}
bool SetOffset (const UTF8String &name,const uint32_t offset ){return SetOffset (GetBinding(name),offset);}
void Write(VkPipelineVertexInputStateCreateInfo &vis)const;
};//class VertexAttributeBinding

View File

@ -1,9 +1,9 @@
#include"VKVertexInput.h"
#include"VKBuffer.h"
#include"VKShader.h"
#include"VKShaderModule.h"
VK_NAMESPACE_BEGIN
VertexInput::VertexInput(const Shader *s)
VertexInput::VertexInput(const VertexShaderModule *s)
{
shader=s;
@ -40,6 +40,8 @@ bool VertexInput::Set(const int index,VertexBuffer *buf,VkDeviceSize offset)
bool VertexInput::Set(const UTF8String &name,VertexBuffer *vb,VkDeviceSize offset)
{
return Set(shader->GetBinding(name),vb,offset);
const int binding=shader->GetBinding(name);
return Set(binding,vb,offset);
}
VK_NAMESPACE_END

View File

@ -6,7 +6,7 @@
VK_NAMESPACE_BEGIN
class VertexBuffer;
class IndexBuffer;
class Shader;
class VertexShaderModule;
/**
* buffer绑定CommandBuffer使用<br>
@ -14,7 +14,7 @@ class Shader;
*/
class VertexInput
{
const Shader *shader;
const VertexShaderModule *shader;
int buf_count=0;
VkBuffer *buf_list=nullptr;
@ -25,7 +25,7 @@ class VertexInput
public:
VertexInput(const Shader *);
VertexInput(const VertexShaderModule *);
virtual ~VertexInput();
bool Set(const int binding, VertexBuffer *vb,VkDeviceSize offset=0);

View File

@ -3,7 +3,8 @@
#include"VKPhysicalDevice.h"
#include"VKDevice.h"
#include"VKBuffer.h"
#include"VKShader.h"
#include"VKShaderModule.h"
#include"VKShaderModuleManage.h"
#include"VKImageView.h"
#include"VKVertexInput.h"
#include"VKDescriptorSets.h"
@ -13,13 +14,9 @@
#include"VKCommandBuffer.h"
#include"VKFormat.h"
#include"VKFramebuffer.h"
#include"VKMaterial.h"
#include<hgl/math/Math.h>
#include<fstream>
#ifndef WIN32
#include<unistd.h>
#endif//
using namespace hgl;
using namespace hgl::graph;
@ -34,72 +31,13 @@ struct WorldConfig
Matrix4f mvp;
}world;
char *LoadFile(const char *filename,uint32_t &file_length)
{
std::ifstream fs;
fs.open(filename,std::ios_base::binary);
if(!fs.is_open())
return(nullptr);
fs.seekg(0,std::ios_base::end);
file_length=fs.tellg();
char *data=new char[file_length];
fs.seekg(0,std::ios_base::beg);
fs.read(data,file_length);
fs.close();
return data;
}
bool LoadShader(vulkan::Shader *sc,const char *filename,VkShaderStageFlagBits shader_flag)
{
uint32_t size;
char *data=LoadFile(filename,size);
if(!data)
return(false);
if(!sc->CreateShader(shader_flag,data,size))
return(false);
delete[] data;
return(true);
}
vulkan::Shader *LoadShader(VkDevice device)
{
vulkan::Shader *sc=new vulkan::Shader(device);
if(LoadShader(sc,"FlatColor.vert.spv",VK_SHADER_STAGE_VERTEX_BIT))
if(LoadShader(sc,"FlatColor.frag.spv",VK_SHADER_STAGE_FRAGMENT_BIT))
return sc;
delete sc;
return(nullptr);
}
vulkan::Buffer *CreateUBO(vulkan::Device *dev)
{
{
const VkExtent2D extent=dev->GetExtent();
const VkExtent2D extent=dev->GetExtent();
world.mvp=ortho(extent.width,extent.height);
}
world.mvp=ortho(extent.width,extent.height);
vulkan::Buffer *ubo=dev->CreateUBO(sizeof(WorldConfig));
uint8_t *p=ubo->Map();
if(p)
{
memcpy(p,&world,sizeof(WorldConfig));
ubo->Unmap();
}
return ubo;
return dev->CreateUBO(sizeof(WorldConfig),&world);
}
constexpr float vertex_data[]=
@ -113,17 +51,13 @@ 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::Shader *shader)
void CreateVertexBuffer(vulkan::Device *dev,vulkan::VertexInput *vi)
{
vertex_buffer =dev->CreateVBO(FMT_RG32F, 3,vertex_data);
color_buffer =dev->CreateVBO(FMT_RGB32F, 3,color_data);
vulkan::VertexInput *vi=new vulkan::VertexInput(shader);
vi->Set("Vertex", vertex_buffer);
vi->Set("Color", color_buffer);
return vi;
}
void wait_seconds(int seconds) {
@ -181,37 +115,30 @@ int main(int,char **)
std::cout<<"auto select physical device: "<<render_device->GetDeviceName()<<std::endl;
}
vulkan::Shader *shader=LoadShader(device->GetDevice());
vulkan::ShaderModuleManage *shader_manage=device->CreateShaderModuleManage();
if(!shader)
const vulkan::Material *material=shader_manage->CreateMaterial("FlatColor.vert.spv","FlatColor.frag.spv");
if(!material)
return -3;
vulkan::MaterialInstance *mi=material->CreateInstance();
vulkan::Buffer *ubo=CreateUBO(device);
vulkan::VertexAttributeBinding *vis_instance=shader->CreateVertexAttributeBinding();
vulkan::VertexInput *vi=CreateVertexBuffer(device,shader);
vulkan::PipelineCreater pc(device);
vulkan::DescriptorSetLayoutCreater dslc(device);
mi->UpdateUBO("world",*ubo);
const int ubo_world_config=shader->GetUBO("world");
CreateVertexBuffer(device,mi->GetVI());
dslc.BindUBO(ubo_world_config,VK_SHADER_STAGE_VERTEX_BIT);
vulkan::DescriptorSetLayout *dsl=dslc.Create();
dsl->UpdateUBO(ubo_world_config,*ubo);
vulkan::PipelineLayout *pl=CreatePipelineLayout(*device,dsl);
vulkan::PipelineLayout *pl=CreatePipelineLayout(*device,mi->GetDSL());
pc.SetDepthTest(false);
pc.SetDepthWrite(false);
pc.CloseCullFace();
pc.Set(shader);
pc.Set(vis_instance);
pc.Set(mi);
pc.Set(PRIM_TRIANGLES);
pc.Set(*pl);
@ -227,7 +154,7 @@ int main(int,char **)
cmd_buf->Begin(device->GetRenderPass(),device->GetFramebuffer(0));
cmd_buf->Bind(pipeline);
cmd_buf->Bind(pl);
cmd_buf->Bind(vi);
cmd_buf->Bind(mi->GetVI());
cmd_buf->Draw(3);
cmd_buf->End();
@ -235,7 +162,7 @@ int main(int,char **)
device->Wait();
device->QueuePresent();
wait_seconds(1);
wait_seconds(2);
delete vertex_buffer;
delete color_buffer;
@ -243,12 +170,13 @@ int main(int,char **)
delete pipeline;
delete pl;
delete dsl;
// delete dsl;
delete vi;
// delete vi;
delete ubo;
delete shader;
// delete shader;
delete mi;
delete cmd_buf;
delete device;