[vulkan] Add a function to update texture contents

It works on only one layer and one mip, and assumes the provided texture
data is compatible with the image, but does support sub-image updates
(x, y location as parameters, width and height in the texture data).
This commit is contained in:
Bill Currie 2022-11-15 09:18:26 +09:00
parent 8fa6167a57
commit 251e47f4d6
2 changed files with 51 additions and 0 deletions

View file

@ -26,6 +26,8 @@ qfv_tex_t *Vulkan_LoadEnvMap (struct vulkan_ctx_s *ctx, tex_t *tex,
qfv_tex_t *Vulkan_LoadEnvSides (struct vulkan_ctx_s *ctx, tex_t **tex, qfv_tex_t *Vulkan_LoadEnvSides (struct vulkan_ctx_s *ctx, tex_t **tex,
const char *name); const char *name);
VkImageView Vulkan_TexImageView (qfv_tex_t *tex) __attribute__((pure)); VkImageView Vulkan_TexImageView (qfv_tex_t *tex) __attribute__((pure));
void Vulkan_UpdateTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex, tex_t *src,
int x, int y, int layer, int mip);
void Vulkan_UnloadTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex); void Vulkan_UnloadTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex);
void Vulkan_Texture_Init (struct vulkan_ctx_s *ctx); void Vulkan_Texture_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Texture_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_Texture_Shutdown (struct vulkan_ctx_s *ctx);

View file

@ -410,6 +410,55 @@ Vulkan_TexImageView (qfv_tex_t *tex)
return tex->view; return tex->view;
} }
void
Vulkan_UpdateTex (vulkan_ctx_t *ctx, qfv_tex_t *tex, tex_t *src,
int x, int y, int layer, int mip)
{
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
int bpp;
VkFormat format;
if (!tex_format (src, &format, &bpp)) {
return;
}
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging);
qfv_imagebarrier_t ib = imageBarriers[qfv_LT_ShaderReadOnly_to_TransferDst];
ib.barrier.image = tex->image;
dfunc->vkCmdPipelineBarrier (packet->cmd, ib.srcStages, ib.dstStages,
0, 0, 0, 0, 0,
1, &ib.barrier);
VkBufferImageCopy copy = {
.bufferOffset = stage_tex_data (packet, src, bpp),
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = mip,
.baseArrayLayer = layer,
.layerCount = 1,
},
.imageOffset = { .x = x, .y = y, .z = 0 },
.imageExtent = {
.width = src->width,
.height = src->height,
.depth = 1,
},
};
dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer,
tex->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copy);
ib = imageBarriers[qfv_LT_TransferDst_to_ShaderReadOnly];
ib.barrier.image = tex->image;
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);
QFV_PacketSubmit (packet);
}
void void
Vulkan_UnloadTex (vulkan_ctx_t *ctx, qfv_tex_t *tex) Vulkan_UnloadTex (vulkan_ctx_t *ctx, qfv_tex_t *tex)
{ {