Files
Seele/src/Engine/Graphics/Vulkan/Texture.cpp
T

482 lines
17 KiB
C++
Raw Normal View History

2023-11-05 10:36:01 +01:00
#include "Texture.h"
2023-11-15 17:42:57 +01:00
#include "Command.h"
2020-04-01 02:17:49 +02:00
#include <math.h>
using namespace Seele;
using namespace Seele::Vulkan;
2020-04-12 15:47:19 +02:00
VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
2020-04-01 02:17:49 +02:00
{
2020-04-12 15:47:19 +02:00
switch (format)
{
case Gfx::SE_FORMAT_D16_UNORM:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case Gfx::SE_FORMAT_D32_SFLOAT:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case Gfx::SE_FORMAT_S8_UINT:
return VK_IMAGE_ASPECT_STENCIL_BIT;
case Gfx::SE_FORMAT_D16_UNORM_S8_UINT:
case Gfx::SE_FORMAT_D24_UNORM_S8_UINT:
case Gfx::SE_FORMAT_D32_SFLOAT_S8_UINT:
case Gfx::SE_FORMAT_X8_D24_UNORM_PACK32:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
2023-11-15 17:42:57 +01:00
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
2021-05-10 23:57:55 +02:00
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage)
: currentOwner(owner)
2020-06-02 11:46:18 +02:00
, graphics(graphics)
2023-11-15 17:42:57 +01:00
, width(createInfo.width)
, height(createInfo.height)
, depth(createInfo.depth)
, arrayCount(createInfo.elements)
, layerCount(createInfo.layers)
2021-04-01 16:40:14 +02:00
, mipLevels(createInfo.mipLevels)
, samples(createInfo.samples)
, format(createInfo.format)
, usage(createInfo.usage)
2020-06-02 11:46:18 +02:00
, image(existingImage)
2021-04-01 16:40:14 +02:00
, aspect(getAspectFromFormat(createInfo.format))
2021-05-10 23:57:55 +02:00
, layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED)
2023-11-17 22:31:26 +01:00
, ownsImage(false)
2020-04-12 15:47:19 +02:00
{
if (existingImage == VK_NULL_HANDLE)
{
2023-11-17 22:31:26 +01:00
ownsImage = true;
2023-11-15 17:42:57 +01:00
VkImageType type = VK_IMAGE_TYPE_MAX_ENUM;
VkImageCreateFlags flags = 0;
2020-04-12 15:47:19 +02:00
switch (viewType)
{
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2023-11-15 17:42:57 +01:00
type = VK_IMAGE_TYPE_1D;
2020-04-12 15:47:19 +02:00
break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2023-11-15 17:42:57 +01:00
type = VK_IMAGE_TYPE_2D;
2020-04-12 15:47:19 +02:00
break;
case VK_IMAGE_VIEW_TYPE_3D:
2023-11-15 17:42:57 +01:00
type = VK_IMAGE_TYPE_3D;
2020-04-12 15:47:19 +02:00
break;
case VK_IMAGE_VIEW_TYPE_CUBE:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2023-11-15 17:42:57 +01:00
type = VK_IMAGE_TYPE_2D;
flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
2020-04-12 15:47:19 +02:00
layerCount = 6 * arrayCount;
break;
default:
break;
}
2023-12-10 22:27:59 +01:00
if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
{
usage = usage
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT;
}
2023-11-15 17:42:57 +01:00
VkImageCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.imageType = type,
.format = cast(format),
.extent = {
.width = width,
.height = height,
.depth = depth,
},
.mipLevels = mipLevels,
.arrayLayers = arrayCount * layerCount,
.samples = (VkSampleCountFlagBits)samples,
.tiling = VK_IMAGE_TILING_OPTIMAL,
2023-12-10 22:27:59 +01:00
.usage = usage,
2023-11-15 17:42:57 +01:00
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.initialLayout = cast(layout),
};
2024-01-17 17:57:59 +01:00
VmaAllocationCreateInfo allocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateImage(graphics->getAllocator(), &info, &allocInfo, &image, &allocation, nullptr));
2021-05-10 23:57:55 +02:00
2024-01-17 17:57:59 +01:00
const DataSource& sourceData = createInfo.sourceData;
if(sourceData.size > 0)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
void* data;
VkMemoryPropertyFlags memProps;
VkBuffer stagingBuffer = VK_NULL_HANDLE;
VmaAllocation stagingAlloc = VK_NULL_HANDLE;
vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &memProps);
if(memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
vmaMapMemory(graphics->getAllocator(), allocation, &data);
}
else
{
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = sourceData.size,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo alloc = {
.usage = VMA_MEMORY_USAGE_AUTO,
2024-01-17 19:34:38 +01:00
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
2024-01-17 17:57:59 +01:00
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingBuffer, &stagingAlloc, nullptr));
vmaMapMemory(graphics->getAllocator(), stagingAlloc, &data);
}
std::memcpy(data, sourceData.data, sourceData.size);
vmaFlushAllocation(graphics->getAllocator(), stagingAlloc, 0, VK_WHOLE_SIZE);
2020-04-12 15:47:19 +02:00
2024-01-17 17:57:59 +01:00
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = arrayCount * layerCount,
},
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
};
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(),
stagingBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(stagingBuffer != VK_NULL_HANDLE)
{
2024-01-17 19:34:38 +01:00
vmaUnmapMemory(graphics->getAllocator(), stagingAlloc);
graphics->getDestructionManager()->queueBuffer(commandPool->getCommands(), stagingBuffer, stagingAlloc);
2024-01-17 17:57:59 +01:00
}
}
2020-04-12 15:47:19 +02:00
}
2020-06-02 11:46:18 +02:00
2024-01-17 17:57:59 +01:00
if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
2020-10-14 01:49:43 +02:00
{
2021-05-10 23:57:55 +02:00
changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
2023-12-10 22:27:59 +01:00
else if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
2021-05-10 23:57:55 +02:00
else
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
2020-10-14 01:49:43 +02:00
}
2020-06-02 11:46:18 +02:00
2023-11-15 17:42:57 +01:00
VkImageViewCreateInfo viewInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.image = image,
.viewType = viewType,
.format = cast(format),
.subresourceRange = {
.aspectMask = aspect,
.levelCount = mipLevels,
.layerCount = layerCount,
},
};
2023-11-17 22:31:26 +01:00
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &imageView));
2020-04-01 02:17:49 +02:00
}
2023-11-15 17:42:57 +01:00
TextureBase::~TextureBase()
2020-04-01 02:17:49 +02:00
{
2023-11-17 22:31:26 +01:00
if (ownsImage)
{
2024-01-17 19:34:38 +01:00
graphics->getDestructionManager()->queueImage(graphics->getQueueCommands(currentOwner)->getCommands(), image, allocation);
2023-11-17 22:31:26 +01:00
}
graphics->getDestructionManager()->queueImageView(graphics->getQueueCommands(currentOwner)->getCommands(), imageView);
2020-04-01 02:17:49 +02:00
}
2020-10-03 11:00:10 +02:00
2023-11-15 17:42:57 +01:00
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout)
2020-06-02 11:46:18 +02:00
{
2023-11-15 17:42:57 +01:00
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
2024-01-02 16:48:03 +01:00
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
2023-11-15 17:42:57 +01:00
.oldLayout = cast(layout),
.newLayout = cast(newLayout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = {
.aspectMask = aspect,
2023-11-16 22:58:47 +01:00
.baseMipLevel = 0,
2023-11-15 17:42:57 +01:00
.levelCount = 1,
2023-11-16 22:58:47 +01:00
.baseArrayLayer = 0,
2023-11-15 17:42:57 +01:00
.layerCount = layerCount,
},
};
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
vkCmdPipelineBarrier(commandPool->getCommands()->getHandle(),
2020-06-02 11:46:18 +02:00
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
2023-11-15 17:42:57 +01:00
commandPool->submitCommands();
2020-06-02 11:46:18 +02:00
layout = newLayout;
}
2023-11-15 17:42:57 +01:00
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
2023-02-13 14:56:13 +01:00
{
2023-11-15 17:42:57 +01:00
uint64 imageSize = width * height * depth * Gfx::getFormatInfo(format).blockSize;
2023-02-13 14:56:13 +01:00
2024-01-17 17:57:59 +01:00
auto prevLayout = layout;
2023-02-13 14:56:13 +01:00
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
2024-01-17 17:57:59 +01:00
void* data;
VkBuffer stagingBuffer = VK_NULL_HANDLE;
VmaAllocation stagingAlloc;
2024-01-18 18:39:44 +01:00
// always create a staging buffer since we do buffer -> image copy and the image may be in any tiling format
2024-01-17 17:57:59 +01:00
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = imageSize,
2024-01-17 19:34:38 +01:00
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2024-01-17 17:57:59 +01:00
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo alloc = {
.usage = VMA_MEMORY_USAGE_AUTO,
2024-01-18 18:39:44 +01:00
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT,
2024-01-17 17:57:59 +01:00
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingBuffer, &stagingAlloc, nullptr));
2023-11-15 17:42:57 +01:00
PCommand cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
2023-11-06 14:47:21 +01:00
//Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
2023-02-13 14:56:13 +01:00
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = mipLevel,
.baseArrayLayer = arrayLayer * layerCount + face,
.layerCount = 1,
},
2023-11-15 17:42:57 +01:00
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
2023-02-13 14:56:13 +01:00
};
2024-01-17 17:57:59 +01:00
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer, 1, &region);
changeLayout(prevLayout);
2024-01-18 18:39:44 +01:00
VK_CHECK(vmaMapMemory(graphics->getAllocator(), stagingAlloc, &data));
2024-01-17 17:57:59 +01:00
buffer.resize(imageSize);
2023-02-13 14:56:13 +01:00
std::memcpy(buffer.data(), data, buffer.size());
2024-01-17 17:57:59 +01:00
vmaUnmapMemory(graphics->getAllocator(), stagingAlloc);
2024-01-18 18:39:44 +01:00
graphics->getDestructionManager()->queueBuffer(cmdBuffer, stagingBuffer, stagingAlloc);
2023-02-13 14:56:13 +01:00
}
2023-11-15 17:42:57 +01:00
void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner)
2020-04-12 15:47:19 +02:00
{
2023-11-15 17:42:57 +01:00
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkImageMemoryBarrier imageBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.image = image,
.subresourceRange = {
.aspectMask = aspect,
},
};
PCommandPool sourcePool = graphics->getQueueCommands(currentOwner);
PCommandPool dstPool = nullptr;
2020-04-12 15:47:19 +02:00
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (currentOwner == Gfx::QueueType::COMPUTE)
{
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (currentOwner == Gfx::QueueType::GRAPHICS)
{
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER)
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
2023-11-15 17:42:57 +01:00
dstPool = graphics->getTransferCommands();
2020-04-12 15:47:19 +02:00
}
2020-06-02 11:46:18 +02:00
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
2020-04-12 15:47:19 +02:00
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
2023-11-15 17:42:57 +01:00
dstPool = graphics->getDedicatedTransferCommands();
2020-04-12 15:47:19 +02:00
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
2023-11-15 17:42:57 +01:00
dstPool = graphics->getComputeCommands();
2020-04-12 15:47:19 +02:00
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
2023-11-15 17:42:57 +01:00
dstPool = graphics->getGraphicsCommands();
2020-04-12 15:47:19 +02:00
}
2021-09-23 10:10:39 +02:00
2023-11-15 17:42:57 +01:00
VkCommandBuffer sourceCmd = sourcePool->getCommands()->getHandle();
VkCommandBuffer destCmd = dstPool->getCommands()->getHandle();
2021-09-23 10:10:39 +02:00
vkCmdPipelineBarrier(sourceCmd, srcStage, srcStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
vkCmdPipelineBarrier(destCmd, dstStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
2021-05-10 23:57:55 +02:00
currentOwner = newOwner;
2023-11-15 17:42:57 +01:00
sourcePool->submitCommands();
2020-04-12 15:47:19 +02:00
}
2020-04-01 02:17:49 +02:00
2023-11-15 17:42:57 +01:00
void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
2021-05-10 23:57:55 +02:00
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
2020-04-12 15:47:19 +02:00
{
2023-11-15 17:42:57 +01:00
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = {
.aspectMask = aspect,
2023-11-16 22:58:47 +01:00
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
2023-11-15 17:42:57 +01:00
},
};
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
vkCmdPipelineBarrier(command->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
2020-04-12 15:47:19 +02:00
}
2020-06-02 11:46:18 +02:00
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
2023-11-01 23:12:30 +01:00
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
2023-11-15 17:42:57 +01:00
, TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, Gfx::Texture2D::currentOwner, existingImage)
2020-04-12 15:47:19 +02:00
{
2020-04-01 02:17:49 +02:00
}
Texture2D::~Texture2D()
{
2020-06-02 11:46:18 +02:00
}
2021-05-10 23:57:55 +02:00
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout)
{
2023-11-15 17:42:57 +01:00
TextureBase::changeLayout(newLayout);
2021-05-10 23:57:55 +02:00
}
2023-02-13 14:56:13 +01:00
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
2023-11-15 17:42:57 +01:00
TextureBase::download(mipLevel, arrayLayer, face, buffer);
2023-02-13 14:56:13 +01:00
}
2020-06-02 11:46:18 +02:00
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
2023-11-15 17:42:57 +01:00
TextureBase::executeOwnershipBarrier(newOwner);
2021-05-10 23:57:55 +02:00
}
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
2023-11-15 17:42:57 +01:00
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
2023-01-29 18:58:59 +01:00
}
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
2023-11-01 23:12:30 +01:00
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
2023-11-15 17:42:57 +01:00
, TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D,
createInfo, Gfx::Texture3D::currentOwner, existingImage)
2023-01-29 18:58:59 +01:00
{
}
Texture3D::~Texture3D()
{
}
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout)
{
2023-11-15 17:42:57 +01:00
TextureBase::changeLayout(newLayout);
2023-01-29 18:58:59 +01:00
}
2023-02-13 14:56:13 +01:00
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
2023-11-15 17:42:57 +01:00
TextureBase::download(mipLevel, arrayLayer, face, buffer);
2023-02-13 14:56:13 +01:00
}
2023-01-29 18:58:59 +01:00
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
2023-11-15 17:42:57 +01:00
TextureBase::executeOwnershipBarrier(newOwner);
2023-01-29 18:58:59 +01:00
}
void Texture3D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
2023-11-15 17:42:57 +01:00
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
2023-01-29 18:58:59 +01:00
}
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
2023-11-01 23:12:30 +01:00
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner)
2023-11-15 17:42:57 +01:00
, TextureBase(graphics, createInfo.elements > 1? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE,
createInfo, Gfx::TextureCube::currentOwner, existingImage)
2023-01-29 18:58:59 +01:00
{
}
TextureCube::~TextureCube()
{
}
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout)
{
2023-11-15 17:42:57 +01:00
TextureBase::changeLayout(newLayout);
2023-01-29 18:58:59 +01:00
}
2023-02-13 14:56:13 +01:00
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
2023-11-15 17:42:57 +01:00
TextureBase::download(mipLevel, arrayLayer, face, buffer);
2023-02-13 14:56:13 +01:00
}
2023-01-29 18:58:59 +01:00
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
2023-11-15 17:42:57 +01:00
TextureBase::executeOwnershipBarrier(newOwner);
2023-01-29 18:58:59 +01:00
}
void TextureCube::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
2023-11-15 17:42:57 +01:00
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
2023-01-29 18:58:59 +01:00
}