Copy the temp buffer to the output image
This commit is contained in:
1 parent
466e0345b8
commit
9536dbc550
3 files changed
+166
-17
No files matched your search
+16
-6
@@ -1166,12 +1166,21 @@ typedef struct GpuCmdDispatchBaseRequest {
|
|||||||
u32 group_count_z;
|
u32 group_count_z;
|
||||||
} GpuCmdDispatchBaseRequest;
|
} GpuCmdDispatchBaseRequest;
|
||||||
|
|
||||||
typedef struct GpuQueueSubmitRequest {
|
typedef struct GpuBufferImageCopy {
|
||||||
GpuSemaphorePtrArray wait_semaphores;
|
GpuImageSubresourceLayers image_subresource;
|
||||||
GpuPipelineStageFlagsArray wait_dst_stage_masks;
|
GpuOffset3d image_offset;
|
||||||
GpuCommandBufferPtrArray command_buffers;
|
GpuExtent3d image_extent;
|
||||||
GpuSemaphorePtrArray signal_semaphores;
|
u64 buffer_offset;
|
||||||
} GpuQueueSubmitRequest;
|
} GpuBufferImageCopy;
|
||||||
|
typedef GpuBufferImageCopy *GpuBufferImageCopyArray;
|
||||||
|
|
||||||
|
typedef struct GpuCmdCopyBufferToImageRequest {
|
||||||
|
GpuCommandBuffer *command_buffer;
|
||||||
|
GpuBuffer *src_buffer;
|
||||||
|
GpuImage *dst_image;
|
||||||
|
GpuImageLayout dst_image_layout;
|
||||||
|
GpuBufferImageCopyArray copy_regions;
|
||||||
|
} GpuCmdCopyBufferToImageRequest;
|
||||||
|
|
||||||
GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request);
|
GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request);
|
||||||
GpuPhysicalDevice gpuFindPhysicalDevice(const WpAllocator *allocator, const WpAllocator *temp,
|
GpuPhysicalDevice gpuFindPhysicalDevice(const WpAllocator *allocator, const WpAllocator *temp,
|
||||||
@@ -1252,6 +1261,7 @@ void gpuCmdDraw(GpuCmdDrawRequest request);
|
|||||||
void gpuCmdDrawIndexed(GpuCmdDrawIndexedRequest request);
|
void gpuCmdDrawIndexed(GpuCmdDrawIndexedRequest request);
|
||||||
void gpuCmdDispatch(GpuCmdDispatchRequest request);
|
void gpuCmdDispatch(GpuCmdDispatchRequest request);
|
||||||
void gpuCmdDispatchBase(GpuCmdDispatchBaseRequest request);
|
void gpuCmdDispatchBase(GpuCmdDispatchBaseRequest request);
|
||||||
|
void gpuCmdCopyBufferToImage(const WpAllocator *temp, GpuCmdCopyBufferToImageRequest request);
|
||||||
|
|
||||||
#ifdef WP_PLATFORM_CPP
|
#ifdef WP_PLATFORM_CPP
|
||||||
END_C_LINKAGE
|
END_C_LINKAGE
|
||||||
|
|||||||
+144
-5
@@ -77,6 +77,7 @@ typedef VkRenderingAttachmentInfo *VkRenderingAttachmen
|
|||||||
typedef VkSemaphoreSubmitInfo *VkSemaphoreSubmitInfoArray;
|
typedef VkSemaphoreSubmitInfo *VkSemaphoreSubmitInfoArray;
|
||||||
typedef VkCommandBufferSubmitInfo *VkCommandBufferSubmitInfoArray;
|
typedef VkCommandBufferSubmitInfo *VkCommandBufferSubmitInfoArray;
|
||||||
typedef VkImageBlit2 *VkImageBlit2Array;
|
typedef VkImageBlit2 *VkImageBlit2Array;
|
||||||
|
typedef VkBufferImageCopy *VkBufferImageCopyArray;
|
||||||
|
|
||||||
struct GpuInstance {
|
struct GpuInstance {
|
||||||
VkInstance vk_instance;
|
VkInstance vk_instance;
|
||||||
@@ -890,8 +891,24 @@ GpuImage *gpuCreateImage(const WpAllocator *allocator, GpuImageCreateRequest req
|
|||||||
.initialLayout = vkImageLayoutFromGpuImageLayout(request.layout),
|
.initialLayout = vkImageLayoutFromGpuImageLayout(request.layout),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if the image requires a dedicated allocation
|
||||||
|
VkMemoryDedicatedRequirements dedicated_memory_reqs = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
|
||||||
|
};
|
||||||
|
VkMemoryRequirements2 memory_reqs = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
|
||||||
|
.pNext = &dedicated_memory_reqs,
|
||||||
|
};
|
||||||
|
VkDeviceImageMemoryRequirements image_memory_reqs = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
|
||||||
|
.pCreateInfo = &image_create_info,
|
||||||
|
};
|
||||||
|
vkGetDeviceImageMemoryRequirements(request.device->vk_device, &image_memory_reqs, &memory_reqs);
|
||||||
|
|
||||||
|
b8 requires_dedicated_memory = dedicated_memory_reqs.requiresDedicatedAllocation ||
|
||||||
|
dedicated_memory_reqs.prefersDedicatedAllocation;
|
||||||
VmaAllocationCreateInfo alloc_create_info = {
|
VmaAllocationCreateInfo alloc_create_info = {
|
||||||
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
|
.flags = requires_dedicated_memory ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0,
|
||||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -934,11 +951,14 @@ GpuImage *gpuLoadImageFromFile(const WpAllocator *allocator, const WpAllocator *
|
|||||||
wpStr8CopyToCstr(buf, &request.filename, request.filename.size + 1);
|
wpStr8CopyToCstr(buf, &request.filename, request.filename.size + 1);
|
||||||
|
|
||||||
i32 width, height, channels;
|
i32 width, height, channels;
|
||||||
const u8 *data = stbi_load(buf, &width, &height, &channels, 4);
|
i32 requested_channels = 4;
|
||||||
|
const u8 *data = stbi_load(buf, &width, &height, &channels, requested_channels);
|
||||||
assertWithLogger(data != NULL, &logger, "Failed to load image data");
|
assertWithLogger(data != NULL, &logger, "Failed to load image data");
|
||||||
|
|
||||||
|
GpuDevice *device = request.command_pool->device;
|
||||||
|
|
||||||
GpuImageCreateRequest img_request = {
|
GpuImageCreateRequest img_request = {
|
||||||
.device = request.command_pool->device,
|
.device = device,
|
||||||
.size = { .x = width, .y = height, .z = 1 },
|
.size = { .x = width, .y = height, .z = 1 },
|
||||||
.type = GPU_IMAGE_TYPE_2D,
|
.type = GPU_IMAGE_TYPE_2D,
|
||||||
.format = GPU_FORMAT_R8G8B8A8_SRGB,
|
.format = GPU_FORMAT_R8G8B8A8_SRGB,
|
||||||
@@ -956,14 +976,15 @@ GpuImage *gpuLoadImageFromFile(const WpAllocator *allocator, const WpAllocator *
|
|||||||
};
|
};
|
||||||
GpuImage *output = gpuCreateImage(allocator, img_request);
|
GpuImage *output = gpuCreateImage(allocator, img_request);
|
||||||
|
|
||||||
u64 data_size = width * height * channels * sizeof(u8);
|
u64 data_size = width * height * requested_channels * sizeof(u8);
|
||||||
GpuBufferCreateRequest temp_buf_request = {
|
GpuBufferCreateRequest temp_buf_request = {
|
||||||
.device = request.command_pool->device,
|
.device = device,
|
||||||
.size = data_size,
|
.size = data_size,
|
||||||
.usage = GPU_BUFFER_USAGE_TRANSFER_SRC,
|
.usage = GPU_BUFFER_USAGE_TRANSFER_SRC,
|
||||||
};
|
};
|
||||||
GpuBuffer temp_storage = gpuCreateBuffer(allocator, temp_buf_request);
|
GpuBuffer temp_storage = gpuCreateBuffer(allocator, temp_buf_request);
|
||||||
memcpy(temp_storage.cpu_mapping, data, data_size);
|
memcpy(temp_storage.cpu_mapping, data, data_size);
|
||||||
|
gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = temp_storage });
|
||||||
|
|
||||||
stbi_image_free((void *)data);
|
stbi_image_free((void *)data);
|
||||||
|
|
||||||
@@ -974,6 +995,95 @@ GpuImage *gpuLoadImageFromFile(const WpAllocator *allocator, const WpAllocator *
|
|||||||
GpuCommandBufferPtrArray cbs = gpuAllocateCommandBuffers(allocator, temp, cb_request);
|
GpuCommandBufferPtrArray cbs = gpuAllocateCommandBuffers(allocator, temp, cb_request);
|
||||||
GpuCommandBuffer *cb = cbs[0];
|
GpuCommandBuffer *cb = cbs[0];
|
||||||
|
|
||||||
|
gpuBeginCommandBuffer((GpuCommandBufferBeginRequest){ .command_buffer = cb, .one_time_submit = true });
|
||||||
|
|
||||||
|
GpuImageMemoryBarrier image_barrier = {
|
||||||
|
.image = output,
|
||||||
|
.src_stage_mask = GPU_PIPELINE_STAGE_NONE,
|
||||||
|
.src_access_mask = GPU_ACCESS_NONE,
|
||||||
|
.dst_stage_mask = GPU_PIPELINE_STAGE_TRANSFER,
|
||||||
|
.dst_access_mask = GPU_ACCESS_TRANSFER_WRITE,
|
||||||
|
.old_layout = GPU_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.new_layout = GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
.subresource = {
|
||||||
|
.aspect = GPU_IMAGE_ASPECT_COLOR,
|
||||||
|
.level_count = 1,
|
||||||
|
.layer_count = 1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GpuCmdPipelineBarrierRequest barrier_req = {
|
||||||
|
.command_buffer = cb,
|
||||||
|
.info = (GpuDependencyInfo){
|
||||||
|
.image_memory_barriers = wpArray(GpuImageMemoryBarrier, image_barrier),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
gpuCmdPipelineBarrier(temp, barrier_req);
|
||||||
|
|
||||||
|
GpuCmdCopyBufferToImageRequest copy_req = {
|
||||||
|
.command_buffer = cb,
|
||||||
|
.src_buffer = &temp_storage,
|
||||||
|
.dst_image = output,
|
||||||
|
.dst_image_layout = GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
.copy_regions = wpArray(
|
||||||
|
GpuBufferImageCopy,
|
||||||
|
(GpuBufferImageCopy){
|
||||||
|
.image_subresource = { .layer_count = 1, .aspect_mask = GPU_IMAGE_ASPECT_COLOR },
|
||||||
|
.image_extent = { .width = width, .height = height, .depth = 1 },
|
||||||
|
}
|
||||||
|
),
|
||||||
|
};
|
||||||
|
gpuCmdCopyBufferToImage(temp, copy_req);
|
||||||
|
|
||||||
|
image_barrier = (GpuImageMemoryBarrier){
|
||||||
|
.image = output,
|
||||||
|
.src_stage_mask = GPU_PIPELINE_STAGE_TRANSFER,
|
||||||
|
.src_access_mask = GPU_ACCESS_TRANSFER_WRITE,
|
||||||
|
.dst_stage_mask = GPU_PIPELINE_STAGE_FRAGMENT_SHADER,
|
||||||
|
.dst_access_mask = GPU_ACCESS_SHADER_READ,
|
||||||
|
.old_layout = GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
.new_layout = GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
||||||
|
.subresource = {
|
||||||
|
.aspect = GPU_IMAGE_ASPECT_COLOR,
|
||||||
|
.level_count = 1,
|
||||||
|
.layer_count = 1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
barrier_req = (GpuCmdPipelineBarrierRequest){
|
||||||
|
.command_buffer = cb,
|
||||||
|
.info = (GpuDependencyInfo){
|
||||||
|
.image_memory_barriers = wpArray(GpuImageMemoryBarrier, image_barrier),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
gpuCmdPipelineBarrier(temp, barrier_req);
|
||||||
|
|
||||||
|
gpuEndCommandBuffer(cb);
|
||||||
|
|
||||||
|
GpuFence *fence = gpuCreateFence(allocator, device);
|
||||||
|
|
||||||
|
GpuResetFencesRequest reset_req = {
|
||||||
|
.device = device,
|
||||||
|
.fences = wpArray(GpuFence *, fence)
|
||||||
|
};
|
||||||
|
gpuResetFences(temp, reset_req);
|
||||||
|
|
||||||
|
GpuCommandBuffersSubmitRequest submit_req = {
|
||||||
|
.device = device,
|
||||||
|
.command_buffers = cbs,
|
||||||
|
.fence = fence,
|
||||||
|
};
|
||||||
|
gpuSubmitCommandBuffers(temp, submit_req);
|
||||||
|
|
||||||
|
GpuWaitForFencesRequest wait_req = {
|
||||||
|
.device = device,
|
||||||
|
.fences = wpArray(GpuFence *, fence),
|
||||||
|
.timeout = UINT64_MAX,
|
||||||
|
};
|
||||||
|
gpuWaitForFences(temp, wait_req);
|
||||||
|
|
||||||
|
gpuDestroyFence(fence);
|
||||||
|
gpuDestroyBuffer(&temp_storage);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2193,6 +2303,35 @@ void gpuCmdDispatchBase(GpuCmdDispatchBaseRequest request) {
|
|||||||
request.group_count_z);
|
request.group_count_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gpuCmdCopyBufferToImage(const WpAllocator *temp, GpuCmdCopyBufferToImageRequest request) {
|
||||||
|
u64 region_count = wpArrayCount(request.copy_regions);
|
||||||
|
VkBufferImageCopyArray copy_regions = wpArrayAllocCapacity(VkBufferImageCopy, temp, region_count,
|
||||||
|
WP_ARRAY_INIT_FILLED);
|
||||||
|
assertWithLogger(copy_regions != NULL, &logger, "Failed to allocate temp copy buffer to image arrays");
|
||||||
|
|
||||||
|
for (u64 i = 0; i < region_count; ++i) {
|
||||||
|
copy_regions[i] = (VkBufferImageCopy){
|
||||||
|
.bufferOffset = request.copy_regions[i].buffer_offset,
|
||||||
|
.imageSubresource = (VkImageSubresourceLayers){
|
||||||
|
.aspectMask = vkImageAspectFromGpuImageAspect(request.copy_regions[i].image_subresource.aspect_mask),
|
||||||
|
.baseArrayLayer = request.copy_regions[i].image_subresource.base_array_layer,
|
||||||
|
.layerCount = request.copy_regions[i].image_subresource.layer_count,
|
||||||
|
.mipLevel = request.copy_regions[i].image_subresource.mip_level,
|
||||||
|
},
|
||||||
|
.imageOffset = (VkOffset3D){ .x = request.copy_regions[i].image_offset.x,
|
||||||
|
.y = request.copy_regions[i].image_offset.y,
|
||||||
|
.z = request.copy_regions[i].image_offset.z },
|
||||||
|
.imageExtent = (VkExtent3D){ .width = request.copy_regions[i].image_extent.width,
|
||||||
|
.height = request.copy_regions[i].image_extent.height,
|
||||||
|
.depth = request.copy_regions[i].image_extent.depth },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(request.command_buffer->vk_buffer, request.src_buffer->internal->vk_buffer,
|
||||||
|
request.dst_image->vk_image, vkImageLayoutFromGpuImageLayout(request.dst_image_layout),
|
||||||
|
wpArrayCount(copy_regions), copy_regions);
|
||||||
|
}
|
||||||
|
|
||||||
wp_intern VkExtensions getInstanceExtensions(void) {
|
wp_intern VkExtensions getInstanceExtensions(void) {
|
||||||
Config config = configGet();
|
Config config = configGet();
|
||||||
VkExtensions output = {0};
|
VkExtensions output = {0};
|
||||||
|
|||||||
+6
-6
@@ -165,11 +165,11 @@ i32 main(void) {
|
|||||||
|
|
||||||
wpFileRead(code, spirv, code_size);
|
wpFileRead(code, spirv, code_size);
|
||||||
|
|
||||||
// GpuLoadImageFromFileRequest load_img_req = {
|
GpuLoadImageFromFileRequest load_img_req = {
|
||||||
// .command_pool = pool,
|
.command_pool = pool,
|
||||||
// .filename = wpStr8LitRo("assets/collections.png"),
|
.filename = wpStr8LitRo("assets/collections.png"),
|
||||||
// };
|
};
|
||||||
// GpuImage *texture = gpuLoadImageFromFile(&arena, &temp_arena, load_img_req);
|
GpuImage *texture = gpuLoadImageFromFile(&arena, &temp_arena, load_img_req);
|
||||||
|
|
||||||
GpuShaderCreateRequest shader_request = {
|
GpuShaderCreateRequest shader_request = {
|
||||||
.device = device,
|
.device = device,
|
||||||
@@ -626,7 +626,7 @@ i32 main(void) {
|
|||||||
gpuDestroyDescriptorPool(desc_pool);
|
gpuDestroyDescriptorPool(desc_pool);
|
||||||
gpuDestroyBuffer(&shader_data);
|
gpuDestroyBuffer(&shader_data);
|
||||||
gpuDestroyShader(shader);
|
gpuDestroyShader(shader);
|
||||||
// gpuDestroyImage(texture);
|
gpuDestroyImage(texture);
|
||||||
gpuDestroyCommandPool(pool);
|
gpuDestroyCommandPool(pool);
|
||||||
gpuDestroyBuffer(&vert_idx_buffer);
|
gpuDestroyBuffer(&vert_idx_buffer);
|
||||||
gpuDestroySwapchain(swapchain);
|
gpuDestroySwapchain(swapchain);
|
||||||
|
|||||||
Reference in new issue
Block a user