VKDevice::ChangeTexture2D add batch commit edition.

This commit is contained in:
hyzboy 2020-07-29 17:06:43 +08:00
parent 093fa93825
commit 3dbddbeb9a
8 changed files with 179 additions and 49 deletions

@ -1 +1 @@
Subproject commit 57a355602415294de7bcfdca9bd935db5b484388
Subproject commit 02ede84ecd6e25cd705503018a53444bfda5af39

View File

@ -114,9 +114,11 @@ private:
float left =0;
float top =0;
tile_data->BeginCommit();
for(int i=0;i<count;i++)
{
(*tb)->to=tile_data->Add((*tb)->bmp); //添加一个tile图片
(*tb)->to=tile_data->Commit((*tb)->bmp); //添加一个tile图片
vp=WriteRect(vp,left+BORDER, //产生绘制顶点信息
top +BORDER,
@ -141,6 +143,8 @@ private:
++tb;
}
tile_data->EndCommit();
return(true);
}
@ -202,7 +206,7 @@ private:
AutoDelete<vulkan::PipelineCreater>
pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target);
pipeline_creater->CloseCullFace();
pipeline_creater->Set(PRIM_2D_RECTANGLES);
pipeline_creater->Set(PRIM_RECTANGLES);
pipeline=pipeline_creater->Create();

View File

@ -16,7 +16,7 @@ namespace hgl
{
int col,row; //当前tile在整个纹理中的tile位置
RectScope2d uv_pixel; //以象素为单位的tile位置和尺寸
RectScope2i uv_pixel; //以象素为单位的tile位置和尺寸
RectScope2d uv_float; //以浮点为单位的tile位置和尺寸
};//struct TileObject
@ -30,20 +30,26 @@ namespace hgl
protected:
vulkan::Buffer *tile_buffer; ///<Tile暂存缓冲区
uint pixel_bytes; ///<单个象素字节数
Texture2D *tile_texture; ///<TileData所用的纹理对象
ObjectPool<TileObject> to_pool; ///<Tile对象池
uint tile_width,tile_height; ///<Tile的宽和高
uint32_t tile_bytes; ///<一个tile字节数
uint tile_bytes; ///<一个tile字节数
uint tile_count,tile_max_count; ///<当前Tile数量与最大数量
uint tile_rows,tile_cols; ///<贴图中可用的Tile行数和列数
protected:
bool WriteTile(TileObject *,const void *,const uint,const int,const int); ///<写入一个Tile数据
vulkan::Buffer *tile_buffer; ///<Tile暂存缓冲区
List<ImageRegion> commit_list;
uint commit_offset;
uint8 *commit_ptr;
bool CommitTile(TileObject *,const void *,const uint,const int,const int); ///<提交一个Tile数据
public:
@ -60,11 +66,15 @@ namespace hgl
TileData(Device *,Texture2D *,const uint tw,const uint th);
virtual ~TileData();
TileObject *Add(const void *,const uint,const int=-1,const int=-1); ///<增加一个Tile
TileObject *Add(BitmapData *bmp){return this->Add(bmp->data,bmp->total_bytes,bmp->width,bmp->height);} ///<增加一个Tile
void BeginCommit();
TileObject *Commit(const void *,const uint,const int=-1,const int=-1); ///<提交一个Tile
TileObject *Commit(BitmapData *bmp){return this->Commit(bmp->data,bmp->total_bytes,bmp->width,bmp->height);}///<提交一个Tile
bool Change(TileObject *,const void *,const uint,const int=-1,const int=-1); ///<更改一个Tile的数据内容
int EndCommit();
bool Delete(TileObject *); ///<删除一个Tile
bool Change(TileObject *,const void *,const uint,const int=-1,const int=-1); ///<更改一个Tile的数据内容
void Clear(); ///<清除Tile数据
};//class TileData
}//namespace graph

View File

@ -4,7 +4,9 @@
#include<hgl/type/List.h>
#include<hgl/type/BaseString.h>
#include<hgl/type/Map.h>
#include<hgl/type/RectScope.h>
#include<hgl/platform/Window.h>
#include<hgl/graph/Bitmap.h>
#include<hgl/graph/vulkan/VK.h>
#include<hgl/graph/vulkan/VKDeviceAttribute.h>
#include<hgl/graph/vulkan/VKSwapchain.h>
@ -179,9 +181,35 @@ public: //Texture
const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
const VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL);
bool ChangeTexture2D(Texture2D *,Buffer *buf,const VkBufferImageCopy *,const int count);
bool ChangeTexture2D(Texture2D *,Buffer *buf,const List<ImageRegion> &);
bool ChangeTexture2D(Texture2D *,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height);
bool ChangeTexture2D(Texture2D *,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size);
template<typename T>
bool ChangeTexture2D(Texture2D *tex,Buffer *buf,const RectScope2<T> &rs)
{
return ChangeTexture2D( tex,
buf,
rs.GetLeft(),
rs.GetTop(),
rs.GetWidth(),
rs.GetHeight());
}
template<typename T>
bool ChangeTexture2D(Texture2D *tex,void *data,const RectScope2<T> &rs,uint32_t size)
{
return ChangeTexture2D( tex,
buf,
rs.GetLeft(),
rs.GetTop(),
rs.GetWidth(),
rs.GetHeight(),
size);
}
public: //
Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr);

View File

@ -14,7 +14,7 @@
#define PRIM_TRIANGLES_ADJ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ///<代表一个有六个顶点的Primitive,其中第1,3,5个顶点代表一个Triangle,而地2,4,6个点提供邻近信息.(由1起算)
#define PRIM_TRIANGLE_STRIP_ADJ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ///<4+2N个Vertices代表N个Primitive,其中1,3,5,7,9...代表原本的Triangle strip形成Triangle,而2,4,6,8,10...代表邻近提供信息的点.(由1起算)
#define PRIM_PATCHS VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
#define PRIM_2D_RECTANGLES 0x100 ///<矩形(并非原生支持。以画点形式在每个点的Position中传递Left,Top,Width,Height。在Geometry Shader中转换为2个三角形。用于2D游戏或UI)
#define PRIM_RECTANGLES 0x100 ///<矩形(并非原生支持。以画点形式在每个点的Position中传递Left,Top,Width,Height。在Geometry Shader中转换为2个三角形。用于2D游戏或UI)
#define PRIM_BEGIN VK_PRIMITIVE_TOPOLOGY_POINT_LIST
#define PRIM_END VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
constexpr uint32_t PRIM_RANGE =PRIM_END-PRIM_BEGIN+1;

View File

@ -109,29 +109,11 @@ Texture2D *Device::CreateTexture2D(const VkFormat format,void *data,uint32_t wid
return(tex);
}
bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height)
bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count)
{
if(!tex||!buf
||left<0||left+width>tex->GetWidth()
||top<0||top+height>tex->GetHeight()
||width<=0||height<=0)
if(!tex||!buf)
return(false);
VkBufferImageCopy buffer_image_copy;
buffer_image_copy.bufferOffset = 0;
buffer_image_copy.bufferRowLength = 0;
buffer_image_copy.bufferImageHeight = 0;
buffer_image_copy.imageSubresource.aspectMask = tex->GetAspect();
buffer_image_copy.imageSubresource.mipLevel = 0;
buffer_image_copy.imageSubresource.baseArrayLayer = 0;
buffer_image_copy.imageSubresource.layerCount = 1;
buffer_image_copy.imageOffset.x = left;
buffer_image_copy.imageOffset.y = top;
buffer_image_copy.imageOffset.z = 0;
buffer_image_copy.imageExtent.width = width;
buffer_image_copy.imageExtent.height= height;
buffer_image_copy.imageExtent.depth = 1;
VkImageSubresourceRange subresourceRange;
subresourceRange.aspectMask = tex->GetAspect();
subresourceRange.baseMipLevel = 0;
@ -164,8 +146,8 @@ bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t t
buf->GetBuffer(),
tex->GetImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&buffer_image_copy);
count,
buffer_image_copy);
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
@ -186,6 +168,70 @@ bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t t
return(true);
}
bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,const List<ImageRegion> &ir_list)
{
if(!tex||!buf||ir_list.GetCount()<=0)
return(false);
const int ir_count=ir_list.GetCount();
int count=0;
AutoDeleteArray<VkBufferImageCopy> buffer_image_copy=new VkBufferImageCopy[ir_count];
VkBufferImageCopy *tp=buffer_image_copy;
const ImageRegion *sp=ir_list.GetData();
VkDeviceSize offset=0;
for(int i=0;i<ir_list.GetCount();i++)
{
tp->bufferOffset = offset;
tp->bufferRowLength = 0;
tp->bufferImageHeight = 0;
tp->imageSubresource.aspectMask = tex->GetAspect();
tp->imageSubresource.mipLevel = 0;
tp->imageSubresource.baseArrayLayer = 0;
tp->imageSubresource.layerCount = 1;
tp->imageOffset.x = sp->left;
tp->imageOffset.y = sp->top;
tp->imageOffset.z = 0;
tp->imageExtent.width = sp->width;
tp->imageExtent.height= sp->height;
tp->imageExtent.depth = 1;
offset+=sp->bytes;
++sp;
++tp;
}
return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count);
}
bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height)
{
if(!tex||!buf
||left<0||left+width>tex->GetWidth()
||top<0||top+height>tex->GetHeight()
||width<=0||height<=0)
return(false);
VkBufferImageCopy buffer_image_copy;
buffer_image_copy.bufferOffset = 0;
buffer_image_copy.bufferRowLength = 0;
buffer_image_copy.bufferImageHeight = 0;
buffer_image_copy.imageSubresource.aspectMask = tex->GetAspect();
buffer_image_copy.imageSubresource.mipLevel = 0;
buffer_image_copy.imageSubresource.baseArrayLayer = 0;
buffer_image_copy.imageSubresource.layerCount = 1;
buffer_image_copy.imageOffset.x = left;
buffer_image_copy.imageOffset.y = top;
buffer_image_copy.imageOffset.z = 0;
buffer_image_copy.imageExtent.width = width;
buffer_image_copy.imageExtent.height= height;
buffer_image_copy.imageExtent.depth = 1;
return ChangeTexture2D(tex,buf,&buffer_image_copy,1);
}
bool Device::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size)
{
if(!tex||!data

View File

@ -220,12 +220,12 @@ PipelineCreater::PipelineCreater(Device *dev,const Material *material,const Rend
bool PipelineCreater::Set(const uint topology,bool restart)
{
if(topology<PRIM_BEGIN||topology>PRIM_END)
if(topology!=PRIM_2D_RECTANGLES)return(false);
if(topology!=PRIM_RECTANGLES)return(false);
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssembly.pNext = nullptr;
inputAssembly.flags = 0;
inputAssembly.topology = VkPrimitiveTopology(topology==PRIM_2D_RECTANGLES?VK_PRIMITIVE_TOPOLOGY_POINT_LIST:topology);
inputAssembly.topology = VkPrimitiveTopology(topology==PRIM_RECTANGLES?VK_PRIMITIVE_TOPOLOGY_POINT_LIST:topology);
inputAssembly.primitiveRestartEnable = restart;
pipelineInfo.pInputAssemblyState = &inputAssembly;

View File

@ -48,9 +48,13 @@ namespace hgl
}
}
tile_bytes=tile_width*tile_height*GetStrideByFormat(tile_texture->GetFormat());
pixel_bytes =GetStrideByFormat(tile_texture->GetFormat());
tile_bytes =tile_width*tile_height*pixel_bytes;
tile_buffer=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tile_bytes,nullptr);
tile_buffer=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tile_bytes*tile_max_count,nullptr);
commit_offset=0;
commit_ptr=nullptr;
}
TileData::~TileData()
@ -58,9 +62,36 @@ namespace hgl
SAFE_CLEAR(tile_buffer);
SAFE_CLEAR(tile_texture);
}
bool TileData::WriteTile(TileObject *obj,const void *data,const uint bytes,int ctw,int cth)
void TileData::BeginCommit()
{
commit_list.ClearData();
commit_offset=0;
commit_ptr=(uint8 *)tile_buffer->Map();
}
int TileData::EndCommit()
{
const int commit_count=commit_list.GetCount();
if(commit_count<=0)
return -1;
tile_buffer->Unmap();
commit_ptr=nullptr;
if(!device->ChangeTexture2D(tile_texture,tile_buffer,commit_list))
return -2;
const int result=commit_list.GetCount();
commit_list.ClearData();
return result;
}
bool TileData::CommitTile(TileObject *obj,const void *data,const uint bytes,int ctw,int cth)
{
if(!commit_ptr)return(false);
if(!obj||!data||!bytes||ctw<=0||cth<=0)
return(false);
@ -72,14 +103,23 @@ namespace hgl
tile_texture->GetWidth(),
tile_texture->GetHeight());
tile_buffer->Write(data,0,bytes);
const int commit_count=commit_list.GetCount();
device->ChangeTexture2D(tile_texture,
tile_buffer,
obj->uv_pixel.GetLeft(),
obj->uv_pixel.GetTop(),
tile_width,
tile_height);
if(commit_count>=tile_max_count) //理论上不可能
return(false);
memcpy(commit_ptr,data,bytes);
commit_ptr+=bytes;
ImageRegion ir;
ir.left =obj->uv_pixel.GetLeft();
ir.top =obj->uv_pixel.GetTop();
ir.width =obj->uv_pixel.GetWidth();
ir.height =obj->uv_pixel.GetHeight();
ir.bytes =bytes;
commit_list.Add(ir);
return(true);
}
@ -92,8 +132,9 @@ namespace hgl
* @param cth tile高度,-1
* @return Tile创建的对象
*/
TileObject *TileData::Add(const void *data,const uint bytes,const int ctw,const int cth)
TileObject *TileData::Commit(const void *data,const uint bytes,const int ctw,const int cth)
{
if(!commit_ptr)return(false);
if(!data||!bytes||ctw<=0||cth<=0)
return(nullptr);
@ -102,7 +143,7 @@ namespace hgl
if(!to_pool.Get(obj))
return(nullptr);
WriteTile(obj,data,bytes,ctw,cth);
CommitTile(obj,data,bytes,ctw,cth);
tile_count++;
return(obj);
@ -131,13 +172,14 @@ namespace hgl
*/
bool TileData::Change(TileObject *obj,const void *data,const uint bytes,const int ctw,const int cth)
{
if(!commit_ptr)return(false);
if(!obj||!data||!bytes||ctw<=0||cth<=0)
return(false);
if(!to_pool.IsActive(obj))
return(false);
return WriteTile(obj,data,bytes,ctw,cth);
return CommitTile(obj,data,bytes,ctw,cth);
}
/**