mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[vulkan] Add a couple of staging helper functions
I got tired of writing the same 13 or so lines of code over and over (it actually put me off experimenting with Vulkan). Thus... QFV_PacketCopyBuffer does the work of handling barriers and a (full packet) copy from the staging buffer to a GPU buffer. QFV_PacketCopyImage does a similar job, but for images. However, it still needs a lot of work, but it does make getting a basic texture onto the GPU much less of a hassle. Both functions should make staging data much less error-prone.
This commit is contained in:
parent
51b73eee73
commit
c028e15943
3 changed files with 61 additions and 2 deletions
|
@ -6,13 +6,13 @@
|
||||||
#endif
|
#endif
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct qfv_imagebarrier_s {
|
||||||
VkPipelineStageFlags srcStages;
|
VkPipelineStageFlags srcStages;
|
||||||
VkPipelineStageFlags dstStages;
|
VkPipelineStageFlags dstStages;
|
||||||
VkImageMemoryBarrier barrier;
|
VkImageMemoryBarrier barrier;
|
||||||
} qfv_imagebarrier_t;
|
} qfv_imagebarrier_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct qfv_bufferbarrier_s {
|
||||||
VkPipelineStageFlags srcStages;
|
VkPipelineStageFlags srcStages;
|
||||||
VkPipelineStageFlags dstStages;
|
VkPipelineStageFlags dstStages;
|
||||||
VkBufferMemoryBarrier barrier;
|
VkBufferMemoryBarrier barrier;
|
||||||
|
|
|
@ -34,5 +34,12 @@ void QFV_FlushStagingBuffer (qfv_stagebuf_t *stage, size_t offset, size_t size);
|
||||||
qfv_packet_t *QFV_PacketAcquire (qfv_stagebuf_t *stage);
|
qfv_packet_t *QFV_PacketAcquire (qfv_stagebuf_t *stage);
|
||||||
void *QFV_PacketExtend (qfv_packet_t *packet, size_t size);
|
void *QFV_PacketExtend (qfv_packet_t *packet, size_t size);
|
||||||
void QFV_PacketSubmit (qfv_packet_t *packet);
|
void QFV_PacketSubmit (qfv_packet_t *packet);
|
||||||
|
struct qfv_bufferbarrier_s;
|
||||||
|
void QFV_PacketCopyBuffer (qfv_packet_t *packet, VkBuffer dstBuffer,
|
||||||
|
const struct qfv_bufferbarrier_s *dstBarrier);
|
||||||
|
struct qfv_imagebarrier_s;
|
||||||
|
void QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage,
|
||||||
|
int width, int height,
|
||||||
|
const struct qfv_imagebarrier_s *dstBarrier);
|
||||||
|
|
||||||
#endif//__QF_Vulkan_staging_h
|
#endif//__QF_Vulkan_staging_h
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
|
||||||
|
#include "QF/Vulkan/barrier.h"
|
||||||
#include "QF/Vulkan/buffer.h"
|
#include "QF/Vulkan/buffer.h"
|
||||||
#include "QF/Vulkan/command.h"
|
#include "QF/Vulkan/command.h"
|
||||||
#include "QF/Vulkan/debug.h"
|
#include "QF/Vulkan/debug.h"
|
||||||
|
@ -279,3 +280,54 @@ QFV_PacketSubmit (qfv_packet_t *packet)
|
||||||
// The fence was reset when the packet was acquired
|
// The fence was reset when the packet was acquired
|
||||||
dfunc->vkQueueSubmit (device->queue.queue, 1, &submitInfo, packet->fence);
|
dfunc->vkQueueSubmit (device->queue.queue, 1, &submitInfo, packet->fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QFV_PacketCopyBuffer (qfv_packet_t *packet, VkBuffer dstBuffer,
|
||||||
|
const qfv_bufferbarrier_t *dstBarrier)
|
||||||
|
{
|
||||||
|
qfv_devfuncs_t *dfunc = packet->stage->device->funcs;
|
||||||
|
qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
|
||||||
|
bb.barrier.buffer = dstBuffer;
|
||||||
|
bb.barrier.size = packet->length;
|
||||||
|
dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
|
||||||
|
0, 0, 0, 1, &bb.barrier, 0, 0);
|
||||||
|
VkBufferCopy copy_region = { packet->offset, 0, packet->length };
|
||||||
|
dfunc->vkCmdCopyBuffer (packet->cmd, packet->stage->buffer, dstBuffer,
|
||||||
|
1, ©_region);
|
||||||
|
bb = *dstBarrier;
|
||||||
|
bb.barrier.buffer = dstBuffer;
|
||||||
|
bb.barrier.size = packet->length;
|
||||||
|
dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
|
||||||
|
0, 0, 0, 1, &bb.barrier, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage,
|
||||||
|
int width, int height,
|
||||||
|
const qfv_imagebarrier_t *dstBarrier)
|
||||||
|
{
|
||||||
|
qfv_devfuncs_t *dfunc = packet->stage->device->funcs;
|
||||||
|
qfv_imagebarrier_t ib = imageBarriers[qfv_LT_Undefined_to_TransferDst];
|
||||||
|
ib.barrier.image = dstImage;
|
||||||
|
ib.barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
ib.barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
dfunc->vkCmdPipelineBarrier (packet->cmd, ib.srcStages, ib.dstStages,
|
||||||
|
0, 0, 0, 0, 0, 1, &ib.barrier);
|
||||||
|
VkBufferImageCopy copy_region = {
|
||||||
|
.bufferOffset = packet->offset,
|
||||||
|
.bufferRowLength = 0,
|
||||||
|
.bufferImageHeight = 0,
|
||||||
|
.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
|
||||||
|
{0, 0, 0}, {width, height, 1},
|
||||||
|
};
|
||||||
|
dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer,
|
||||||
|
dstImage,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
1, ©_region);
|
||||||
|
ib = *dstBarrier;
|
||||||
|
ib.barrier.image = dstImage;
|
||||||
|
ib.barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
ib.barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
dfunc->vkCmdPipelineBarrier (packet->cmd, ib.srcStages, ib.dstStages,
|
||||||
|
0, 0, 0, 0, 0, 1, &ib.barrier);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue