added Cubemap support,but only test non-mipmaps texture.

This commit is contained in:
2022-01-07 16:55:39 +08:00
parent f35d8ab9af
commit 1d499ffd5b
13 changed files with 436 additions and 119 deletions

View File

@@ -22,6 +22,12 @@ public:
SetRectScope(0,0,tex->GetWidth(),tex->GetHeight());
}
BufferImageCopy(const TextureCube *tex):BufferImageCopy()
{
imageSubresource.aspectMask=tex->GetAspect();
SetRectScope(0,0,tex->GetWidth(),tex->GetHeight());
}
void Set(const VkImageAspectFlags aspect_mask,const uint32_t layer_count)
{
imageSubresource.aspectMask=aspect_mask;

View File

@@ -17,7 +17,6 @@ void GenerateMipmaps2D(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAs
int32_t width =extent.width;
int32_t height =extent.height;
int32_t depth =extent.depth;
for (uint32_t i = 1; i < mipLevels; i++)
{
@@ -32,14 +31,13 @@ void GenerateMipmaps2D(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAs
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
subresourceRange);
blit.srcOffsets[1] = {width,height,depth};
blit.srcOffsets[1] = {width,height,1};
blit.srcSubresource.mipLevel = i - 1;
if(width >1)width >>=1;
if(height>1)height>>=1;
if(depth >1)depth >>=1;
blit.dstOffsets[1] = {width,height,depth};
blit.dstOffsets[1] = {width,height,1};
blit.dstSubresource.mipLevel = i;
texture_cmd_buf->BlitImage(

View File

@@ -0,0 +1,70 @@
#include<hgl/graph/VKCommandBuffer.h>
VK_NAMESPACE_BEGIN
void GenerateMipmapsCube(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels)
{
ImageSubresourceRange subresourceRange(aspect_mask);
VkImageBlit blit;
blit.srcOffsets[0] = {0, 0, 0};
blit.srcSubresource.aspectMask = aspect_mask;
blit.srcSubresource.baseArrayLayer = 0;
blit.srcSubresource.layerCount = 6;
blit.dstOffsets[0] = {0, 0, 0};
blit.dstSubresource=blit.srcSubresource;
int32_t width =extent.width;
int32_t height =extent.height;
for (uint32_t i = 1; i < mipLevels; i++)
{
subresourceRange.baseMipLevel = i - 1;
texture_cmd_buf->ImageMemoryBarrier(image,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
subresourceRange);
blit.srcOffsets[1] = {width,height,1};
blit.srcSubresource.mipLevel = i - 1;
if(width >1)width >>=1;
if(height>1)height>>=1;
blit.dstOffsets[1] = {width,height,1};
blit.dstSubresource.mipLevel = i;
texture_cmd_buf->BlitImage(
image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &blit,
VK_FILTER_LINEAR);
texture_cmd_buf->ImageMemoryBarrier(image,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
subresourceRange);
}
subresourceRange.baseMipLevel = mipLevels - 1;
texture_cmd_buf->ImageMemoryBarrier(image,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
subresourceRange);
}
VK_NAMESPACE_END

View File

@@ -74,7 +74,7 @@ Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci)
if(tci->origin_mipmaps<=1) //本身不含mipmaps数据,又想要mipmaps
{
CommitTexture2D(tex,tci->buffer,VK_PIPELINE_STAGE_TRANSFER_BIT);
GenerateMipmaps2D(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel);
GenerateMipmaps2D(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel);
}
texture_cmd_buf->End();

View File

@@ -3,7 +3,7 @@
#include<hgl/graph/VKCommandBuffer.h>
#include"BufferImageCopy2D.h"
VK_NAMESPACE_BEGIN
void GenerateMipmaps2D(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels);
void GenerateMipmapsCube(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels);
TextureCube *GPUDevice::CreateTextureCube(TextureData *tex_data)
{
@@ -59,18 +59,18 @@ TextureCube *GPUDevice::CreateTextureCube(TextureCreateInfo *tci)
{
if(tci->target_mipmaps<=1) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mipmaps<70><73><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2>Ҫmipmaps
{
CommitTexture2D(tex,tci->buffer,tci->extent.width,tci->extent.height,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
CommitTextureCube(tex,tci->buffer,tci->mipmap_zero_total_bytes,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mipmaps<70><73><EFBFBD><EFBFBD>
{
CommitTexture2DMipmaps(tex,tci->buffer,tci->extent.width,tci->extent.height,tci->mipmap_zero_total_bytes);
CommitTextureCubeMipmaps(tex,tci->buffer,tci->extent,tci->mipmap_zero_total_bytes);
}
}
else
if(tci->origin_mipmaps<=1) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mipmaps<70><73><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ҫmipmaps
{
CommitTexture2D(tex,tci->buffer,tci->extent.width,tci->extent.height,VK_PIPELINE_STAGE_TRANSFER_BIT);
GenerateMipmaps2D(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel);
CommitTextureCube(tex,tci->buffer,tci->mipmap_zero_total_bytes,VK_PIPELINE_STAGE_TRANSFER_BIT);
GenerateMipmapsCube(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel);
}
texture_cmd_buf->End();
@@ -79,111 +79,149 @@ TextureCube *GPUDevice::CreateTextureCube(TextureCreateInfo *tci)
delete tci->buffer;
}
delete tci;
delete tci; //"delete tci" is correct,please don't use "Clear(tci)"
return tex;
}
//
//bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,VkPipelineStageFlags destinationStage)
//{
// if(!tex||!buf)
// return(false);
//
// ImageSubresourceRange subresourceRange(tex->GetAspect(),tex->GetMipLevel());
//
// texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
// VK_PIPELINE_STAGE_HOST_BIT,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// 0,
// VK_ACCESS_TRANSFER_WRITE_BIT,
// VK_IMAGE_LAYOUT_UNDEFINED,
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// subresourceRange);
//
// texture_cmd_buf->CopyBufferToImage(
// buf->GetBuffer(),
// tex->GetImage(),
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// count,
// buffer_image_copy);
//
// if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ǹ<EFBFBD><C7B8>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>mipmaps
// {
// texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_ACCESS_TRANSFER_WRITE_BIT,
// VK_ACCESS_TRANSFER_WRITE_BIT,
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// subresourceRange);
// }
// else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD>fragment shader<65><72><EFBFBD>ˣ<EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
// {
// texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
// VK_ACCESS_TRANSFER_WRITE_BIT,
// VK_ACCESS_SHADER_READ_BIT,
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
// subresourceRange);
// }
//
// return(true);
//}
//
//bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t width,uint32_t height,VkPipelineStageFlags destinationStage)
//{
// if(!tex||!buf)return(false);
//
// BufferImageCopy buffer_image_copy(tex);
//
// return CommitTexture2D(tex,buf,&buffer_image_copy,1,destinationStage);
//}
//
//bool GPUDevice::CommitTexture2DMipmaps(Texture2D *tex,GPUBuffer *buf,uint32_t width,uint32_t height,uint32_t total_bytes)
//{
// if(!tex||!buf
// ||width<=0||height<=0)
// return(false);
//
// const uint32_t miplevel=tex->GetMipLevel();
//
// 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 CommitTexture2D(tex,buf,buffer_image_copy,miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
//}
//
bool GPUDevice::CommitTextureCube(TextureCube *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,VkPipelineStageFlags destinationStage)
{
if(!tex||!buf)
return(false);
ImageSubresourceRange subresourceRange(tex->GetAspect(),tex->GetMipLevel(),6);
texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
texture_cmd_buf->CopyBufferToImage(
buf->GetBuffer(),
tex->GetImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
count,
buffer_image_copy);
if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ǹ<EFBFBD><C7B8>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>mipmaps
{
texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
}
else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD>fragment shader<65><72><EFBFBD>ˣ<EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
{
texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
subresourceRange);
}
return(true);
}
bool GPUDevice::CommitTextureCube(TextureCube *tex,GPUBuffer *buf,const uint32_t mipmaps_zero_bytes,VkPipelineStageFlags destinationStage)
{
if(!tex||!buf||!mipmaps_zero_bytes)return(false);
AutoDeleteArray<VkBufferImageCopy> bic_list(6);
uint32_t face=0;
uint32_t offset=0;
for(VkBufferImageCopy &bic:bic_list)
{
bic.bufferOffset = offset;
bic.bufferRowLength = 0;
bic.bufferImageHeight = 0;
bic.imageSubresource.aspectMask = tex->GetAspect();
bic.imageSubresource.mipLevel = 0;
bic.imageSubresource.baseArrayLayer = face;
bic.imageSubresource.layerCount = 1;
bic.imageOffset.x = 0;
bic.imageOffset.y = 0;
bic.imageOffset.z = 0;
bic.imageExtent.width = tex->GetWidth();
bic.imageExtent.height= tex->GetHeight();
bic.imageExtent.depth = 1;
++face;
offset+=mipmaps_zero_bytes;
}
return CommitTextureCube(tex,buf,bic_list,6,destinationStage);
}
bool GPUDevice::CommitTextureCubeMipmaps(TextureCube *tex,GPUBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes)
{
if(!tex||!buf
||extent.width*extent.height<=0)
return(false);
const uint32_t miplevel=tex->GetMipLevel();
AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(miplevel*6);
VkDeviceSize offset=0;
uint32_t face=0;
uint32_t level=0;
uint32_t width=extent.width;
uint32_t height=extent.height;
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 = face;
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(face==5)
{
face=0;
++level;
if(width>1){width>>=1;total_bytes>>=1;}
if(height>1){height>>=1;total_bytes>>=1;}
}
else
{
++face;
}
}
return CommitTextureCube(tex,buf,buffer_image_copy,miplevel*6,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
//bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List<Image2DRegion> &ir_list,VkPipelineStageFlags destinationStage)
//{
// if(!tex||!buf||ir_list.GetCount()<=0)

View File

@@ -148,4 +148,24 @@ Texture2D *RenderResource::LoadTexture2D(const OSString &filename,bool auto_mipm
return tex;
}
TextureCube *CreateTextureCubeFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps);
TextureCube *RenderResource::LoadTextureCube(const OSString &filename,bool auto_mipmaps)
{
TextureCube *tex;
if(texture_by_name.Get(filename,(Texture *&)tex))
return tex;
tex=CreateTextureCubeFromFile(device,filename,auto_mipmaps);
if(tex)
{
texture_by_name.Add(filename,tex);
Add(tex);
}
return tex;
}
VK_NAMESPACE_END