finished support autoGenerateMipmaps
This commit is contained in:
parent
10c79f30a0
commit
2c5fd977f2
@ -1 +1 @@
|
||||
Subproject commit 59523b92969fc7f015b6d63667c7524d526db1ac
|
||||
Subproject commit 741edebad8108eeee4b256bef0dae3ba0a9fdbcb
|
@ -88,9 +88,11 @@ private:
|
||||
axis_pipeline=CreatePipeline(axis_material,InlinePipeline::Solid3D,Prim::Lines);
|
||||
if(!axis_pipeline)return(false);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
texture.color =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Albedo.Tex2D"),true);
|
||||
texture.normal =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Normal.Tex2D"),true);
|
||||
|
||||
VkSamplerCreateInfo sampler_create_info=
|
||||
{
|
||||
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
@ -103,20 +105,17 @@ private:
|
||||
VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
0.0f,
|
||||
false,
|
||||
0,
|
||||
VK_TRUE,
|
||||
device->GetGPUPhysicalDevice()->GetMaxSamplerAnisotropy(),
|
||||
false,
|
||||
VK_COMPARE_OP_NEVER,
|
||||
0.0f,
|
||||
1.0f,
|
||||
static_cast<float>(texture.color->GetMipLevel()),
|
||||
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
|
||||
false
|
||||
};
|
||||
|
||||
texture.sampler =db->CreateSampler(&sampler_create_info);
|
||||
|
||||
texture.color =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Albedo.Tex2D"));
|
||||
texture.normal =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Normal.Tex2D"));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
|
||||
cili.lunarg.standard_validation = true;
|
||||
cili.khronos.validation = true;
|
||||
cili.RenderDoc.Capture = false;
|
||||
cili.RenderDoc.Capture = true;
|
||||
|
||||
inst=CreateInstance("VulkanTest",nullptr,&cili);
|
||||
|
||||
|
@ -131,11 +131,11 @@ public: //Texture
|
||||
|
||||
void Clear(TextureCreateInfo *);
|
||||
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const VkBufferImageCopy *,const int count);
|
||||
bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const List<ImageRegion> &);
|
||||
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);
|
||||
bool ChangeTexture2D(Texture2D *,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size);
|
||||
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);
|
||||
|
||||
template<typename T>
|
||||
bool ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const RectScope2<T> &rs)
|
||||
@ -160,8 +160,6 @@ public: //Texture
|
||||
size);
|
||||
}
|
||||
|
||||
void GenerateMipmaps(Texture2D *);
|
||||
|
||||
public: //
|
||||
|
||||
Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr);
|
||||
|
@ -15,12 +15,13 @@ protected:
|
||||
VkImageAspectFlags aspect_mask;
|
||||
|
||||
VkExtent3D extent;
|
||||
uint32_t miplevel;
|
||||
|
||||
private:
|
||||
|
||||
friend ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img);
|
||||
friend ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img);
|
||||
|
||||
ImageView(VkDevice dev,VkImageView iv,const VkImageViewType vt,const VkFormat fmt,const VkExtent3D &ext,const VkImageAspectFlags am)
|
||||
ImageView(VkDevice dev,VkImageView iv,const VkImageViewType vt,const VkFormat fmt,const VkExtent3D &ext,const uint32_t &ml,const VkImageAspectFlags am)
|
||||
{
|
||||
device =dev;
|
||||
image_view =iv;
|
||||
@ -28,6 +29,7 @@ private:
|
||||
format =fmt;
|
||||
aspect_mask =am;
|
||||
extent =ext;
|
||||
miplevel =ml;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -41,6 +43,7 @@ public:
|
||||
const VkImageViewType GetViewType ()const{return view_type;}
|
||||
const VkFormat GetFormat ()const{return format;}
|
||||
const VkExtent3D & GetExtent ()const{return extent;}
|
||||
const uint32_t & GetMipLevel ()const{return miplevel;}
|
||||
const VkImageAspectFlags GetAspectFlags ()const{return aspect_mask;}
|
||||
|
||||
const bool hasColor ()const{return aspect_mask&VK_IMAGE_ASPECT_COLOR_BIT;}
|
||||
@ -49,12 +52,12 @@ public:
|
||||
const bool hasDepthStencil ()const{return aspect_mask&(VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT);}
|
||||
};//class ImageView
|
||||
|
||||
ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img);
|
||||
ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img);
|
||||
|
||||
#define CREATE_IMAGE_VIEW(short_name,larget_name) \
|
||||
inline ImageView *CreateImageView##short_name(VkDevice device,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img=VK_NULL_HANDLE) \
|
||||
inline ImageView *CreateImageView##short_name(VkDevice device,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img=VK_NULL_HANDLE) \
|
||||
{ \
|
||||
return CreateImageView(device,VK_IMAGE_VIEW_TYPE_##larget_name,format,ext,aspectMask,img); \
|
||||
return CreateImageView(device,VK_IMAGE_VIEW_TYPE_##larget_name,format,ext,miplevel,aspectMask,img); \
|
||||
}
|
||||
|
||||
CREATE_IMAGE_VIEW(1D,1D);
|
||||
|
@ -92,19 +92,22 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
const uint32_t GetMaxImage1D ()const{return properties.limits.maxImageDimension1D;}
|
||||
const uint32_t GetMaxImage2D ()const{return properties.limits.maxImageDimension2D;}
|
||||
const uint32_t GetMaxImage3D ()const{return properties.limits.maxImageDimension3D;}
|
||||
const uint32_t GetMaxImageCube ()const{return properties.limits.maxImageDimensionCube;}
|
||||
const uint32_t GetMaxImageArrayLayers ()const{return properties.limits.maxImageArrayLayers;}
|
||||
const uint32_t GetMaxUBORange ()const{return properties.limits.maxUniformBufferRange;}
|
||||
const uint32_t GetMaxSSBORange ()const{return properties.limits.maxStorageBufferRange;}
|
||||
const uint32_t GetMaxBoundDescriptorSets()const{return properties.limits.maxBoundDescriptorSets;}
|
||||
const uint32_t GetMaxImage1D ()const{return properties.limits.maxImageDimension1D;}
|
||||
const uint32_t GetMaxImage2D ()const{return properties.limits.maxImageDimension2D;}
|
||||
const uint32_t GetMaxImage3D ()const{return properties.limits.maxImageDimension3D;}
|
||||
const uint32_t GetMaxImageCube ()const{return properties.limits.maxImageDimensionCube;}
|
||||
const uint32_t GetMaxImageArrayLayers ()const{return properties.limits.maxImageArrayLayers;}
|
||||
const uint32_t GetMaxUBORange ()const{return properties.limits.maxUniformBufferRange;}
|
||||
const uint32_t GetMaxSSBORange ()const{return properties.limits.maxStorageBufferRange;}
|
||||
const uint32_t GetMaxBoundDescriptorSets()const{return properties.limits.maxBoundDescriptorSets;}
|
||||
|
||||
const uint32_t GetMaxVertexInputAttributes ()const{return properties.limits.maxVertexInputAttributes;}
|
||||
const uint32_t GetMaxVertexInputBindings ()const{return properties.limits.maxVertexInputBindings;}
|
||||
const uint32_t GetMaxVertexInputAttributes ()const{return properties.limits.maxVertexInputAttributes;}
|
||||
const uint32_t GetMaxVertexInputBindings ()const{return properties.limits.maxVertexInputBindings;}
|
||||
|
||||
const uint32_t GetMaxColorAttachments ()const{return properties.limits.maxColorAttachments;}
|
||||
const uint32_t GetMaxColorAttachments ()const{return properties.limits.maxColorAttachments;}
|
||||
|
||||
const float GetMaxSamplerAnisotropy ()const{return properties.limits.maxSamplerAnisotropy;}
|
||||
const float GetMaxSamplerLodBias ()const{return properties.limits.maxSamplerLodBias;}
|
||||
|
||||
const void GetPointSize(float &granularity,float &min_size,float &max_size)
|
||||
{
|
||||
|
@ -115,7 +115,7 @@ public: //Material
|
||||
|
||||
public: //texture
|
||||
|
||||
Texture2D * LoadTexture2D(const OSString &);
|
||||
Texture2D * LoadTexture2D(const OSString &,bool auto_mipmaps=false);
|
||||
|
||||
public: //Get
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
GPUMemory * GetMemory () {return data?data->memory:nullptr;}
|
||||
ImageView * GetImageView () {return data?data->image_view:nullptr;}
|
||||
|
||||
const uint32 GetMipLevels ()const {return data?data->mip_levels:0;}
|
||||
const uint32 GetMipLevel ()const {return data?data->miplevel:0;}
|
||||
const bool IsOptimal ()const {return data?data->tiling==VK_IMAGE_TILING_OPTIMAL:false;}
|
||||
const bool IsLinear ()const {return data?data->tiling==VK_IMAGE_TILING_LINEAR:false;}
|
||||
|
||||
|
@ -9,7 +9,7 @@ struct TextureData
|
||||
VkImage image =VK_NULL_HANDLE;
|
||||
VkImageLayout image_layout=VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
ImageView * image_view =nullptr;
|
||||
uint32 mip_levels =0;
|
||||
uint32 miplevel =0;
|
||||
VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL;
|
||||
};//struct TextureData
|
||||
|
||||
|
@ -78,21 +78,21 @@ namespace
|
||||
return(VK_NULL_HANDLE);
|
||||
}
|
||||
|
||||
ImageView *Create2DImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,VkImage img=VK_NULL_HANDLE)
|
||||
ImageView *Create2DImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,const uint32_t miplevel,VkImage img=VK_NULL_HANDLE)
|
||||
{
|
||||
VkExtent3D extent;
|
||||
|
||||
copy(extent,ext);
|
||||
|
||||
return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,VK_IMAGE_ASPECT_COLOR_BIT,img);
|
||||
return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,miplevel,VK_IMAGE_ASPECT_COLOR_BIT,img);
|
||||
}
|
||||
|
||||
ImageView *CreateDepthImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,VkImage img=VK_NULL_HANDLE)
|
||||
ImageView *CreateDepthImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,const uint32_t miplevel,VkImage img=VK_NULL_HANDLE)
|
||||
{
|
||||
VkExtent3D extent;
|
||||
|
||||
copy(extent,ext,1);
|
||||
return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,VK_IMAGE_ASPECT_DEPTH_BIT,img);
|
||||
return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,miplevel,VK_IMAGE_ASPECT_DEPTH_BIT,img);
|
||||
}
|
||||
|
||||
VkDescriptorPool CreateDescriptorPool(VkDevice device,uint32_t sets_count)
|
||||
|
@ -10,10 +10,100 @@
|
||||
VK_NAMESPACE_BEGIN
|
||||
namespace
|
||||
{
|
||||
const uint32_t GetMipLevels(const uint32_t size)
|
||||
const uint32_t GetMipLevel(const uint32_t size)
|
||||
{
|
||||
return static_cast<uint32_t>(std::floor(std::log2(size)))+1;
|
||||
}
|
||||
|
||||
const uint32_t GetMipLevel(const VkExtent2D &ext)
|
||||
{
|
||||
return GetMipLevel(std::max(ext.width,ext.height));
|
||||
}
|
||||
|
||||
const uint32_t GetMipLevel(const VkExtent3D &ext)
|
||||
{
|
||||
return GetMipLevel(std::max(std::max(ext.width,ext.height),ext.depth));
|
||||
}
|
||||
|
||||
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) {
|
||||
// Check if image format supports linear blitting
|
||||
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.image = image;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.subresourceRange.aspectMask = aspect_mask;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
|
||||
int32_t mipWidth = width;
|
||||
int32_t mipHeight = height;
|
||||
|
||||
for (uint32_t i = 1; i < mipLevels; i++)
|
||||
{
|
||||
barrier.subresourceRange.baseMipLevel = i - 1;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
|
||||
VkImageBlit blit{};
|
||||
blit.srcOffsets[0] = {0, 0, 0};
|
||||
blit.srcOffsets[1] = {mipWidth, mipHeight, 1};
|
||||
blit.srcSubresource.aspectMask = aspect_mask;
|
||||
blit.srcSubresource.mipLevel = i - 1;
|
||||
blit.srcSubresource.baseArrayLayer = 0;
|
||||
blit.srcSubresource.layerCount = 1;
|
||||
blit.dstOffsets[0] = {0, 0, 0};
|
||||
blit.dstOffsets[1] = { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1 };
|
||||
blit.dstSubresource.aspectMask = aspect_mask;
|
||||
blit.dstSubresource.mipLevel = i;
|
||||
blit.dstSubresource.baseArrayLayer = 0;
|
||||
blit.dstSubresource.layerCount = 1;
|
||||
|
||||
texture_cmd_buf->BlitImage(
|
||||
image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &blit,
|
||||
VK_FILTER_LINEAR);
|
||||
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
|
||||
if (mipWidth > 1) mipWidth /= 2;
|
||||
if (mipHeight > 1) mipHeight /= 2;
|
||||
}
|
||||
|
||||
barrier.subresourceRange.baseMipLevel = mipLevels - 1;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
}
|
||||
}//namespace
|
||||
|
||||
bool GPUDevice::CheckFormatSupport(const VkFormat format,const uint32_t bits,ImageTiling tiling) const
|
||||
@ -51,9 +141,11 @@ 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->image)
|
||||
{
|
||||
Image2DCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent.width,tci->extent.height,tci->mipmap);
|
||||
Image2DCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent.width,tci->extent.height,miplevels);
|
||||
tci->image=CreateImage(&ici);
|
||||
|
||||
if(!tci->image)
|
||||
@ -66,7 +158,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
}
|
||||
|
||||
if(!tci->image_view)
|
||||
tci->image_view=CreateImageView2D(attr->device,tci->format,tci->extent,tci->aspect,tci->image);
|
||||
tci->image_view=CreateImageView2D(attr->device,tci->format,tci->extent,miplevels,tci->aspect,tci->image);
|
||||
|
||||
TextureData *tex_data=new TextureData;
|
||||
|
||||
@ -74,8 +166,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->mip_levels = tci->mipmap;
|
||||
tex_data->miplevel = miplevels;
|
||||
tex_data->tiling = VkImageTiling(tci->tiling);
|
||||
|
||||
Texture2D *tex=CreateTexture2D(tex_data);
|
||||
@ -91,7 +182,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
|
||||
if(tci->buffer)
|
||||
{
|
||||
ChangeTexture2D(tex,tci->buffer,0,0,tci->extent.width,tci->extent.height);
|
||||
ChangeTexture2D(tex,tci->buffer,0,0,tci->extent.width,tci->extent.height,tex_data->miplevel);
|
||||
delete tci->buffer;
|
||||
}
|
||||
|
||||
@ -99,7 +190,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
|
||||
return tex;
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count)
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,const uint32_t miplevel)
|
||||
{
|
||||
if(!tex||!buf)
|
||||
return(false);
|
||||
@ -107,18 +198,17 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
||||
VkImageSubresourceRange subresourceRange;
|
||||
subresourceRange.aspectMask = tex->GetAspect();
|
||||
subresourceRange.baseMipLevel = 0;
|
||||
subresourceRange.levelCount = 1;
|
||||
subresourceRange.levelCount = miplevel;
|
||||
subresourceRange.baseArrayLayer = 0;
|
||||
subresourceRange.layerCount = 1;
|
||||
|
||||
ImageMemoryBarrier imageMemoryBarrier;
|
||||
ImageMemoryBarrier imageMemoryBarrier(tex->GetImage());
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
imageMemoryBarrier.image = tex->GetImage();
|
||||
imageMemoryBarrier.subresourceRange = subresourceRange;
|
||||
|
||||
texture_cmd_buf->Begin();
|
||||
@ -136,27 +226,45 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImag
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
count,
|
||||
buffer_image_copy);
|
||||
|
||||
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
VkPipelineStageFlags destinationStage;
|
||||
|
||||
if(miplevel>1)
|
||||
{
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
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(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
destinationStage,
|
||||
0,
|
||||
0, nullptr,
|
||||
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)
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRegion> &ir_list,const uint32_t miplevel)
|
||||
{
|
||||
if(!tex||!buf||ir_list.GetCount()<=0)
|
||||
return(false);
|
||||
@ -191,10 +299,10 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<ImageRe
|
||||
++tp;
|
||||
}
|
||||
|
||||
return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count);
|
||||
return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count,miplevel);
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height)
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height,const uint32_t miplevel)
|
||||
{
|
||||
if(!tex||!buf
|
||||
||left<0||left+width>tex->GetWidth()
|
||||
@ -217,10 +325,10 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint
|
||||
buffer_image_copy.imageExtent.height= height;
|
||||
buffer_image_copy.imageExtent.depth = 1;
|
||||
|
||||
return ChangeTexture2D(tex,buf,&buffer_image_copy,1);
|
||||
return ChangeTexture2D(tex,buf,&buffer_image_copy,1,miplevel);
|
||||
}
|
||||
|
||||
bool GPUDevice::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size)
|
||||
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)
|
||||
{
|
||||
if(!tex||!data
|
||||
||left<0||left+width>tex->GetWidth()
|
||||
@ -231,100 +339,13 @@ 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);
|
||||
bool result=ChangeTexture2D(tex,buf,left,top,width,height,miplevel);
|
||||
|
||||
delete buf;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
void GPUDevice::GenerateMipmaps(Texture2D *tex)
|
||||
{
|
||||
//VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels) {
|
||||
// Check if image format supports linear blitting
|
||||
|
||||
const uint32_t mipLevels=GetMipLevels(std::max(tex->GetWidth(),tex->GetHeight()));
|
||||
|
||||
VkImage image=tex->GetImage();
|
||||
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.image = image;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.subresourceRange.aspectMask = tex->GetAspect();
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
|
||||
int32_t mipWidth = tex->GetWidth();
|
||||
int32_t mipHeight = tex->GetHeight();
|
||||
|
||||
texture_cmd_buf->Begin();
|
||||
|
||||
for (uint32_t i = 1; i < mipLevels; i++) {
|
||||
barrier.subresourceRange.baseMipLevel = i - 1;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
|
||||
VkImageBlit blit{};
|
||||
blit.srcOffsets[0] = {0, 0, 0};
|
||||
blit.srcOffsets[1] = {mipWidth, mipHeight, 1};
|
||||
blit.srcSubresource.aspectMask = tex->GetAspect();
|
||||
blit.srcSubresource.mipLevel = i - 1;
|
||||
blit.srcSubresource.baseArrayLayer = 0;
|
||||
blit.srcSubresource.layerCount = 1;
|
||||
blit.dstOffsets[0] = {0, 0, 0};
|
||||
blit.dstOffsets[1] = { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1 };
|
||||
blit.dstSubresource.aspectMask = tex->GetAspect();
|
||||
blit.dstSubresource.mipLevel = i;
|
||||
blit.dstSubresource.baseArrayLayer = 0;
|
||||
blit.dstSubresource.layerCount = 1;
|
||||
|
||||
texture_cmd_buf->BlitImage(
|
||||
image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &blit,
|
||||
VK_FILTER_LINEAR);
|
||||
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
|
||||
if (mipWidth > 1) mipWidth /= 2;
|
||||
if (mipHeight > 1) mipHeight /= 2;
|
||||
}
|
||||
|
||||
barrier.subresourceRange.baseMipLevel = mipLevels - 1;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
texture_cmd_buf->PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
|
||||
texture_cmd_buf->End();
|
||||
}
|
||||
|
||||
bool GPUDevice::SubmitTexture(const VkCommandBuffer *cmd_bufs,const uint32_t count)
|
||||
{
|
||||
if(!cmd_bufs||count<=0)
|
||||
|
@ -6,7 +6,7 @@ ImageView::~ImageView()
|
||||
vkDestroyImageView(device,image_view,nullptr);
|
||||
}
|
||||
|
||||
ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img)
|
||||
ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img)
|
||||
{
|
||||
ImageViewCreateInfo iv_createinfo;
|
||||
|
||||
@ -15,7 +15,7 @@ ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,
|
||||
iv_createinfo.viewType =type;
|
||||
iv_createinfo.subresourceRange.aspectMask =aspectMask;
|
||||
iv_createinfo.subresourceRange.baseMipLevel =0;
|
||||
iv_createinfo.subresourceRange.levelCount =ext.depth;
|
||||
iv_createinfo.subresourceRange.levelCount =miplevel;
|
||||
iv_createinfo.subresourceRange.baseArrayLayer =0;
|
||||
iv_createinfo.subresourceRange.layerCount =ext.depth;
|
||||
|
||||
@ -42,6 +42,6 @@ ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,
|
||||
if(vkCreateImageView(device,&iv_createinfo,nullptr,&img_view)!=VK_SUCCESS)
|
||||
return(nullptr);
|
||||
|
||||
return(new ImageView(device,img_view,type,format,ext,aspectMask));
|
||||
return(new ImageView(device,img_view,type,format,ext,miplevel,aspectMask));
|
||||
}
|
||||
VK_NAMESPACE_END
|
||||
|
@ -170,16 +170,16 @@ Sampler *RenderResource::CreateSampler(VkSamplerCreateInfo *sci)
|
||||
return s;
|
||||
}
|
||||
|
||||
Texture2D *CreateTextureFromFile(GPUDevice *device,const OSString &filename);
|
||||
Texture2D *CreateTextureFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps);
|
||||
|
||||
Texture2D *RenderResource::LoadTexture2D(const OSString &filename)
|
||||
Texture2D *RenderResource::LoadTexture2D(const OSString &filename,bool auto_mipmaps)
|
||||
{
|
||||
Texture2D *tex;
|
||||
|
||||
if(texture_by_name.Get(filename,(Texture *&)tex))
|
||||
return tex;
|
||||
|
||||
tex=CreateTextureFromFile(device,filename);
|
||||
tex=CreateTextureFromFile(device,filename,auto_mipmaps);
|
||||
|
||||
if(tex)
|
||||
{
|
||||
|
@ -95,15 +95,18 @@ namespace
|
||||
VkFormat format;
|
||||
GPUBuffer *buf;
|
||||
|
||||
bool auto_mipmaps;
|
||||
|
||||
Texture2D *tex;
|
||||
|
||||
public:
|
||||
|
||||
VkTexture2DLoader(GPUDevice *dev):device(dev)
|
||||
VkTexture2DLoader(GPUDevice *dev,const bool am):device(dev)
|
||||
{
|
||||
buf=nullptr;
|
||||
format=VK_FORMAT_UNDEFINED;
|
||||
tex=nullptr;
|
||||
auto_mipmaps=am;
|
||||
}
|
||||
|
||||
virtual ~VkTexture2DLoader()
|
||||
@ -159,6 +162,15 @@ namespace
|
||||
|
||||
TextureCreateInfo *tci=new TextureCreateInfo(format);
|
||||
|
||||
if(auto_mipmaps)
|
||||
{
|
||||
if(device->CheckFormatSupport(format,VK_FORMAT_FEATURE_BLIT_DST_BIT))
|
||||
{
|
||||
tci->usage|=VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
tci->SetAutoMipmaps();
|
||||
}
|
||||
}
|
||||
|
||||
tci->SetData(buf,file_header.width,file_header.height);
|
||||
|
||||
tex=device->CreateTexture2D(tci);
|
||||
@ -176,9 +188,9 @@ namespace
|
||||
};//class VkTexture2DLoader
|
||||
}//namespace
|
||||
|
||||
Texture2D *CreateTextureFromFile(GPUDevice *device,const OSString &filename)
|
||||
Texture2D *CreateTextureFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps)
|
||||
{
|
||||
VkTexture2DLoader loader(device);
|
||||
VkTexture2DLoader loader(device,auto_mipmaps);
|
||||
|
||||
if(!loader.Load(filename))
|
||||
return(nullptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user