| 5056 | } |
| 5057 | |
| 5058 | static int AsyncProcessCallback(HJobContext, HJob job, void* _context, void* data) |
| 5059 | { |
| 5060 | VulkanContext* context = (VulkanContext*) _context; |
| 5061 | uint16_t param_array_index = (uint16_t) (size_t) data; |
| 5062 | SetTextureAsyncParams ap = GetSetTextureAsyncParams(context->m_SetTextureAsyncState, param_array_index); |
| 5063 | |
| 5064 | if (dmAtomicGet32(&context->m_DeleteContextRequested)) |
| 5065 | { |
| 5066 | return 0; |
| 5067 | } |
| 5068 | |
| 5069 | VulkanTexture* tex; |
| 5070 | { |
| 5071 | DM_MUTEX_SCOPED_LOCK(context->m_BaseContext.m_AssetHandleContainerMutex); |
| 5072 | tex = GetAssetFromContainer<VulkanTexture>(context->m_BaseContext.m_AssetHandleContainer, ap.m_Texture); |
| 5073 | } |
| 5074 | |
| 5075 | // Texture might have been deleted before the job thread has started processing this job. |
| 5076 | if (tex == NULL) |
| 5077 | { |
| 5078 | return 0; |
| 5079 | } |
| 5080 | |
| 5081 | // Async texture uploading |
| 5082 | { |
| 5083 | VkCommandBuffer cmd_buffer = BeginSingleTimeCommands(context->m_LogicalDevice.m_Device, context->m_LogicalDevice.m_CommandPoolWorker); |
| 5084 | |
| 5085 | uint8_t tex_layer_count = dmMath::Max(tex->m_LayerCount, ap.m_Params.m_LayerCount); |
| 5086 | uint16_t tex_depth = dmMath::Max((uint16_t) 1, dmMath::Max(tex->m_Base.m_Depth, ap.m_Params.m_Depth)); |
| 5087 | TextureFormat format_orig = ap.m_Params.m_Format; |
| 5088 | void* tex_data_ptr = (void*) ap.m_Params.m_Data; |
| 5089 | uint8_t* temp_data = 0; |
| 5090 | bool is_memoryless = IsTextureMemoryless(tex); |
| 5091 | |
| 5092 | uint32_t tex_data_size; |
| 5093 | if (IsTextureFormatASTC(ap.m_Params.m_Format)) |
| 5094 | { |
| 5095 | tex_data_size = ap.m_Params.m_DataSize * tex_layer_count; |
| 5096 | } |
| 5097 | else |
| 5098 | { |
| 5099 | uint32_t tex_bpp = GetTextureFormatBitsPerPixel(ap.m_Params.m_Format); |
| 5100 | uint32_t tex_data_size_bpp = tex_bpp * ap.m_Params.m_Width * ap.m_Params.m_Height * tex_depth * tex_layer_count; |
| 5101 | tex_data_size = (uint32_t) ceil((float) tex_data_size_bpp / 8.0f); |
| 5102 | } |
| 5103 | |
| 5104 | DeviceBuffer stage_buffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT); |
| 5105 | |
| 5106 | if (!is_memoryless) |
| 5107 | { |
| 5108 | // Note: There's no RGB support in Vulkan. We have to expand this to four channels |
| 5109 | // TODO: Can we use R11G11B10 somehow? |
| 5110 | if (format_orig == TEXTURE_FORMAT_RGB) |
| 5111 | { |
| 5112 | uint32_t data_pixel_count = ap.m_Params.m_Width * ap.m_Params.m_Height * tex_layer_count; |
| 5113 | temp_data = new uint8_t[data_pixel_count * 4]; // RGBA => 4 bytes per pixel |
| 5114 | |
| 5115 | RepackRGBToRGBA(data_pixel_count, (uint8_t*) tex_data_ptr, temp_data); |
nothing calls this directly
no test coverage detected