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;
|
MaterialInstance * material_instance =nullptr;
|
||||||
Renderable * render_obj =nullptr;
|
Renderable * render_obj =nullptr;
|
||||||
RenderableInstance *render_instance =nullptr;
|
RenderableInstance *render_instance =nullptr;
|
||||||
GPUBuffer * ubo_world_matrix =nullptr;
|
GPUBuffer * ubo_world_matrix =nullptr;
|
||||||
|
|
||||||
Pipeline * pipeline =nullptr;
|
Pipeline * pipeline =nullptr;
|
||||||
|
|
||||||
|
@ -9,10 +9,6 @@
|
|||||||
using namespace hgl;
|
using namespace hgl;
|
||||||
using namespace hgl::graph;
|
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 SCREEN_SIZE=512;
|
||||||
|
|
||||||
constexpr uint32_t VERTEX_COUNT=4;
|
constexpr uint32_t VERTEX_COUNT=4;
|
||||||
@ -79,7 +75,6 @@ public:
|
|||||||
SAFE_CLEAR(vertex_buffer);
|
SAFE_CLEAR(vertex_buffer);
|
||||||
SAFE_CLEAR(sampler_nearest);
|
SAFE_CLEAR(sampler_nearest);
|
||||||
SAFE_CLEAR(sampler_linear);
|
SAFE_CLEAR(sampler_linear);
|
||||||
SAFE_CLEAR(texture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -135,7 +130,7 @@ private:
|
|||||||
|
|
||||||
bool InitTexture()
|
bool InitTexture()
|
||||||
{
|
{
|
||||||
texture=CreateTextureFromFile(device,OS_TEXT("res/image/heightmap.Tex2D"));
|
texture=db->LoadTexture2D(OS_TEXT("res/image/heightmap.Tex2D"));
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ private:
|
|||||||
MaterialInstance * material_instance =nullptr;
|
MaterialInstance * material_instance =nullptr;
|
||||||
Renderable * render_obj =nullptr;
|
Renderable * render_obj =nullptr;
|
||||||
RenderableInstance *render_instance =nullptr;
|
RenderableInstance *render_instance =nullptr;
|
||||||
GPUBuffer * ubo_world_matrix =nullptr;
|
GPUBuffer * ubo_world_matrix =nullptr;
|
||||||
|
|
||||||
Pipeline * pipeline =nullptr;
|
Pipeline * pipeline =nullptr;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ private:
|
|||||||
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Rectangles);
|
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Rectangles);
|
||||||
if(!pipeline)return(false);
|
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);
|
if(!texture)return(false);
|
||||||
|
|
||||||
sampler=db->CreateSampler();
|
sampler=db->CreateSampler();
|
||||||
|
@ -4,10 +4,28 @@
|
|||||||
#include<hgl/io/InputStream.h>
|
#include<hgl/io/InputStream.h>
|
||||||
#include<hgl/type/String.h>
|
#include<hgl/type/String.h>
|
||||||
#include<hgl/graph/Bitmap.h>
|
#include<hgl/graph/Bitmap.h>
|
||||||
|
#include<hgl/graph/VKFormat.h>
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
namespace graph
|
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)
|
#pragma pack(push,1)
|
||||||
struct Tex2DFileHeader
|
struct Tex2DFileHeader
|
||||||
{
|
{
|
||||||
@ -31,7 +49,8 @@ namespace hgl
|
|||||||
|
|
||||||
public:
|
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
|
};//struct TexPixelFormat
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
@ -50,10 +69,12 @@ namespace hgl
|
|||||||
uint16 compress_format;
|
uint16 compress_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 total_bytes;
|
protected:
|
||||||
|
|
||||||
protected:
|
uint32 mipmap_zero_total_bytes;
|
||||||
|
|
||||||
|
uint32 ComputeTotalBytes();
|
||||||
|
|
||||||
virtual void *OnBegin(uint32)=0;
|
virtual void *OnBegin(uint32)=0;
|
||||||
virtual void OnEnd()=0;
|
virtual void OnEnd()=0;
|
||||||
virtual void OnError(){}
|
virtual void OnError(){}
|
||||||
|
@ -120,6 +120,11 @@ public: //Image
|
|||||||
VkImage CreateImage (VkImageCreateInfo *);
|
VkImage CreateImage (VkImageCreateInfo *);
|
||||||
void DestoryImage (VkImage);
|
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
|
public: //Texture
|
||||||
|
|
||||||
bool CheckFormatSupport(const VkFormat,const uint32_t bits,ImageTiling tiling=ImageTiling::Optimal)const;
|
bool CheckFormatSupport(const VkFormat,const uint32_t bits,ImageTiling tiling=ImageTiling::Optimal)const;
|
||||||
@ -131,11 +136,10 @@ public: //Texture
|
|||||||
|
|
||||||
void Clear(TextureCreateInfo *);
|
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,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const List<ImageRegion> &, const uint32_t miplevel=1);
|
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 *,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,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);
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const RectScope2<T> &rs)
|
bool ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const RectScope2<T> &rs)
|
||||||
|
@ -9,7 +9,7 @@ struct TextureData
|
|||||||
VkImage image =VK_NULL_HANDLE;
|
VkImage image =VK_NULL_HANDLE;
|
||||||
VkImageLayout image_layout=VK_IMAGE_LAYOUT_UNDEFINED;
|
VkImageLayout image_layout=VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
ImageView * image_view =nullptr;
|
ImageView * image_view =nullptr;
|
||||||
uint32 miplevel =0;
|
uint32 miplevel =0;
|
||||||
VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL;
|
VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL;
|
||||||
};//struct TextureData
|
};//struct TextureData
|
||||||
|
|
||||||
@ -18,7 +18,9 @@ struct TextureCreateInfo
|
|||||||
VkExtent3D extent;
|
VkExtent3D extent;
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
uint32_t usage;
|
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;
|
VkImageAspectFlags aspect;
|
||||||
ImageTiling tiling;
|
ImageTiling tiling;
|
||||||
|
|
||||||
@ -30,19 +32,16 @@ struct TextureCreateInfo
|
|||||||
ImageView * image_view; //如果没有imageview,则创建
|
ImageView * image_view; //如果没有imageview,则创建
|
||||||
|
|
||||||
void * pixels; //如果没有buffer但有pixels,则根据pixels和以上条件创建buffer
|
void * pixels; //如果没有buffer但有pixels,则根据pixels和以上条件创建buffer
|
||||||
VkDeviceSize pixel_bytes;
|
VkDeviceSize total_bytes;
|
||||||
GPUBuffer * buffer; //如果pixels也没有,则代表不会立即写入图像数据
|
GPUBuffer * buffer; //如果pixels也没有,则代表不会立即写入图像数据
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextureCreateInfo()
|
TextureCreateInfo()
|
||||||
{
|
{
|
||||||
hgl_zero(*this);
|
hgl_zero(*this);
|
||||||
mipmap=1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAutoMipmaps(){mipmap=0;}
|
|
||||||
|
|
||||||
TextureCreateInfo(const uint32_t aspect_bit,const VkExtent2D &ext,const VkFormat &fmt,VkImage img):TextureCreateInfo()
|
TextureCreateInfo(const uint32_t aspect_bit,const VkExtent2D &ext,const VkFormat &fmt,VkImage img):TextureCreateInfo()
|
||||||
{
|
{
|
||||||
aspect=aspect_bit;
|
aspect=aspect_bit;
|
||||||
@ -172,6 +171,11 @@ public:
|
|||||||
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAutoMipmaps()
|
||||||
|
{
|
||||||
|
target_mipmaps=hgl::GetMipLevel(extent.width,extent.height,extent.depth);
|
||||||
|
}
|
||||||
};//struct TextureCreateInfo
|
};//struct TextureCreateInfo
|
||||||
|
|
||||||
struct ColorTextureCreateInfo:public TextureCreateInfo
|
struct ColorTextureCreateInfo:public TextureCreateInfo
|
||||||
|
@ -10,6 +10,46 @@
|
|||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
namespace
|
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)
|
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) {
|
//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);
|
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)
|
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);
|
tci->image=CreateImage(&ici);
|
||||||
|
|
||||||
if(!tci->image)
|
if(!tci->image)
|
||||||
@ -143,7 +184,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!tci->image_view)
|
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;
|
TextureData *tex_data=new TextureData;
|
||||||
|
|
||||||
@ -151,7 +192,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
|||||||
tex_data->image_layout = tci->image_layout;
|
tex_data->image_layout = tci->image_layout;
|
||||||
tex_data->image = tci->image;
|
tex_data->image = tci->image;
|
||||||
tex_data->image_view = tci->image_view;
|
tex_data->image_view = tci->image_view;
|
||||||
tex_data->miplevel = miplevels;
|
tex_data->miplevel = tci->target_mipmaps;
|
||||||
tex_data->tiling = VkImageTiling(tci->tiling);
|
tex_data->tiling = VkImageTiling(tci->tiling);
|
||||||
|
|
||||||
Texture2D *tex=CreateTexture2D(tex_data);
|
Texture2D *tex=CreateTexture2D(tex_data);
|
||||||
@ -162,12 +203,33 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
|||||||
return(nullptr);
|
return(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!tci->buffer)&&tci->pixels&&tci->pixel_bytes>0)
|
if((!tci->buffer)&&tci->pixels&&tci->total_bytes>0)
|
||||||
tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->pixel_bytes,tci->pixels);
|
tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->total_bytes,tci->pixels);
|
||||||
|
|
||||||
if(tci->buffer)
|
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;
|
delete tci->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +237,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
|||||||
return tex;
|
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)
|
if(!tex||!buf)
|
||||||
return(false);
|
return(false);
|
||||||
@ -196,7 +258,6 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
|||||||
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
imageMemoryBarrier.subresourceRange = subresourceRange;
|
imageMemoryBarrier.subresourceRange = subresourceRange;
|
||||||
|
|
||||||
texture_cmd_buf->Begin();
|
|
||||||
texture_cmd_buf->PipelineBarrier(
|
texture_cmd_buf->PipelineBarrier(
|
||||||
VK_PIPELINE_STAGE_HOST_BIT,
|
VK_PIPELINE_STAGE_HOST_BIT,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_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.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
|
|
||||||
VkPipelineStageFlags destinationStage;
|
if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT)
|
||||||
|
|
||||||
if(miplevel>1)
|
|
||||||
{
|
{
|
||||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
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.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_cmd_buf->PipelineBarrier(
|
texture_cmd_buf->PipelineBarrier(
|
||||||
@ -240,16 +295,10 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
|||||||
0, nullptr,
|
0, nullptr,
|
||||||
1, &imageMemoryBarrier);
|
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);
|
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)
|
if(!tex||!buf||ir_list.GetCount()<=0)
|
||||||
return(false);
|
return(false);
|
||||||
@ -259,11 +308,10 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRe
|
|||||||
|
|
||||||
AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(ir_count);
|
AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(ir_count);
|
||||||
VkBufferImageCopy *tp=buffer_image_copy;
|
VkBufferImageCopy *tp=buffer_image_copy;
|
||||||
const ImageRegion *sp=ir_list.GetData();
|
|
||||||
|
|
||||||
VkDeviceSize offset=0;
|
VkDeviceSize offset=0;
|
||||||
|
|
||||||
for(int i=0;i<ir_list.GetCount();i++)
|
for(const ImageRegion &sp:ir_list)
|
||||||
{
|
{
|
||||||
tp->bufferOffset = offset;
|
tp->bufferOffset = offset;
|
||||||
tp->bufferRowLength = 0;
|
tp->bufferRowLength = 0;
|
||||||
@ -272,22 +320,21 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRe
|
|||||||
tp->imageSubresource.mipLevel = 0;
|
tp->imageSubresource.mipLevel = 0;
|
||||||
tp->imageSubresource.baseArrayLayer = 0;
|
tp->imageSubresource.baseArrayLayer = 0;
|
||||||
tp->imageSubresource.layerCount = 1;
|
tp->imageSubresource.layerCount = 1;
|
||||||
tp->imageOffset.x = sp->left;
|
tp->imageOffset.x = sp.left;
|
||||||
tp->imageOffset.y = sp->top;
|
tp->imageOffset.y = sp.top;
|
||||||
tp->imageOffset.z = 0;
|
tp->imageOffset.z = 0;
|
||||||
tp->imageExtent.width = sp->width;
|
tp->imageExtent.width = sp.width;
|
||||||
tp->imageExtent.height= sp->height;
|
tp->imageExtent.height= sp.height;
|
||||||
tp->imageExtent.depth = 1;
|
tp->imageExtent.depth = 1;
|
||||||
|
|
||||||
offset+=sp->bytes;
|
offset+=sp.bytes;
|
||||||
++sp;
|
|
||||||
++tp;
|
++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
|
if(!tex||!buf
|
||||||
||left<0||left+width>tex->GetWidth()
|
||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)
|
||width<=0||height<=0)
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
VkBufferImageCopy buffer_image_copy;
|
BufferImageCopy buffer_image_copy(tex->GetAspect());
|
||||||
buffer_image_copy.bufferOffset = 0;
|
|
||||||
buffer_image_copy.bufferRowLength = 0;
|
buffer_image_copy.SetRectScope(left,top,width,height);
|
||||||
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,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
|
if(!tex||!data
|
||||||
||left<0||left+width>tex->GetWidth()
|
||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);
|
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;
|
delete buf;
|
||||||
|
|
||||||
|
@ -117,21 +117,6 @@ namespace
|
|||||||
|
|
||||||
void *OnBegin(uint32 total_bytes) override
|
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(buf);
|
||||||
SAFE_CLEAR(tex);
|
SAFE_CLEAR(tex);
|
||||||
|
|
||||||
@ -161,8 +146,10 @@ namespace
|
|||||||
buf->Unmap();
|
buf->Unmap();
|
||||||
|
|
||||||
TextureCreateInfo *tci=new TextureCreateInfo(format);
|
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))
|
if(device->CheckFormatSupport(format,VK_FORMAT_FEATURE_BLIT_DST_BIT))
|
||||||
{
|
{
|
||||||
@ -170,8 +157,13 @@ namespace
|
|||||||
tci->SetAutoMipmaps();
|
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);
|
tex=device->CreateTexture2D(tci);
|
||||||
|
|
||||||
|
@ -7,6 +7,51 @@ namespace hgl
|
|||||||
{
|
{
|
||||||
namespace graph
|
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)
|
bool Texture2DLoader::Load(io::InputStream *is)
|
||||||
{
|
{
|
||||||
if(!is)return(false);
|
if(!is)return(false);
|
||||||
@ -14,31 +59,27 @@ namespace hgl
|
|||||||
if(is->Read(&file_header,sizeof(Tex2DFileHeader))!=sizeof(Tex2DFileHeader))
|
if(is->Read(&file_header,sizeof(Tex2DFileHeader))!=sizeof(Tex2DFileHeader))
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
if(file_header.version!=2)
|
if(file_header.version!=3)
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
total_bytes=0;
|
|
||||||
|
|
||||||
if(file_header.channels==0) //压缩格式
|
if(file_header.channels==0) //压缩格式
|
||||||
{
|
{
|
||||||
if(is->Read(&compress_format,sizeof(uint16))!=sizeof(uint16))
|
if(is->Read(&compress_format,sizeof(uint16))!=sizeof(uint16))
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
if(is->Read(&total_bytes,sizeof(uint32))!=sizeof(uint32))
|
|
||||||
return(false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(is->Read(&pixel_format,sizeof(TexPixelFormat))!=sizeof(TexPixelFormat))
|
if(is->Read(&pixel_format,sizeof(TexPixelFormat))!=sizeof(TexPixelFormat))
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
total_bytes=file_header.pixel_count()*pixel_format.pixel_bytes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32 total_bytes=ComputeTotalBytes();
|
||||||
|
|
||||||
if(is->Available()<total_bytes)
|
if(is->Available()<total_bytes)
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
void *ptr=OnBegin(total_bytes);
|
void *ptr=OnBegin(total_bytes);
|
||||||
|
|
||||||
if(!ptr)
|
if(!ptr)
|
||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user