| 4775 | } |
| 4776 | |
| 4777 | static void VulkanSetTextureInternal(VulkanContext* context, VulkanTexture* texture, const TextureParams& params) |
| 4778 | { |
| 4779 | // Same as graphics_opengl.cpp |
| 4780 | switch (params.m_Format) |
| 4781 | { |
| 4782 | case TEXTURE_FORMAT_DEPTH: |
| 4783 | case TEXTURE_FORMAT_STENCIL: |
| 4784 | dmLogError("Unable to upload texture data, unsupported type (%s).", GetTextureFormatLiteral(params.m_Format)); |
| 4785 | return; |
| 4786 | default:break; |
| 4787 | } |
| 4788 | |
| 4789 | assert(params.m_Width <= context->m_PhysicalDevice.m_Properties.limits.maxImageDimension2D); |
| 4790 | assert(params.m_Height <= context->m_PhysicalDevice.m_Properties.limits.maxImageDimension2D); |
| 4791 | |
| 4792 | if (texture->m_Base.m_MipMapCount == 1 && params.m_MipMap > 0) |
| 4793 | { |
| 4794 | return; |
| 4795 | } |
| 4796 | |
| 4797 | TextureFormat format_orig = params.m_Format; |
| 4798 | uint8_t tex_layer_count = dmMath::Max(texture->m_LayerCount, params.m_LayerCount); |
| 4799 | uint16_t tex_depth = dmMath::Max(texture->m_Base.m_Depth, params.m_Depth); |
| 4800 | uint8_t tex_bpp = GetTextureFormatBitsPerPixel(params.m_Format); |
| 4801 | size_t tex_data_size_bpp = params.m_DataSize * tex_layer_count * 8; // Convert into bits |
| 4802 | void* tex_data_ptr = (void*)params.m_Data; |
| 4803 | VkFormat vk_format = GetVulkanFormatFromTextureFormat(params.m_Format); |
| 4804 | |
| 4805 | if (vk_format == VK_FORMAT_UNDEFINED) |
| 4806 | { |
| 4807 | dmLogError("Unable to upload texture data, unsupported type (%s).", GetTextureFormatLiteral(format_orig)); |
| 4808 | return; |
| 4809 | } |
| 4810 | |
| 4811 | // For future reference, we could validate ASTC buffer sizes by using these calculations: |
| 4812 | // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/ |
| 4813 | |
| 4814 | LogicalDevice& logical_device = context->m_LogicalDevice; |
| 4815 | VkPhysicalDevice vk_physical_device = context->m_PhysicalDevice.m_Device; |
| 4816 | |
| 4817 | // Note: There's no RGB support in Vulkan. We have to expand this to four channels |
| 4818 | // TODO: Can we use R11G11B10 somehow? |
| 4819 | uint8_t* temp_data = 0; |
| 4820 | if (format_orig == TEXTURE_FORMAT_RGB) |
| 4821 | { |
| 4822 | uint32_t data_pixel_count = params.m_Width * params.m_Height * tex_layer_count; |
| 4823 | temp_data = new uint8_t[data_pixel_count * 4]; // RGBA => 4 bytes per pixel |
| 4824 | |
| 4825 | RepackRGBToRGBA(data_pixel_count, (uint8_t*) tex_data_ptr, temp_data); |
| 4826 | vk_format = VK_FORMAT_R8G8B8A8_UNORM; |
| 4827 | tex_data_ptr = temp_data; |
| 4828 | tex_bpp = 32; |
| 4829 | } |
| 4830 | |
| 4831 | // In cases where we just want to clear the texture we don't have a valid data or datasize, so we need to infer it. |
| 4832 | // This will NOT work for clearing compressed texture formats, but I don't think that is a case we can support anyway. |
| 4833 | tex_data_size_bpp = tex_bpp * params.m_Width * params.m_Height * tex_depth * tex_layer_count; |
| 4834 | texture->m_Base.m_Format = params.m_Format; |
no test coverage detected