| 55 | } |
| 56 | |
| 57 | void VulkanTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, ref_ptr<void> data) |
| 58 | { |
| 59 | Base::Create(context, params, data); |
| 60 | |
| 61 | static uint32_t textureCounter = 0; |
| 62 | textureCounter++; |
| 63 | m_textureID = textureCounter; |
| 64 | |
| 65 | ref_ptr<dp::vulkan::VulkanBaseContext> vulkanContext = context; |
| 66 | m_objectManager = vulkanContext->GetObjectManager(); |
| 67 | |
| 68 | if (Validate()) |
| 69 | { |
| 70 | m_objectManager->DestroyObject(m_textureObject); |
| 71 | m_textureObject = {}; |
| 72 | } |
| 73 | |
| 74 | auto const format = VulkanFormatUnpacker::Unpack(params.m_format); |
| 75 | |
| 76 | VkFormatProperties formatProperties; |
| 77 | vkGetPhysicalDeviceFormatProperties(vulkanContext->GetPhysicalDevice(), format, &formatProperties); |
| 78 | VkImageTiling tiling = VK_IMAGE_TILING_LINEAR; |
| 79 | if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) |
| 80 | tiling = VK_IMAGE_TILING_OPTIMAL; |
| 81 | |
| 82 | m_isMutable = params.m_isMutable; |
| 83 | if (params.m_isRenderTarget) |
| 84 | { |
| 85 | // Create image. |
| 86 | if (params.m_format == TextureFormat::DepthStencil || params.m_format == TextureFormat::Depth) |
| 87 | { |
| 88 | m_aspectFlags = params.m_format == TextureFormat::DepthStencil |
| 89 | ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) |
| 90 | : VK_IMAGE_ASPECT_DEPTH_BIT; |
| 91 | m_textureObject = m_objectManager->CreateImage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format, tiling, |
| 92 | m_aspectFlags, params.m_width, params.m_height); |
| 93 | } |
| 94 | else |
| 95 | { |
| 96 | m_aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; |
| 97 | m_textureObject = m_objectManager->CreateImage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, |
| 98 | format, tiling, m_aspectFlags, params.m_width, params.m_height); |
| 99 | } |
| 100 | } |
| 101 | else |
| 102 | { |
| 103 | auto const bufferSize = GetBytesPerPixel(params.m_format) * params.m_width * params.m_height; |
| 104 | |
| 105 | // Create temporary staging buffer. |
| 106 | m_creationStagingBuffer = make_unique_dp<VulkanStagingBuffer>(m_objectManager, bufferSize); |
| 107 | ASSERT(m_creationStagingBuffer->HasEnoughSpace(bufferSize), ()); |
| 108 | VulkanStagingBuffer::StagingData staging; |
| 109 | m_reservationId = m_creationStagingBuffer->ReserveWithId(bufferSize, staging); |
| 110 | if (data != nullptr) |
| 111 | memcpy(staging.m_pointer, data.get(), bufferSize); |
| 112 | else |
| 113 | memset(staging.m_pointer, 0, bufferSize); |
| 114 | m_creationStagingBuffer->Flush(); |