10 VulkanTexture::VulkanTexture(
const eastl::string& filename,
int desiredChannels) : Texture(filename, desiredChannels)
12 eastl::string baseLocation =
"Resources/Textures/";
13 baseLocation.append(filename);
15 stbi_uc* textureData = stbi_load(
17 baseLocation.c_str() :
18 "Resources/Textures/default.png",
21 VulkanTexture::CreateTextureWithData(textureData,
true);
23 stbi_image_free(textureData);
26 VulkanTexture::VulkanTexture(
int width,
int height) : Texture(width, height), image(0), imageView(0), sampler(0),
31 VulkanRenderer* VulkanTexture::renderer =
nullptr;
32 VulkanLogicalDevice *VulkanTexture::device =
nullptr;
33 VulkanDescriptorPool* VulkanTexture::descriptorPool =
nullptr;
34 VmaAllocator VulkanTexture::allocator = VK_NULL_HANDLE;
35 VkCommandPool VulkanTexture::commandPool = VK_NULL_HANDLE;
37 void VulkanTexture::InitTextureSystem(VulkanRenderer* renderer, VulkanLogicalDevice * device, VulkanDescriptorPool* descriptorPool, VmaAllocator allocator, VkCommandPool commandPool)
39 VulkanTexture::renderer = renderer;
40 VulkanTexture::device = device;
41 VulkanTexture::descriptorPool = descriptorPool;
42 VulkanTexture::allocator = allocator;
43 VulkanTexture::commandPool = commandPool;
46 VulkanTexture::~VulkanTexture()
48 vkQueueWaitIdle(device->GetGraphicsQueue());
50 vkDestroySampler(device->GetDevice(), sampler,
nullptr);
51 vkDestroyImageView(device->GetDevice(), imageView,
nullptr);
53 vmaDestroyImage(allocator, image, allocation);
56 void VulkanTexture::CreateTextureWithData(stbi_uc* data,
bool genMipMaps,
TextureDataSize bytes,
bool storage)
59 this->storage = storage;
87 VkBufferCreateInfo stagingBufferInfo = {};
88 stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
89 stagingBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
90 stagingBufferInfo.size =
width *
height * 4 * byteSize;
91 stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
93 VmaAllocationCreateInfo stagingBufferAllocInfo = {};
94 stagingBufferAllocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
96 VkBuffer stagingBuffer;
97 VmaAllocation stagingBufferAllocation;
99 vmaCreateBuffer(allocator, &stagingBufferInfo, &stagingBufferAllocInfo, &stagingBuffer, &stagingBufferAllocation,
nullptr);
103 vmaMapMemory(allocator, stagingBufferAllocation, &dst);
104 memcpy(dst, data, static_cast<size_t>(
width*
height * 4 * byteSize));
105 vmaUnmapMemory(allocator, stagingBufferAllocation);
111 format = VK_FORMAT_R8G8B8A8_UNORM;
114 format = VK_FORMAT_R8G8B8A8_SNORM;
117 format = VK_FORMAT_R16G16B16A16_UNORM;
120 format = VK_FORMAT_R16G16B16A16_SFLOAT;
123 format = VK_FORMAT_R32G32B32A32_UINT;
126 format = VK_FORMAT_R32G32B32A32_SFLOAT;
129 format = VK_FORMAT_R8G8B8A8_UNORM;
133 VkImageCreateInfo imageCreateInfo = {};
134 imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
135 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
136 imageCreateInfo.extent.width =
static_cast<uint32_t
>(
width);
137 imageCreateInfo.extent.height =
static_cast<uint32_t
>(
height);
138 imageCreateInfo.extent.depth = 1;
139 imageCreateInfo.mipLevels = 1;
140 imageCreateInfo.arrayLayers = 1;
141 imageCreateInfo.format = format;
142 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
143 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
144 imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
146 imageCreateInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
148 imageCreateInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
149 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
150 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
151 imageCreateInfo.flags = 0;
153 VmaAllocationCreateInfo imageAllocInfo = {};
154 imageAllocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
156 vmaCreateImage(allocator, &imageCreateInfo, &imageAllocInfo, &image, &allocation, &allocationInfo);
158 VkCommandBuffer commandBuffer;
160 VkCommandBufferAllocateInfo cmdAllocInfo = {};
161 cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
162 cmdAllocInfo.commandPool = commandPool;
163 cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
164 cmdAllocInfo.commandBufferCount = 1;
166 vkAllocateCommandBuffers(device->GetDevice(), &cmdAllocInfo, &commandBuffer);
168 VkCommandBufferBeginInfo cmdBeginInfo = {};
169 cmdBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
170 cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
172 vkBeginCommandBuffer(commandBuffer, &cmdBeginInfo);
174 VkImageMemoryBarrier barrier1 = {};
175 barrier1.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
176 barrier1.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
177 barrier1.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
178 barrier1.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
179 barrier1.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
180 barrier1.image = image;
181 barrier1.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
182 barrier1.subresourceRange.baseArrayLayer = 0;
183 barrier1.subresourceRange.baseMipLevel = 0;
184 barrier1.subresourceRange.layerCount = 1;
185 barrier1.subresourceRange.levelCount = 1;
186 barrier1.srcAccessMask = 0;
187 barrier1.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
189 vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0,
nullptr, 0,
nullptr, 1, &barrier1);
191 VkBufferImageCopy region;
192 region.bufferOffset = 0;
193 region.bufferRowLength = 0;
194 region.bufferImageHeight = 0;
196 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
197 region.imageSubresource.baseArrayLayer = 0;
198 region.imageSubresource.layerCount = 1;
199 region.imageSubresource.mipLevel = 0;
201 region.imageOffset = { 0,0,0 };
202 region.imageExtent = {
203 static_cast<uint32_t
>(
width),
204 static_cast<uint32_t>(
height),
208 vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
210 VkImageMemoryBarrier barrier2 = {};
211 barrier2.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
212 barrier2.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
214 barrier2.newLayout = VK_IMAGE_LAYOUT_GENERAL;
216 barrier2.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
217 barrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
218 barrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
219 barrier2.image = image;
220 barrier2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
221 barrier2.subresourceRange.baseMipLevel = 0;
222 barrier2.subresourceRange.baseArrayLayer = 0;
223 barrier2.subresourceRange.layerCount = 1;
224 barrier2.subresourceRange.levelCount = 1;
225 barrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
226 barrier2.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
228 vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
nullptr, 0,
nullptr, 1, &barrier2);
230 vkEndCommandBuffer(commandBuffer);
232 VkSubmitInfo submitInfo = {};
233 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
234 submitInfo.commandBufferCount = 1;
235 submitInfo.pCommandBuffers = &commandBuffer;
239 vkQueueSubmit(device->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
240 vkQueueWaitIdle(device->GetGraphicsQueue());
241 vkFreeCommandBuffers(device->GetDevice(), commandPool, 1, &commandBuffer);
243 vmaDestroyBuffer(allocator, stagingBuffer, stagingBufferAllocation);
245 VkImageViewCreateInfo viewCreateInfo = {};
246 viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
247 viewCreateInfo.image = image;
248 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
249 viewCreateInfo.format = format;
250 viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
251 viewCreateInfo.subresourceRange.baseArrayLayer = 0;
252 viewCreateInfo.subresourceRange.baseMipLevel = 0;
253 viewCreateInfo.subresourceRange.layerCount = 1;
254 viewCreateInfo.subresourceRange.levelCount = 1;
256 vkCreateImageView(device->GetDevice(), &viewCreateInfo,
nullptr, &imageView);
258 VkSamplerCreateInfo samplerInfo = {};
259 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
260 samplerInfo.magFilter = VK_FILTER_LINEAR;
261 samplerInfo.minFilter = VK_FILTER_LINEAR;
263 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
264 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
265 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
267 samplerInfo.anisotropyEnable = VK_TRUE;
268 samplerInfo.maxAnisotropy = 4;
270 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
271 samplerInfo.unnormalizedCoordinates = VK_FALSE;
273 samplerInfo.compareEnable = VK_FALSE;
274 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
276 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
277 samplerInfo.mipLodBias = 0.f;
278 samplerInfo.minLod = 0.f;
279 samplerInfo.maxLod = 0.f;
281 vkCreateSampler(device->GetDevice(), &samplerInfo,
nullptr, &sampler);
283 void VulkanTexture::SetSampler(VkSamplerCreateInfo samplerInfo)
285 if (sampler != VK_NULL_HANDLE)
286 vkDestroySampler(device->GetDevice(), sampler,
nullptr);
287 vkCreateSampler(device->GetDevice(), &samplerInfo,
nullptr, &sampler);
289 for (
size_t i = 0, size = descriptorSets.size(); i < size; ++i) {
290 for (
size_t j = 0, size2 = descriptorSets[i].size(); j < size2; ++j) {
291 for (
size_t k = 0, size3 = descriptorSets[i][j].size(); j < size3; ++k) {
292 if (descriptorSets[i][j][k] != VK_NULL_HANDLE) {
294 VkDescriptorType type;
295 VkImageLayout layout;
297 type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
298 layout = VK_IMAGE_LAYOUT_GENERAL;
301 type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
302 layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
305 renderer->GetDescriptorPool(k)->DescriptorSetBindToImage(descriptorSets[i][j][k],
307 imageView, sampler, 0, 0,
314 VkImage VulkanTexture::GetImage()
const 318 VkImageView VulkanTexture::GetImageView()
const 322 VkSampler VulkanTexture::GetSampler()
const 326 VkDescriptorSet VulkanTexture::CreateDescriptorSet(
size_t threadID,
size_t pipelineID,
size_t set, VkDescriptorSetLayout layout)
328 if (descriptorSets.size() <= pipelineID) {
329 descriptorSets.resize(pipelineID + 1);
331 if (descriptorSets[pipelineID].size() <=
set) {
332 descriptorSets[pipelineID].resize(
set + 1);
334 if (descriptorSets[pipelineID][
set].size() <= threadID) {
335 descriptorSets[pipelineID][
set].resize(threadID + 1, VK_NULL_HANDLE);
338 VkDescriptorSetLayout layouts[] = { layout };
339 renderer->GetDescriptorPool(threadID)->AllocateDescriptorSet(1, layouts, &descriptorSets[pipelineID][
set][threadID]);
341 VkDescriptorType type;
342 VkImageLayout imageLayout;
344 type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
345 imageLayout = VK_IMAGE_LAYOUT_GENERAL;
348 type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
349 imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
351 renderer->GetDescriptorPool(threadID)->DescriptorSetBindToImage(descriptorSets[pipelineID][
set][threadID],
353 imageView, sampler, 0, 0,
356 return descriptorSets[pipelineID][
set][threadID];
358 VkDescriptorSet VulkanTexture::GetDescriptorSet(
size_t threadID,
size_t pipelineID,
size_t set)
360 if (pipelineID >= descriptorSets.size())
361 return VK_NULL_HANDLE;
362 if (
set >= descriptorSets[pipelineID].size())
363 return VK_NULL_HANDLE;
364 if (threadID >= descriptorSets[pipelineID][
set].size())
365 return VK_NULL_HANDLE;
366 return descriptorSets[pipelineID][
set][threadID];
static bool FileExists(const eastl::string &fileName)