12 bIsTextureLoadedInGPU(false),
54 throw std::runtime_error(
"ImageData is not initialized!");
60 if (width >
static_cast<unsigned int>(std::numeric_limits<int32_t>::max()) ||
61 height >
static_cast<unsigned int>(std::numeric_limits<int32_t>::max()))
63 throw std::out_of_range(
"Texture dimensions exceed supported mipmap range.");
66 mMipmapLevels =
static_cast<uint32_t
>(std::floor(std::log2(std::max(width, height)))) + 1;
69 const VkDeviceSize imageSize =
70 static_cast<VkDeviceSize
>(width) *
71 static_cast<VkDeviceSize
>(height) *
74 if (pixelVector.size() == 0)
76 throw std::runtime_error(
"failed to load texture image!");
79 VkBuffer stagingBuffer;
80 VkDeviceMemory stagingBufferMemory;
82 mRenderer->
CreateBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
84 unsigned char* pixels =
new unsigned char[
static_cast<size_t>(imageSize)];
85 std::copy(pixelVector.begin(), pixelVector.end(), pixels);
88 memcpy(data, pixels,
static_cast<size_t>(imageSize));
92 CreateVulkanImage(
static_cast<uint32_t
>(width),
static_cast<uint32_t
>(height),
mMipmapLevels, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
103 VK_FORMAT_R8G8B8A8_SRGB,
104 static_cast<int32_t
>(width),
105 static_cast<int32_t
>(height),
109void VulkanTextureResources::CreateVulkanImage(uint32_t width, uint32_t height, std::uint32_t mipmapLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory)
111 VkImageCreateInfo imageInfo{};
112 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
113 imageInfo.imageType = VK_IMAGE_TYPE_2D;
114 imageInfo.extent.width = width;
115 imageInfo.extent.height = height;
116 imageInfo.extent.depth = 1;
117 imageInfo.mipLevels = mipmapLevels;
118 imageInfo.arrayLayers = 1;
120 imageInfo.format = format;
121 imageInfo.tiling = tiling;
123 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
125 imageInfo.usage = usage;
127 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
129 imageInfo.samples = numSamples;
134 throw std::runtime_error(
"failed to create image!");
137 VkMemoryRequirements memRequirements;
140 VkMemoryAllocateInfo allocInfo{};
141 allocInfo.allocationSize = memRequirements.size;
142 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
143 allocInfo.allocationSize = memRequirements.size;
147 throw std::runtime_error(
"failed to allocate image memory!");
162 VkImageViewCreateInfo viewInfo{};
163 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
164 viewInfo.image = image;
165 viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
166 viewInfo.format = format;
167 viewInfo.subresourceRange.aspectMask = aspectFlags;
168 viewInfo.subresourceRange.baseMipLevel = 0;
169 viewInfo.subresourceRange.levelCount = mipmapLevels;
170 viewInfo.subresourceRange.baseArrayLayer = 0;
171 viewInfo.subresourceRange.layerCount = 1;
173 VkImageView imageView;
176 throw std::runtime_error(
"failed to create texture image view!");
184 VkSamplerCreateInfo samplerInfo{};
186 VkPhysicalDeviceProperties properties{};
189 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
190 samplerInfo.magFilter = VK_FILTER_LINEAR;
191 samplerInfo.minFilter = VK_FILTER_LINEAR;
193 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
194 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
195 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
199 samplerInfo.anisotropyEnable = VK_TRUE;
200 samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
204 samplerInfo.anisotropyEnable = VK_FALSE;
205 samplerInfo.maxAnisotropy = 1.0f;
208 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
209 samplerInfo.unnormalizedCoordinates = VK_FALSE;
211 samplerInfo.compareEnable = VK_FALSE;
212 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
214 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
215 samplerInfo.mipLodBias = 0.0f;
216 samplerInfo.minLod = 0.0f;
221 throw std::runtime_error(
"failed to create texture sampler!");
Represents raw 2D image data stored in memory.
unsigned int GetWidth() const
Returns the image width.
std::vector< uint8_t > GetImageDataRGBA() const
Gets raw image data in RGBA format.
unsigned int GetHeight() const
Returns the image height.
Vulkan-based implementation of the IRenderer interface.
VkPhysicalDeviceFeatures & GetPhysDevSupportedFeatures()
Returns reference to the physical device�s supported features.
void GenerateMipmaps(VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels)
Generates mipmaps for a given image resource.
void CopyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height)
Copies buffer data into an image (used for uploading texture data).
VkDevice & GetLogicalDevice()
Returns reference to the logical Vulkan device.
VkPhysicalDevice & GetPhysicalDevice()
Returns reference to the physical device.
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory)
Creates a new Vulkan buffer with the specified usage and memory properties.
uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
Finds a suitable memory type for a given allocation.
void TransitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, std::uint32_t mipmapLevels)
Transitions the image layout for a given Vulkan image.
VulkanTextureResources(VulkanRenderer *renderer)
Vulkan-specific implementation of ITextureRenderResources.
size_t GetSizeInGPUBytes() const override
Returns the size of the texture in GPU memory in bytes.
VkImageView CreateImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, std::uint32_t mipmapLevels)
bool IsTextureLoadedInGPU() override
Checks if the texture is currently loaded in GPU memory.
void LoadToGPU(const ImageData &data) override
Uploads the texture data from CPU to GPU memory using Vulkan.
void CreateTextureImage()
VulkanRenderer * mRenderer
void CreateTextureImageView()
bool bIsTextureLoadedInGPU
void CreateTextureSampler()
void ReleaseFromGPU() override
Releases the texture data from GPU memory using Vulkan.
VkSampler mTextureSampler
VkImageView mTextureImageView
VkDeviceMemory mTextureImageMemory
void CreateVulkanImage(uint32_t width, uint32_t height, std::uint32_t mipmapLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage &image, VkDeviceMemory &imageMemory)
const ImageData * mImageData
std::uint32_t mMipmapLevels
VkDeviceSize mGpuMemorySize