VKDevice::ChangeTexture2D add batch commit edition.
This commit is contained in:
parent
093fa93825
commit
3dbddbeb9a
@ -1 +1 @@
|
||||
Subproject commit 57a355602415294de7bcfdca9bd935db5b484388
|
||||
Subproject commit 02ede84ecd6e25cd705503018a53444bfda5af39
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user