support texture file with mipmaps data.
This commit is contained in:
parent
7f71b50316
commit
e13d442ee1
2
CMCore
2
CMCore
@ -1 +1 @@
|
||||
Subproject commit 0f3ef7ff3fad57b6a61d9700fe707ad0a97c844e
|
||||
Subproject commit 5d75e138b58826b635db09f0dd325b4e6f2d2052
|
@ -1 +1 @@
|
||||
Subproject commit 7bceaf2f9c5fbe1630e3a8b0e78eac5f4846f22e
|
||||
Subproject commit 3d644e9550395a0635332ce044a4b6453cf694f8
|
@ -42,7 +42,7 @@ private:
|
||||
MaterialInstance * material_instance =nullptr;
|
||||
Renderable * render_obj =nullptr;
|
||||
RenderableInstance *render_instance =nullptr;
|
||||
GPUBuffer * ubo_world_matrix =nullptr;
|
||||
GPUBuffer * ubo_world_matrix =nullptr;
|
||||
|
||||
Pipeline * pipeline =nullptr;
|
||||
|
||||
|
@ -9,10 +9,6 @@
|
||||
using namespace hgl;
|
||||
using namespace hgl::graph;
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
Texture2D *CreateTextureFromFile(GPUDevice *device,const OSString &filename);
|
||||
VK_NAMESPACE_END
|
||||
|
||||
constexpr uint32_t SCREEN_SIZE=512;
|
||||
|
||||
constexpr uint32_t VERTEX_COUNT=4;
|
||||
@ -79,7 +75,6 @@ public:
|
||||
SAFE_CLEAR(vertex_buffer);
|
||||
SAFE_CLEAR(sampler_nearest);
|
||||
SAFE_CLEAR(sampler_linear);
|
||||
SAFE_CLEAR(texture);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -135,7 +130,7 @@ private:
|
||||
|
||||
bool InitTexture()
|
||||
{
|
||||
texture=CreateTextureFromFile(device,OS_TEXT("res/image/heightmap.Tex2D"));
|
||||
texture=db->LoadTexture2D(OS_TEXT("res/image/heightmap.Tex2D"));
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ private:
|
||||
MaterialInstance * material_instance =nullptr;
|
||||
Renderable * render_obj =nullptr;
|
||||
RenderableInstance *render_instance =nullptr;
|
||||
GPUBuffer * ubo_world_matrix =nullptr;
|
||||
GPUBuffer * ubo_world_matrix =nullptr;
|
||||
|
||||
Pipeline * pipeline =nullptr;
|
||||
|
||||
@ -55,7 +55,7 @@ private:
|
||||
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Rectangles);
|
||||
if(!pipeline)return(false);
|
||||
|
||||
texture=CreateTextureFromFile(device,OS_TEXT("res/image/lena.Tex2D"));
|
||||
texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"));
|
||||
if(!texture)return(false);
|
||||
|
||||
sampler=db->CreateSampler();
|
||||
|
@ -4,10 +4,28 @@
|
||||
#include<hgl/io/InputStream.h>
|
||||
#include<hgl/type/String.h>
|
||||
#include<hgl/graph/Bitmap.h>
|
||||
#include<hgl/graph/VKFormat.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
constexpr VkFormat CompressFormatList[]=
|
||||
{
|
||||
FMT_BC1_RGBUN,
|
||||
FMT_BC1_RGBAUN,
|
||||
FMT_BC2UN,
|
||||
FMT_BC3UN,
|
||||
FMT_BC4UN,
|
||||
FMT_BC5UN,
|
||||
FMT_BC6UF,
|
||||
FMT_BC6SF,
|
||||
FMT_BC7UN
|
||||
};
|
||||
|
||||
constexpr uint32 CompressFormatBits[]={4,4,8,8,4,8,8,8,8};
|
||||
|
||||
constexpr uint32 CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat);
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct Tex2DFileHeader
|
||||
{
|
||||
@ -31,7 +49,8 @@ namespace hgl
|
||||
|
||||
public:
|
||||
|
||||
const uint pixel_bytes()const{return (bits[0]+bits[1]+bits[2]+bits[3])>>3;}
|
||||
const uint pixel_bits()const{return bits[0]+bits[1]+bits[2]+bits[3];}
|
||||
const uint pixel_bytes()const{return pixel_bits()>>3;}
|
||||
};//struct TexPixelFormat
|
||||
#pragma pack(pop)
|
||||
|
||||
@ -50,10 +69,12 @@ namespace hgl
|
||||
uint16 compress_format;
|
||||
};
|
||||
|
||||
uint32 total_bytes;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
uint32 mipmap_zero_total_bytes;
|
||||
|
||||
uint32 ComputeTotalBytes();
|
||||
|
||||
virtual void *OnBegin(uint32)=0;
|
||||
virtual void OnEnd()=0;
|
||||
virtual void OnError(){}
|
||||
|
@ -120,6 +120,11 @@ public: //Image
|
||||
VkImage CreateImage (VkImageCreateInfo *);
|
||||
void DestoryImage (VkImage);
|
||||
|
||||
private: //texture
|
||||
|
||||
bool CommitTexture2D(Texture2D *,GPUBuffer *buf,uint32_t width,uint32_t height,const uint32_t miplevel,VkPipelineStageFlags stage);
|
||||
bool CommitTexture2DMipmaps(Texture2D *,GPUBuffer *buf,uint32_t width,uint32_t height,uint32_t miplevel,uint32_t);
|
||||
|
||||
public: //Texture
|
||||
|
||||
bool CheckFormatSupport(const VkFormat,const uint32_t bits,ImageTiling tiling=ImageTiling::Optimal)const;
|
||||
@ -131,11 +136,10 @@ public: //Texture
|
||||
|
||||
void Clear(TextureCreateInfo *);
|
||||
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const VkBufferImageCopy *,const int count, const uint32_t miplevel=1);
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const List<ImageRegion> &, const uint32_t miplevel=1);
|
||||
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height, const uint32_t miplevel=1);
|
||||
bool ChangeTexture2D(Texture2D *,void *data, uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,const uint32_t miplevel=1);
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const List<ImageRegion> &, const uint32_t miplevel=1,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const VkBufferImageCopy *,const int count, const uint32_t miplevel=1,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height, const uint32_t miplevel=1,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
bool ChangeTexture2D(Texture2D *,void *data, uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,const uint32_t miplevel=1,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
template<typename T>
|
||||
bool ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const RectScope2<T> &rs)
|
||||
|
@ -9,7 +9,7 @@ struct TextureData
|
||||
VkImage image =VK_NULL_HANDLE;
|
||||
VkImageLayout image_layout=VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
ImageView * image_view =nullptr;
|
||||
uint32 miplevel =0;
|
||||
uint32 miplevel =0;
|
||||
VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL;
|
||||
};//struct TextureData
|
||||
|
||||
@ -18,7 +18,9 @@ struct TextureCreateInfo
|
||||
VkExtent3D extent;
|
||||
VkFormat format;
|
||||
uint32_t usage;
|
||||
uint32_t mipmap; ///<如果值>0表示提供的数据已有mipmaps,如果为0表示自动生成mipmaps
|
||||
uint32_t mipmap_zero_total_bytes;
|
||||
uint32_t origin_mipmaps; //原始mipmaps,0/1
|
||||
uint32_t target_mipmaps; //目标mipmaps,如果和origin_mipmaps不相等,则证明希望自动生成mipmaps
|
||||
VkImageAspectFlags aspect;
|
||||
ImageTiling tiling;
|
||||
|
||||
@ -30,19 +32,16 @@ struct TextureCreateInfo
|
||||
ImageView * image_view; //如果没有imageview,则创建
|
||||
|
||||
void * pixels; //如果没有buffer但有pixels,则根据pixels和以上条件创建buffer
|
||||
VkDeviceSize pixel_bytes;
|
||||
VkDeviceSize total_bytes;
|
||||
GPUBuffer * buffer; //如果pixels也没有,则代表不会立即写入图像数据
|
||||
|
||||
public:
|
||||
|
||||
TextureCreateInfo()
|
||||
{
|
||||
hgl_zero(*this);
|
||||
mipmap=1;
|
||||
hgl_zero(*this);
|
||||
}
|
||||
|
||||
void SetAutoMipmaps(){mipmap=0;}
|
||||
|
||||
TextureCreateInfo(const uint32_t aspect_bit,const VkExtent2D &ext,const VkFormat &fmt,VkImage img):TextureCreateInfo()
|
||||
{
|
||||
aspect=aspect_bit;
|
||||
@ -172,6 +171,11 @@ public:
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void SetAutoMipmaps()
|
||||
{
|
||||
target_mipmaps=hgl::GetMipLevel(extent.width,extent.height,extent.depth);
|
||||
}
|
||||
};//struct TextureCreateInfo
|
||||
|
||||
struct ColorTextureCreateInfo:public TextureCreateInfo
|
||||
|
@ -10,6 +10,46 @@
|
||||
VK_NAMESPACE_BEGIN
|
||||
namespace
|
||||
{
|
||||
struct BufferImageCopy:public VkBufferImageCopy
|
||||
{
|
||||
public:
|
||||
|
||||
BufferImageCopy()
|
||||
{
|
||||
hgl_zero(*this);
|
||||
imageSubresource.layerCount=1;
|
||||
}
|
||||
|
||||
BufferImageCopy(const VkImageAspectFlags aspect_mask):BufferImageCopy()
|
||||
{
|
||||
imageSubresource.aspectMask=aspect_mask;
|
||||
}
|
||||
|
||||
void Set(const VkImageAspectFlags aspect_mask,const uint32_t layer_count)
|
||||
{
|
||||
imageSubresource.aspectMask=aspect_mask;
|
||||
imageSubresource.layerCount=layer_count;
|
||||
}
|
||||
|
||||
void Set(ImageRegion *ir)
|
||||
{
|
||||
imageOffset.x=ir->left;
|
||||
imageOffset.y=ir->top;
|
||||
imageExtent.width=ir->width;
|
||||
imageExtent.height=ir->height;
|
||||
imageExtent.depth=1;
|
||||
}
|
||||
|
||||
void SetRectScope(int32_t left,int32_t top,uint32_t width,uint32_t height)
|
||||
{
|
||||
imageOffset.x=left;
|
||||
imageOffset.y=top;
|
||||
imageExtent.width=width;
|
||||
imageExtent.height=height;
|
||||
imageExtent.depth=1;
|
||||
}
|
||||
};//
|
||||
|
||||
void GenerateMipmaps(GPUCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,const int32_t width,const int32_t height,const uint32_t mipLevels)
|
||||
{
|
||||
//VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels) {
|
||||
@ -126,11 +166,12 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
|
||||
if(tci->extent.width*tci->extent.height*tci->extent.depth<=0)return(nullptr);
|
||||
|
||||
const uint32_t miplevels=((tci->mipmap==0)?GetMipLevel(tci->extent):tci->mipmap);
|
||||
if(tci->target_mipmaps==0)
|
||||
tci->target_mipmaps=(tci->origin_mipmaps>1?tci->origin_mipmaps:1);
|
||||
|
||||
if(!tci->image)
|
||||
{
|
||||
Image2DCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent.width,tci->extent.height,miplevels);
|
||||
Image2DCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent.width,tci->extent.height,tci->target_mipmaps);
|
||||
tci->image=CreateImage(&ici);
|
||||
|
||||
if(!tci->image)
|
||||
@ -143,7 +184,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
}
|
||||
|
||||
if(!tci->image_view)
|
||||
tci->image_view=CreateImageView2D(attr->device,tci->format,tci->extent,miplevels,tci->aspect,tci->image);
|
||||
tci->image_view=CreateImageView2D(attr->device,tci->format,tci->extent,tci->target_mipmaps,tci->aspect,tci->image);
|
||||
|
||||
TextureData *tex_data=new TextureData;
|
||||
|
||||
@ -151,7 +192,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
tex_data->image_layout = tci->image_layout;
|
||||
tex_data->image = tci->image;
|
||||
tex_data->image_view = tci->image_view;
|
||||
tex_data->miplevel = miplevels;
|
||||
tex_data->miplevel = tci->target_mipmaps;
|
||||
tex_data->tiling = VkImageTiling(tci->tiling);
|
||||
|
||||
Texture2D *tex=CreateTexture2D(tex_data);
|
||||
@ -162,12 +203,33 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
if((!tci->buffer)&&tci->pixels&&tci->pixel_bytes>0)
|
||||
tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->pixel_bytes,tci->pixels);
|
||||
if((!tci->buffer)&&tci->pixels&&tci->total_bytes>0)
|
||||
tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->total_bytes,tci->pixels);
|
||||
|
||||
if(tci->buffer)
|
||||
{
|
||||
ChangeTexture2D(tex,tci->buffer,0,0,tci->extent.width,tci->extent.height,tex_data->miplevel);
|
||||
texture_cmd_buf->Begin();
|
||||
if(tci->target_mipmaps==tci->origin_mipmaps)
|
||||
{
|
||||
if(tci->target_mipmaps<=1) //本身不含mipmaps,但也不要mipmaps
|
||||
{
|
||||
CommitTexture2D(tex,tci->buffer,tci->extent.width,tci->extent.height,tex_data->miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
else //本身有mipmaps数据
|
||||
{
|
||||
CommitTexture2DMipmaps(tex,tci->buffer,tci->extent.width,tci->extent.height,tex_data->miplevel,tci->mipmap_zero_total_bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
if(tci->origin_mipmaps<=1) //本身不含mipmaps数据,又想要mipmaps
|
||||
{
|
||||
CommitTexture2D(tex,tci->buffer,tci->extent.width,tci->extent.height,tex_data->miplevel,VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
GenerateMipmaps(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tex->GetWidth(),tex->GetHeight(),tex_data->miplevel);
|
||||
}
|
||||
texture_cmd_buf->End();
|
||||
|
||||
SubmitTexture(*texture_cmd_buf);
|
||||
|
||||
delete tci->buffer;
|
||||
}
|
||||
|
||||
@ -175,7 +237,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
return tex;
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,const uint32_t miplevel)
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,const uint32_t miplevel,VkPipelineStageFlags destinationStage)
|
||||
{
|
||||
if(!tex||!buf)
|
||||
return(false);
|
||||
@ -196,7 +258,6 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
imageMemoryBarrier.subresourceRange = subresourceRange;
|
||||
|
||||
texture_cmd_buf->Begin();
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
@ -215,21 +276,15 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
||||
VkPipelineStageFlags destinationStage;
|
||||
|
||||
if(miplevel>1)
|
||||
if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT)
|
||||
{
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
else
|
||||
else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
|
||||
{
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
}
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
@ -240,16 +295,10 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
|
||||
if(miplevel>1)
|
||||
GenerateMipmaps(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tex->GetWidth(),tex->GetHeight(),miplevel);
|
||||
|
||||
texture_cmd_buf->End();
|
||||
|
||||
SubmitTexture(*texture_cmd_buf);
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRegion> &ir_list,const uint32_t miplevel)
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRegion> &ir_list,const uint32_t miplevel,VkPipelineStageFlags destinationStage)
|
||||
{
|
||||
if(!tex||!buf||ir_list.GetCount()<=0)
|
||||
return(false);
|
||||
@ -259,11 +308,10 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRe
|
||||
|
||||
AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(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++)
|
||||
for(const ImageRegion &sp:ir_list)
|
||||
{
|
||||
tp->bufferOffset = offset;
|
||||
tp->bufferRowLength = 0;
|
||||
@ -272,22 +320,21 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRe
|
||||
tp->imageSubresource.mipLevel = 0;
|
||||
tp->imageSubresource.baseArrayLayer = 0;
|
||||
tp->imageSubresource.layerCount = 1;
|
||||
tp->imageOffset.x = sp->left;
|
||||
tp->imageOffset.y = sp->top;
|
||||
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.width = sp.width;
|
||||
tp->imageExtent.height= sp.height;
|
||||
tp->imageExtent.depth = 1;
|
||||
|
||||
offset+=sp->bytes;
|
||||
++sp;
|
||||
offset+=sp.bytes;
|
||||
++tp;
|
||||
}
|
||||
|
||||
return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count,miplevel);
|
||||
return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count,miplevel,destinationStage);
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height,const uint32_t miplevel)
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height,const uint32_t miplevel,VkPipelineStageFlags destinationStage)
|
||||
{
|
||||
if(!tex||!buf
|
||||
||left<0||left+width>tex->GetWidth()
|
||||
@ -295,25 +342,66 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint
|
||||
||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;
|
||||
BufferImageCopy buffer_image_copy(tex->GetAspect());
|
||||
|
||||
buffer_image_copy.SetRectScope(left,top,width,height);
|
||||
|
||||
return ChangeTexture2D(tex,buf,&buffer_image_copy,1,miplevel);
|
||||
return ChangeTexture2D(tex,buf,&buffer_image_copy,1,miplevel,destinationStage);
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,const uint32_t miplevel)
|
||||
bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t width,uint32_t height,const uint32_t miplevel,VkPipelineStageFlags destinationStage)
|
||||
{
|
||||
if(!tex||!buf)return(false);
|
||||
|
||||
BufferImageCopy buffer_image_copy(tex->GetAspect());
|
||||
|
||||
buffer_image_copy.SetRectScope(0,0,width,height);
|
||||
|
||||
return ChangeTexture2D(tex,buf,&buffer_image_copy,1,miplevel,destinationStage);
|
||||
}
|
||||
|
||||
bool GPUDevice::CommitTexture2DMipmaps(Texture2D *tex,GPUBuffer *buf,uint32_t width,uint32_t height,uint32_t miplevel,uint32_t total_bytes)
|
||||
{
|
||||
if(!tex||!buf
|
||||
||width<=0||height<=0)
|
||||
return(false);
|
||||
|
||||
AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(miplevel);
|
||||
|
||||
VkDeviceSize offset=0;
|
||||
uint32_t level=0;
|
||||
|
||||
buffer_image_copy.zero();
|
||||
|
||||
for(VkBufferImageCopy &bic:buffer_image_copy)
|
||||
{
|
||||
bic.bufferOffset = offset;
|
||||
bic.bufferRowLength = 0;
|
||||
bic.bufferImageHeight = 0;
|
||||
bic.imageSubresource.aspectMask = tex->GetAspect();
|
||||
bic.imageSubresource.mipLevel = level++;
|
||||
bic.imageSubresource.baseArrayLayer = 0;
|
||||
bic.imageSubresource.layerCount = 1;
|
||||
bic.imageOffset.x = 0;
|
||||
bic.imageOffset.y = 0;
|
||||
bic.imageOffset.z = 0;
|
||||
bic.imageExtent.width = width;
|
||||
bic.imageExtent.height= height;
|
||||
bic.imageExtent.depth = 1;
|
||||
|
||||
if(total_bytes<8)
|
||||
offset+=8;
|
||||
else
|
||||
offset+=total_bytes;
|
||||
|
||||
if(width>1){width>>=1;total_bytes>>=1;}
|
||||
if(height>1){height>>=1;total_bytes>>=1;}
|
||||
}
|
||||
|
||||
return ChangeTexture2D(tex,buf,buffer_image_copy,miplevel,miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,const uint32_t miplevel,VkPipelineStageFlags destinationStage)
|
||||
{
|
||||
if(!tex||!data
|
||||
||left<0||left+width>tex->GetWidth()
|
||||
@ -324,7 +412,7 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t
|
||||
|
||||
GPUBuffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data);
|
||||
|
||||
bool result=ChangeTexture2D(tex,buf,left,top,width,height,miplevel);
|
||||
bool result=ChangeTexture2D(tex,buf,left,top,width,height,miplevel,destinationStage);
|
||||
|
||||
delete buf;
|
||||
|
||||
|
@ -117,21 +117,6 @@ namespace
|
||||
|
||||
void *OnBegin(uint32 total_bytes) override
|
||||
{
|
||||
constexpr VkFormat CompressFormatList[]=
|
||||
{
|
||||
FMT_BC1_RGBUN,
|
||||
FMT_BC1_RGBAUN,
|
||||
FMT_BC2UN,
|
||||
FMT_BC3UN,
|
||||
FMT_BC4UN,
|
||||
FMT_BC5UN,
|
||||
FMT_BC6UF,
|
||||
FMT_BC6SF,
|
||||
FMT_BC7UN
|
||||
};
|
||||
|
||||
constexpr size_t CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat);
|
||||
|
||||
SAFE_CLEAR(buf);
|
||||
SAFE_CLEAR(tex);
|
||||
|
||||
@ -161,8 +146,10 @@ namespace
|
||||
buf->Unmap();
|
||||
|
||||
TextureCreateInfo *tci=new TextureCreateInfo(format);
|
||||
|
||||
tci->SetData(buf,file_header.width,file_header.height);
|
||||
|
||||
if(auto_mipmaps)
|
||||
if(auto_mipmaps&&file_header.mipmaps<=1)
|
||||
{
|
||||
if(device->CheckFormatSupport(format,VK_FORMAT_FEATURE_BLIT_DST_BIT))
|
||||
{
|
||||
@ -170,8 +157,13 @@ namespace
|
||||
tci->SetAutoMipmaps();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tci->origin_mipmaps=
|
||||
tci->target_mipmaps=file_header.mipmaps;
|
||||
}
|
||||
|
||||
tci->SetData(buf,file_header.width,file_header.height);
|
||||
tci->mipmap_zero_total_bytes=mipmap_zero_total_bytes;
|
||||
|
||||
tex=device->CreateTexture2D(tci);
|
||||
|
||||
|
@ -7,6 +7,51 @@ namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
uint32 Texture2DLoader::ComputeTotalBytes()
|
||||
{
|
||||
uint32 pixel_bits;
|
||||
uint32 bytes;
|
||||
|
||||
if(file_header.channels==0)
|
||||
{
|
||||
if(compress_format<0||compress_format>=CompressFormatCount)
|
||||
return(0);
|
||||
|
||||
pixel_bits=CompressFormatBits[compress_format];
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel_bits=pixel_format.pixel_bits();
|
||||
}
|
||||
|
||||
bytes=(pixel_bits*file_header.pixel_count())>>3;
|
||||
|
||||
mipmap_zero_total_bytes=bytes;
|
||||
|
||||
if(file_header.mipmaps<=1)
|
||||
return bytes;
|
||||
|
||||
uint32 total=0;
|
||||
|
||||
uint32 w=file_header.width;
|
||||
uint32 h=file_header.height;
|
||||
|
||||
while(w>=1&&h>=1)
|
||||
{
|
||||
if(bytes<8)
|
||||
total+=8;
|
||||
else
|
||||
total+=bytes;
|
||||
|
||||
if(w==1&&h==1)break;
|
||||
|
||||
if(w>1){w>>=1;bytes>>=1;}
|
||||
if(h>1){h>>=1;bytes>>=1;}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
bool Texture2DLoader::Load(io::InputStream *is)
|
||||
{
|
||||
if(!is)return(false);
|
||||
@ -14,31 +59,27 @@ namespace hgl
|
||||
if(is->Read(&file_header,sizeof(Tex2DFileHeader))!=sizeof(Tex2DFileHeader))
|
||||
return(false);
|
||||
|
||||
if(file_header.version!=2)
|
||||
if(file_header.version!=3)
|
||||
return(false);
|
||||
|
||||
total_bytes=0;
|
||||
|
||||
if(file_header.channels==0) //压缩格式
|
||||
{
|
||||
if(is->Read(&compress_format,sizeof(uint16))!=sizeof(uint16))
|
||||
return(false);
|
||||
|
||||
if(is->Read(&total_bytes,sizeof(uint32))!=sizeof(uint32))
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is->Read(&pixel_format,sizeof(TexPixelFormat))!=sizeof(TexPixelFormat))
|
||||
return(false);
|
||||
|
||||
total_bytes=file_header.pixel_count()*pixel_format.pixel_bytes();
|
||||
}
|
||||
|
||||
const uint32 total_bytes=ComputeTotalBytes();
|
||||
|
||||
if(is->Available()<total_bytes)
|
||||
return(false);
|
||||
|
||||
void *ptr=OnBegin(total_bytes);
|
||||
|
||||
if(!ptr)
|
||||
return(false);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user