235 lines
5.7 KiB
C++
235 lines
5.7 KiB
C++
#include"VKPrimitiveData.h"
|
||
#include<hgl/graph/VKVertexInputLayout.h>
|
||
#include<hgl/graph/VKVertexAttribBuffer.h>
|
||
#include<hgl/graph/VKIndexBuffer.h>
|
||
#include<hgl/graph/VKDevice.h>
|
||
#include<hgl/graph/VertexDataManager.h>
|
||
|
||
VK_NAMESPACE_BEGIN
|
||
|
||
PrimitiveData::PrimitiveData(const VIL *_vil,const uint32_t vc)
|
||
{
|
||
vil=_vil;
|
||
|
||
vertex_count=vc;
|
||
|
||
vab_list=hgl_zero_new<VAB *>(_vil->GetVertexAttribCount());
|
||
|
||
ibo=nullptr;
|
||
}
|
||
|
||
PrimitiveData::~PrimitiveData()
|
||
{
|
||
delete[] vab_list; //注意:这里并不释放VAB,在派生类中释放
|
||
}
|
||
|
||
const int PrimitiveData::GetVABCount()const
|
||
{
|
||
return vil->GetVertexAttribCount();
|
||
}
|
||
|
||
const int PrimitiveData::GetVABIndex(const AnsiString &name) const
|
||
{
|
||
if(name.IsEmpty())return(-1);
|
||
|
||
return vil->GetIndex(name);
|
||
}
|
||
|
||
VAB *PrimitiveData::GetVAB(const int index)
|
||
{
|
||
if(index<0||index>=vil->GetVertexAttribCount())return(nullptr);
|
||
|
||
return vab_list[index];
|
||
}
|
||
|
||
namespace
|
||
{
|
||
/**
|
||
* 直接使用GPUDevice创建VAB/IBO,并在释构时释放
|
||
*/
|
||
class PrimitiveDataPrivateBuffer:public PrimitiveData
|
||
{
|
||
GPUDevice *device;
|
||
|
||
public:
|
||
|
||
int32_t GetVertexOffset ()const override{return 0;}
|
||
uint32_t GetFirstIndex ()const override{return 0;}
|
||
|
||
VertexDataManager * GetVDM()const override{return nullptr;} ///<取得顶点数据管理器
|
||
|
||
public:
|
||
|
||
PrimitiveDataPrivateBuffer(GPUDevice *dev,const VIL *_vil,const uint32_t vc):PrimitiveData(_vil,vc)
|
||
{
|
||
device=dev;
|
||
}
|
||
|
||
~PrimitiveDataPrivateBuffer() override
|
||
{
|
||
VAB **vab=vab_list;
|
||
|
||
for(uint i=0;i<vil->GetVertexAttribCount();i++)
|
||
{
|
||
if(*vab)
|
||
delete *vab;
|
||
|
||
++vab;
|
||
}
|
||
|
||
if(ibo)
|
||
delete ibo;
|
||
}
|
||
|
||
IndexBuffer *InitIBO(const uint32_t ic,IndexType it) override
|
||
{
|
||
if(!device)return(nullptr);
|
||
|
||
if(ibo)delete ibo;
|
||
|
||
ibo=device->CreateIBO(it,ic);
|
||
|
||
if(!ibo)
|
||
return(nullptr);
|
||
|
||
index_count=ic;
|
||
|
||
return(ibo);
|
||
}
|
||
|
||
VAB *InitVAB(const int vab_index,const VkFormat &format,const void *data)
|
||
{
|
||
if(!device)return(nullptr);
|
||
if(!vil)return(nullptr);
|
||
|
||
if(vab_index<0||vab_index>=vil->GetVertexAttribCount())
|
||
return(nullptr);
|
||
|
||
const VertexInputFormat *vif=vil->GetConfig(vab_index);
|
||
|
||
if(!vif)return(nullptr);
|
||
|
||
if(vif->format!=format)
|
||
return(nullptr);
|
||
|
||
if(!vab_list[vab_index])
|
||
{
|
||
vab_list[vab_index]=device->CreateVAB(format,vertex_count,data);
|
||
|
||
if(!vab_list[vab_index])
|
||
return(nullptr);
|
||
}
|
||
|
||
if(vab_list[vab_index]&&data)
|
||
{
|
||
vab_list[vab_index]->Write(data,vertex_count);
|
||
}
|
||
|
||
return vab_list[vab_index];
|
||
}
|
||
};//class PrimitiveDataPrivateBuffer:public PrimitiveData
|
||
|
||
/**
|
||
* 使用VertexDataBuffer分配VAB/IBO,在本类析构时归还数据
|
||
*/
|
||
class PrimitiveDataVDM:public PrimitiveData
|
||
{
|
||
VertexDataManager *vdm;
|
||
|
||
DataChain::UserNode *ib_node;
|
||
DataChain::UserNode *vab_node;
|
||
|
||
public:
|
||
|
||
int32_t GetVertexOffset()const override { return vab_node->GetStart(); }
|
||
uint32_t GetFirstIndex ()const override { return ib_node->GetStart(); }
|
||
VertexDataManager * GetVDM()const override{return vdm;} ///<取得顶点数据管理器
|
||
|
||
public:
|
||
|
||
PrimitiveDataVDM(VertexDataManager *_vdm,const uint32_t vc):PrimitiveData(_vdm->GetVIL(),vc)
|
||
{
|
||
vdm=_vdm;
|
||
|
||
ib_node=nullptr;
|
||
vab_node=vdm->AcquireVAB(vc);
|
||
}
|
||
|
||
~PrimitiveDataVDM() override
|
||
{
|
||
if(ib_node)
|
||
vdm->ReleaseIB(ib_node);
|
||
|
||
if(vab_node)
|
||
vdm->ReleaseVAB(vab_node);
|
||
}
|
||
|
||
IndexBuffer *InitIBO(const uint32_t ic,IndexType it) override
|
||
{
|
||
if(ic<=0)return(nullptr);
|
||
if(!vdm)return(nullptr);
|
||
|
||
if(!ib_node)
|
||
{
|
||
ib_node=vdm->AcquireIB(ic);
|
||
|
||
if(!ib_node)
|
||
return(nullptr);
|
||
|
||
ibo=vdm->GetIBO();
|
||
}
|
||
|
||
index_count=ic;
|
||
|
||
return ibo;
|
||
}
|
||
|
||
VAB *InitVAB(const int vab_index,const VkFormat &format,const void *data)
|
||
{
|
||
if(!vdm)return(nullptr);
|
||
if(!vil)return(nullptr);
|
||
|
||
if (vab_index<0||vab_index>=vil->GetVertexAttribCount())
|
||
return(nullptr);
|
||
|
||
const VertexInputFormat *vif=vil->GetConfig(vab_index);
|
||
|
||
if(!vif)return(nullptr);
|
||
|
||
if(vif->format!=format)
|
||
return(nullptr);
|
||
|
||
if (!vab_list[vab_index])
|
||
{
|
||
vab_list[vab_index]=vdm->GetVAB(vab_index);
|
||
|
||
if(!vab_list[vab_index])
|
||
return(nullptr);
|
||
}
|
||
|
||
if(vab_list[vab_index]&&data)
|
||
vab_list[vab_index]->Write(data,vab_node->GetStart(),vertex_count);
|
||
|
||
return vab_list[vab_index];
|
||
}
|
||
};//class PrimitiveDataVDM:public PrimitiveData
|
||
}//namespace
|
||
|
||
PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const uint32_t vc)
|
||
{
|
||
if(!dev)return(nullptr);
|
||
if(!_vil)return(nullptr);
|
||
if(vc<=0)return(nullptr);
|
||
|
||
return(new PrimitiveDataPrivateBuffer(dev,_vil,vc));
|
||
}
|
||
|
||
PrimitiveData *CreatePrimitiveData(VertexDataManager *vdm,const uint32_t vc)
|
||
{
|
||
if(!vdm)return(nullptr);
|
||
if(vc<=0)return(nullptr);
|
||
|
||
return(new PrimitiveDataVDM(vdm,vc));
|
||
}
|
||
VK_NAMESPACE_END
|