| 4683 | } |
| 4684 | |
| 4685 | static void CopyToTexture(VulkanContext* context, const TextureParams& params, |
| 4686 | bool use_stage_buffer, uint32_t tex_data_size, void* tex_data_ptr, VulkanTexture* texture_out) |
| 4687 | { |
| 4688 | DM_PROFILE(__FUNCTION__); |
| 4689 | |
| 4690 | VkDevice vk_device = context->m_LogicalDevice.m_Device; |
| 4691 | uint32_t layer_count = texture_out->m_LayerCount; |
| 4692 | assert(layer_count > 0); |
| 4693 | |
| 4694 | uint32_t slice_size = tex_data_size / layer_count; |
| 4695 | |
| 4696 | #ifdef __MACH__ |
| 4697 | // macOS quirk: stage buffer offsets for layered compressed data must be 8-byte aligned. |
| 4698 | // For small compressed mips (< 8 bytes per slice), skip upload to avoid validation errors. |
| 4699 | if (slice_size < 8 && layer_count > 1) |
| 4700 | { |
| 4701 | return; |
| 4702 | } |
| 4703 | #endif |
| 4704 | |
| 4705 | // Always allocate a temporary command buffer for the copy, even during a frame |
| 4706 | VkCommandBuffer vk_command_buffer = BeginSingleTimeCommands( |
| 4707 | context->m_LogicalDevice.m_Device, |
| 4708 | context->m_LogicalDevice.m_CommandPool); |
| 4709 | |
| 4710 | // Stage buffer path |
| 4711 | DeviceBuffer stage_buffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT); |
| 4712 | VkResult res = CreateDeviceBuffer( |
| 4713 | context->m_PhysicalDevice.m_Device, |
| 4714 | vk_device, |
| 4715 | tex_data_size, |
| 4716 | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, |
| 4717 | &stage_buffer); |
| 4718 | CHECK_VK_ERROR(res); |
| 4719 | |
| 4720 | res = WriteToDeviceBuffer(vk_device, tex_data_size, 0, tex_data_ptr, &stage_buffer); |
| 4721 | CHECK_VK_ERROR(res); |
| 4722 | |
| 4723 | TransitionImageLayoutWithCmdBuffer( |
| 4724 | vk_command_buffer, |
| 4725 | texture_out, |
| 4726 | VK_IMAGE_ASPECT_COLOR_BIT, |
| 4727 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 4728 | params.m_MipMap, |
| 4729 | layer_count); |
| 4730 | |
| 4731 | // Copy regions on the stack |
| 4732 | dmArray<VkBufferImageCopy> copy_regions; |
| 4733 | copy_regions.SetCapacity(layer_count); |
| 4734 | copy_regions.SetSize(layer_count); |
| 4735 | |
| 4736 | CopyToTextureLayerWithtStageBuffer( |
| 4737 | context, |
| 4738 | vk_command_buffer, |
| 4739 | copy_regions.Begin(), |
| 4740 | &stage_buffer, |
| 4741 | texture_out, |
| 4742 | params, |
no test coverage detected