rename and layout codes.

This commit is contained in:
hyzboy 2024-05-27 01:42:10 +08:00
parent 8bb97ef2de
commit 742fe201ad
12 changed files with 115 additions and 118 deletions

View File

@ -216,7 +216,7 @@ public:
{ {
if(!ri)return(false); if(!ri)return(false);
const VertexInputData *vid=ri->GetVertexInputData(); const PrimitiveRenderBuffer *prb=ri->GetRenderBuffer();
cb->Begin(); cb->Begin();
cb->BindFramebuffer(rp,fb); cb->BindFramebuffer(rp,fb);
@ -225,7 +225,7 @@ public:
cb->BindPipeline(ri->GetPipeline()); cb->BindPipeline(ri->GetPipeline());
cb->BindDescriptorSets(ri->GetMaterial()); cb->BindDescriptorSets(ri->GetMaterial());
cb->BindVAB(ri); cb->BindVAB(ri);
cb->Draw(vid,ri->GetDrawData()); cb->Draw(prb,ri->GetRenderData());
cb->EndRenderPass(); cb->EndRenderPass();
cb->End(); cb->End();

View File

@ -5,7 +5,6 @@
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class RenderAssignBuffer; class RenderAssignBuffer;
/** /**
* *
*/ */
@ -24,13 +23,13 @@ private:
struct RenderItem struct RenderItem
{ {
uint32_t first; uint32_t first;
uint32_t count; uint32_t count;
Pipeline * pipeline; Pipeline * pipeline;
MaterialInstance * mi; MaterialInstance * mi;
const VertexInputData * vid; const PrimitiveRenderBuffer * prb;
const DrawData * dd; const PrimitiveRenderData * prd;
public: public:
@ -44,14 +43,13 @@ private:
protected: protected:
VABList * vbo_list; VABList * vbo_list;
Pipeline * last_pipeline; Pipeline * last_pipeline;
const VertexInputData * last_vid; const PrimitiveRenderBuffer * last_render_buf;
const DrawData * last_dd; const PrimitiveRenderData * last_render_data;
uint last_index;
bool BindVAB(const VertexInputData *,const DrawData *,const uint); bool BindVAB(const PrimitiveRenderBuffer *,const PrimitiveRenderData *,const uint);
void Render(RenderItem *); void Render(RenderItem *);

View File

@ -54,8 +54,8 @@ class DeviceMemory;
class DeviceBuffer; class DeviceBuffer;
struct DeviceBufferData; struct DeviceBufferData;
struct VertexInputData; struct PrimitiveRenderBuffer;
struct DrawData; struct PrimitiveRenderData;
class VertexAttribBuffer; class VertexAttribBuffer;
using VAB=VertexAttribBuffer; using VAB=VertexAttribBuffer;

View File

@ -209,7 +209,7 @@ public: //draw
void DrawIndirect (VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndirectCommand )){return DrawIndirect( buf,0,drawCount,stride);} void DrawIndirect (VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndirectCommand )){return DrawIndirect( buf,0,drawCount,stride);}
void DrawIndexedIndirect(VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndexedIndirectCommand )){return DrawIndexedIndirect( buf,0,drawCount,stride);} void DrawIndexedIndirect(VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndexedIndirectCommand )){return DrawIndexedIndirect( buf,0,drawCount,stride);}
void Draw (const VertexInputData *vid,const DrawData *dd); void Draw (const PrimitiveRenderBuffer *prb,const PrimitiveRenderData *prd);
// void DrawIndexed (const IBAccess *iba,const uint32_t instance_count); // void DrawIndexed (const IBAccess *iba,const uint32_t instance_count);
public: //dynamic state public: //dynamic state

View File

@ -22,7 +22,7 @@ class Material
{ {
AnsiString name; AnsiString name;
VertexInput *vertex_input_data; VertexInput *primitive_render_buffer;
ShaderModuleMap *shader_maps; ShaderModuleMap *shader_maps;
@ -51,7 +51,7 @@ public:
const AnsiString & GetName ()const{return name;} const AnsiString & GetName ()const{return name;}
const VertexInput * GetVertexInput ()const{return vertex_input_data;} const VertexInput * GetVertexInput ()const{return primitive_render_buffer;}
const ShaderStageCreateInfoList & GetStageList ()const{return shader_stage_list;} const ShaderStageCreateInfoList & GetStageList ()const{return shader_stage_list;}

View File

@ -9,35 +9,35 @@
#include<hgl/graph/VKMaterialInstance.h> #include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VertexAttrib.h> #include<hgl/graph/VertexAttrib.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
struct VertexInputData struct PrimitiveRenderBuffer
{ {
uint32_t vab_count; uint32_t vab_count;
VkBuffer *vab_list; VkBuffer * vab_list;
IndexBuffer *ibo; IndexBuffer * ibo;
public: public:
VertexInputData(const uint32_t,const uint32_t,const IBAccess *iba); PrimitiveRenderBuffer(const uint32_t,const uint32_t,const IBAccess *iba);
~VertexInputData(); ~PrimitiveRenderBuffer();
const bool Comp(const VertexInputData *vid)const; const bool Comp(const PrimitiveRenderBuffer *prb)const;
};//struct VertexInputData };//struct PrimitiveRenderBuffer
struct DrawData struct PrimitiveRenderData
{ {
uint vab_count; uint vab_count;
VkDeviceSize * vab_offset; VkDeviceSize * vab_offset;
VkDeviceSize vertex_count; uint32_t vertex_count;
VkDeviceSize index_start; uint32_t index_start;
VkDeviceSize index_count; uint32_t index_count;
public: public:
DrawData(const uint32_t bc,const VkDeviceSize vc,const IBAccess *iba); PrimitiveRenderData(const uint32_t bc,const uint32_t vc,const IBAccess *iba);
~DrawData(); ~PrimitiveRenderData();
const bool Comp(const DrawData *)const; const bool Comp(const PrimitiveRenderData *)const;
}; };
/** /**
@ -49,14 +49,14 @@ class Renderable
MaterialInstance * mat_inst; MaterialInstance * mat_inst;
Primitive * primitive; Primitive * primitive;
VertexInputData * vertex_input_data; PrimitiveRenderBuffer * primitive_render_buffer;
DrawData * draw_data; PrimitiveRenderData * primitive_render_data;
private: private:
friend Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *); friend Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *);
Renderable(Primitive *,MaterialInstance *,Pipeline *,VertexInputData *,DrawData *); Renderable(Primitive *,MaterialInstance *,Pipeline *,PrimitiveRenderBuffer *,PrimitiveRenderData *);
public: public:
@ -64,8 +64,8 @@ public:
{ {
//需要在这里添加删除pipeline/desc_sets/primitive引用计数的代码 //需要在这里添加删除pipeline/desc_sets/primitive引用计数的代码
SAFE_CLEAR(vertex_input_data); SAFE_CLEAR(primitive_render_buffer);
SAFE_CLEAR(draw_data); SAFE_CLEAR(primitive_render_data);
} }
void UpdatePipeline (Pipeline *p){pipeline=p;} void UpdatePipeline (Pipeline *p){pipeline=p;}
@ -77,8 +77,8 @@ public:
Primitive * GetPrimitive (){return primitive;} Primitive * GetPrimitive (){return primitive;}
const AABB & GetBoundingBox ()const{return primitive->GetBoundingBox();} const AABB & GetBoundingBox ()const{return primitive->GetBoundingBox();}
const VertexInputData * GetVertexInputData ()const{return vertex_input_data;} const PrimitiveRenderBuffer * GetRenderBuffer ()const{return primitive_render_buffer;}
const DrawData * GetDrawData ()const{return draw_data;} const PrimitiveRenderData * GetRenderData ()const{return primitive_render_data;}
};//class Renderable };//class Renderable
Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *); Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *);

View File

@ -91,10 +91,10 @@ void MaterialRenderList::End()
void MaterialRenderList::RenderItem::Set(Renderable *ri) void MaterialRenderList::RenderItem::Set(Renderable *ri)
{ {
pipeline =ri->GetPipeline(); pipeline=ri->GetPipeline();
mi =ri->GetMaterialInstance(); mi =ri->GetMaterialInstance();
vid =ri->GetVertexInputData(); prb =ri->GetRenderBuffer();
dd =ri->GetDrawData(); prd =ri->GetRenderData();
} }
void MaterialRenderList::Stat() void MaterialRenderList::Stat()
@ -114,16 +114,16 @@ void MaterialRenderList::Stat()
ri->Set(rn->ri); ri->Set(rn->ri);
last_pipeline =ri->pipeline; last_pipeline =ri->pipeline;
last_vid =ri->vid; last_render_buf =ri->prb;
last_dd =ri->dd; last_render_data=ri->prd;
++rn; ++rn;
for(uint i=1;i<count;i++) for(uint i=1;i<count;i++)
{ {
if(last_pipeline==rn->ri->GetPipeline()) if(last_pipeline==rn->ri->GetPipeline())
if(last_vid->Comp(rn->ri->GetVertexInputData())) if(last_render_buf->Comp(rn->ri->GetRenderBuffer()))
if(last_dd->Comp(rn->ri->GetDrawData())) if(last_render_data->Comp(rn->ri->GetRenderData()))
{ {
++ri->count; ++ri->count;
++rn; ++rn;
@ -138,29 +138,29 @@ void MaterialRenderList::Stat()
ri->Set(rn->ri); ri->Set(rn->ri);
last_pipeline =ri->pipeline; last_pipeline =ri->pipeline;
last_vid =ri->vid; last_render_buf =ri->prb;
last_dd =ri->dd; last_render_data=ri->prd;
++rn; ++rn;
} }
} }
bool MaterialRenderList::BindVAB(const VertexInputData *vid,const DrawData *dd,const uint ri_index) bool MaterialRenderList::BindVAB(const PrimitiveRenderBuffer *prb,const PrimitiveRenderData *prd,const uint ri_index)
{ {
//binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。 //binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。
//const VIL *vil=last_vil; //const VIL *vil=last_vil;
//if(vil->GetCount(VertexInputGroup::Basic)!=vid->vab_count) //if(vil->GetCount(VertexInputGroup::Basic)!=prb->vab_count)
// return(false); //这里基本不太可能因为CreateRenderable时就会检查值是否一样 // return(false); //这里基本不太可能因为CreateRenderable时就会检查值是否一样
vbo_list->Restart(); vbo_list->Restart();
//Basic组它所有的VAB信息均来自于Primitive由vid参数传递进来 //Basic组它所有的VAB信息均来自于Primitive由vid参数传递进来
{ {
vbo_list->Add(vid->vab_list, vbo_list->Add(prb->vab_list,
nullptr,//dd->vab_offset, //暂时不用dd->vab_offset全部写0测试一下是否可以使用Draw时的firstVertex或vertexOffset nullptr,//prd->vab_offset, //暂时不用dd->vab_offset全部写0测试一下是否可以使用Draw时的firstVertex或vertexOffset
vid->vab_count); prb->vab_count);
} }
if(assign_buffer) //L2W/MI分发组 if(assign_buffer) //L2W/MI分发组
@ -213,35 +213,33 @@ void MaterialRenderList::Render(RenderItem *ri)
cmd_buf->BindPipeline(ri->pipeline); cmd_buf->BindPipeline(ri->pipeline);
last_pipeline=ri->pipeline; last_pipeline=ri->pipeline;
last_vid=nullptr; last_render_buf=nullptr;
//这里未来尝试换pipeline同时不换mi/primitive是否需要重新绑定mi/primitive //这里未来尝试换pipeline同时不换mi/primitive是否需要重新绑定mi/primitive
} }
if(!ri->vid->Comp(last_vid)) if(!ri->prb->Comp(last_render_buf))
{ {
last_vid=ri->vid; last_render_buf=ri->prb;
last_dd=nullptr; last_render_data=nullptr;
BindVAB(ri->vid,ri->dd,ri->first); BindVAB(ri->prb,ri->prd,ri->first);
cmd_buf->BindIBO(ri->vid->ibo,0); cmd_buf->BindIBO(ri->prb->ibo,0);
} }
if(last_vid->ibo) if(last_render_buf->ibo)
{ {
cmd_buf->DrawIndexed(ri->dd->index_count, cmd_buf->DrawIndexed(ri->prd->index_count,
ri->count, ri->count,
ri->dd->index_start, ri->prd->index_start,
ri->dd->vab_offset[0], //因为vkCmdDrawIndexed的vertexOffset是针对所有VAB的所以所有的VAB数据都必须是对齐的 ri->prd->vab_offset[0], //因为vkCmdDrawIndexed的vertexOffset是针对所有VAB的所以所有的VAB数据都必须是对齐的
//最终这里使用vab_offset[0]是可以的因为它也等于其它所有的vab_offset。未来考虑统一成一个。 //最终这里使用vab_offset[0]是可以的因为它也等于其它所有的vab_offset。未来考虑统一成一个。
ri->first); //这里vkCmdDrawIndexed的firstInstance参数指的是instance Rate更新的VAB的起始实例数不是指instance批量渲染。 ri->first); //这里vkCmdDrawIndexed的firstInstance参数指的是instance Rate更新的VAB的起始实例数不是指instance批量渲染。
//所以这里使用ri->first是对的。 //所以这里使用ri->first是对的。
} }
else else
{ {
cmd_buf->Draw(ri->dd->vertex_count,ri->count); cmd_buf->Draw(ri->prd->vertex_count,ri->count);
} }
} }
@ -259,7 +257,7 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb)
RenderItem *ri=ri_array.GetData(); RenderItem *ri=ri_array.GetData();
last_pipeline =nullptr; last_pipeline =nullptr;
last_vid =nullptr; last_render_buf =nullptr;
if(assign_buffer) if(assign_buffer)
assign_buffer->Bind(material); assign_buffer->Bind(material);

View File

@ -143,20 +143,20 @@ bool RenderCmdBuffer::BindVAB(Renderable *ri)
if(!ri) if(!ri)
return(false); return(false);
const VertexInputData *vid=ri->GetVertexInputData(); const PrimitiveRenderBuffer *prb=ri->GetRenderBuffer();
if(vid->vab_count<=0) if(prb->vab_count<=0)
return(false); return(false);
const DrawData *dd=ri->GetDrawData(); const PrimitiveRenderData *prd=ri->GetRenderData();
if(dd->vertex_count<=0) if(prd->vertex_count<=0)
return(false); return(false);
vkCmdBindVertexBuffers(cmd_buf,0,vid->vab_count,vid->vab_list,dd->vab_offset); vkCmdBindVertexBuffers(cmd_buf,0,prb->vab_count,prb->vab_list,prd->vab_offset);
if(vid->ibo&&dd->index_count) if(prb->ibo&&prd->index_count)
BindIBO(vid->ibo,dd->index_start); BindIBO(prb->ibo,prd->index_start);
return(true); return(true);
} }
@ -185,15 +185,15 @@ void RenderCmdBuffer::DrawIndexedIndirect( VkBuffer buffer,
vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset+i*stride,1,stride); vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset+i*stride,1,stride);
} }
void RenderCmdBuffer::Draw(const VertexInputData *vid,const DrawData *dd) void RenderCmdBuffer::Draw(const PrimitiveRenderBuffer *prb,const PrimitiveRenderData *prd)
{ {
if(!vid||!dd) if(!prb||!prd)
return; return;
if (vid->ibo) if (prb->ibo)
DrawIndexed(dd->index_count); DrawIndexed(prd->index_count);
else else
Draw(dd->vertex_count); Draw(prd->vertex_count);
} }
//void RenderCmdBuffer::DrawIndexed(const IBAccess *iba,const uint32_t instance_count) //void RenderCmdBuffer::DrawIndexed(const IBAccess *iba,const uint32_t instance_count)

View File

@ -13,7 +13,7 @@ Material::Material(const AnsiString &n)
{ {
name=n; name=n;
vertex_input_data=nullptr; primitive_render_buffer=nullptr;
shader_maps=new ShaderModuleMap; shader_maps=new ShaderModuleMap;
desc_manager=nullptr; desc_manager=nullptr;
pipeline_layout_data=nullptr; pipeline_layout_data=nullptr;
@ -28,7 +28,7 @@ Material::~Material()
{ {
SAFE_CLEAR(mi_data_manager); SAFE_CLEAR(mi_data_manager);
ReleaseVertexInput(vertex_input_data); ReleaseVertexInput(primitive_render_buffer);
delete shader_maps; //不用SAFE_CLEAR是因为这个一定会有 delete shader_maps; //不用SAFE_CLEAR是因为这个一定会有
SAFE_CLEAR(desc_manager); SAFE_CLEAR(desc_manager);
SAFE_CLEAR(pipeline_layout_data); SAFE_CLEAR(pipeline_layout_data);
@ -49,22 +49,22 @@ const bool Material::hasSet(const DescriptorSetType &dst)const
const VIL *Material::GetDefaultVIL()const const VIL *Material::GetDefaultVIL()const
{ {
return vertex_input_data->GetDefaultVIL(); return primitive_render_buffer->GetDefaultVIL();
} }
VIL *Material::CreateVIL(const VILConfig *format_map) VIL *Material::CreateVIL(const VILConfig *format_map)
{ {
return vertex_input_data->CreateVIL(format_map); return primitive_render_buffer->CreateVIL(format_map);
} }
bool Material::Release(VIL *vil) bool Material::Release(VIL *vil)
{ {
return vertex_input_data->Release(vil); return primitive_render_buffer->Release(vil);
} }
const uint Material::GetVILCount() const uint Material::GetVILCount()
{ {
return vertex_input_data->GetInstanceCount(); return primitive_render_buffer->GetInstanceCount();
} }
bool Material::BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic) bool Material::BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic)

View File

@ -19,12 +19,12 @@ class PrimitiveData
{ {
protected: protected:
const VIL * vil; const VIL * vil;
uint32_t vertex_count; uint32_t vertex_count;
VABAccess *vab_access; VABAccess * vab_access;
IBAccess ib_access; IBAccess ib_access;
public: public:

View File

@ -124,7 +124,7 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
ShaderCreateInfoVertex *vert=mci->GetVS(); ShaderCreateInfoVertex *vert=mci->GetVS();
if(vert) if(vert)
mtl->vertex_input_data=GetVertexInput(vert->sdm->GetShaderStageIO().input); mtl->primitive_render_buffer=GetVertexInput(vert->sdm->GetShaderStageIO().input);
} }
{ {

View File

@ -7,7 +7,7 @@
#include<hgl/log/LogInfo.h> #include<hgl/log/LogInfo.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
VertexInputData::VertexInputData(const uint32_t c,const uint32_t vc,const IBAccess *iba) PrimitiveRenderBuffer::PrimitiveRenderBuffer(const uint32_t c,const uint32_t vc,const IBAccess *iba)
{ {
vab_count=c; vab_count=c;
@ -19,38 +19,38 @@ VertexInputData::VertexInputData(const uint32_t c,const uint32_t vc,const IBAcce
ibo=nullptr; ibo=nullptr;
} }
VertexInputData::~VertexInputData() PrimitiveRenderBuffer::~PrimitiveRenderBuffer()
{ {
delete[] vab_list; delete[] vab_list;
} }
const bool VertexInputData::Comp(const VertexInputData *vid)const const bool PrimitiveRenderBuffer::Comp(const PrimitiveRenderBuffer *prb)const
{ {
if(!vid)return(false); if(!prb)return(false);
if(vab_count!=vid->vab_count)return(false); if(vab_count!=prb->vab_count)return(false);
for(uint32_t i=0;i<vab_count;i++) for(uint32_t i=0;i<vab_count;i++)
{ {
if(vab_list[i]!=vid->vab_list[i])return(false); if(vab_list[i]!=prb->vab_list[i])return(false);
} }
if(ibo!=vid->ibo)return(false); if(ibo!=prb->ibo)return(false);
return(true); return(true);
} }
Renderable::Renderable(Primitive *r,MaterialInstance *mi,Pipeline *p,VertexInputData *vid,DrawData *dd) Renderable::Renderable(Primitive *r,MaterialInstance *mi,Pipeline *p,PrimitiveRenderBuffer *prb,PrimitiveRenderData *prd)
{ {
primitive=r; primitive=r;
pipeline=p; pipeline=p;
mat_inst=mi; mat_inst=mi;
vertex_input_data=vid; primitive_render_buffer=prb;
draw_data=dd; primitive_render_data=prd;
} }
DrawData::DrawData(const uint32_t bc,const VkDeviceSize vc,const IBAccess *iba) PrimitiveRenderData::PrimitiveRenderData(const uint32_t bc,const uint32_t vc,const IBAccess *iba)
{ {
vab_count=bc; vab_count=bc;
@ -65,26 +65,26 @@ DrawData::DrawData(const uint32_t bc,const VkDeviceSize vc,const IBAccess *iba)
} }
} }
DrawData::~DrawData() PrimitiveRenderData::~PrimitiveRenderData()
{ {
delete[] vab_offset; delete[] vab_offset;
} }
const bool DrawData::Comp(const DrawData *dd)const const bool PrimitiveRenderData::Comp(const PrimitiveRenderData *prd)const
{ {
if(!dd)return(false); if(!prd)return(false);
if(vab_count!=dd->vab_count)return(false); if(vab_count!=prd->vab_count)return(false);
for(uint i=0;i<vab_count;i++) for(uint i=0;i<vab_count;i++)
{ {
if(vab_offset[i]!=dd->vab_offset[i])return(false); if(vab_offset[i]!=prd->vab_offset[i])return(false);
} }
if(vertex_count!=dd->vertex_count)return(false); if(vertex_count!=prd->vertex_count)return(false);
if(index_start!=dd->index_start)return(false); if(index_start!=prd->index_start)return(false);
if(index_count!=dd->index_count)return(false); if(index_count!=prd->index_count)return(false);
return(true); return(true);
} }
@ -106,10 +106,11 @@ Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
const IBAccess *iba=prim->GetIBAccess(); const IBAccess *iba=prim->GetIBAccess();
VertexInputData *vid=new VertexInputData(input_count,prim->GetVertexCount(),iba); PrimitiveRenderBuffer * prb=new PrimitiveRenderBuffer( input_count,prim->GetVertexCount(),iba);
DrawData *dd=new DrawData(input_count,prim->GetVertexCount(),iba); PrimitiveRenderData * prd=new PrimitiveRenderData( input_count,prim->GetVertexCount(),iba);
const VertexInputFormat *vif=vil->GetVIFList(VertexInputGroup::Basic); const VertexInputFormat *vif=vil->GetVIFList(VertexInputGroup::Basic);
VABAccess *vab_access; VABAccess *vab_access;
for(uint i=0;i<input_count;i++) for(uint i=0;i<input_count;i++)
@ -145,11 +146,11 @@ Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
return(nullptr); return(nullptr);
} }
dd->vab_offset[i]=vab_access->start; prd->vab_offset[i]=vab_access->start;
vid->vab_list[i]=vab_access->vab->GetBuffer(); prb->vab_list[i]=vab_access->vab->GetBuffer();
++vif; ++vif;
} }
return(new Renderable(prim,mi,p,vid,dd)); return(new Renderable(prim,mi,p,prb,prd));
} }
VK_NAMESPACE_END VK_NAMESPACE_END