The device's textureCompressionBC is asked for and remembered (gvk_has_bc). tex_load_ex prefers a DX10 .dds with the full chain beside the .png (not for an edge-padded cut-out atlas): texture_dds.ludic reads BC7 / BC5 / BC4, gpu_tex_compressed makes the image with every level and no colour-attachment use (a compressed image is only sampled and copied into), and gvk_tex_upload_blocks copies each level's blocks from one staging buffer. A colour map is BC7 sampled as sRGB, a data map BC7 read as it is. examples/rendering/bc.ludic holds it, in the suite; ludic.lab's plate carries its .dds (its three shots render at 56-60 dB against the .png's). ludic-dev test 307/307, no Vulkan SDK in the environment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 lines
2 KiB
Text
31 lines
2 KiB
Text
# gpu_vk_bc.ludic - a block-compressed texture's levels uploaded as they are: the GPU decodes BC
|
|
# blocks itself, so the bytes in the file are the bytes in video memory, a quarter of RGBA8's.
|
|
|
|
# every level of `tex` (made by gvk_tex_storage with its whole chain) from `data`, level l's
|
|
# blocks at offs[l] .. offs[l + 1]
|
|
function gvk_tex_upload_blocks(render3d_st: mut Render3dState, tex: int, w: int, h: int, levels: int, data: pointer, offs: words) -> bool {
|
|
let n = offs[levels]
|
|
let dst = gvk_staging(render3d_st, n, VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
|
|
if dst == null { print("r3d: vulkan: no staging buffer for a compressed upload"); return false }
|
|
mem_copy(dst, data, n)
|
|
let image = render3d_st.gvk_tex_image[tex]
|
|
let cb = gvk_once_begin(render3d_st)
|
|
gvk_barrier(render3d_st, cb, image, false, 0, levels, 1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
|
for l in 0 .. levels {
|
|
let bic = gvk_tmp(render3d_st, VkBufferImageCopy_sizeof)
|
|
Vk.zero(bic, VkBufferImageCopy_sizeof)
|
|
let off: long = offs[l]
|
|
Vk.put_i64(bic, VkBufferImageCopy_bufferOffset, off)
|
|
Vk.put_i32(bic, VkBufferImageCopy_imageSubresource + VkImageSubresourceLayers_aspectMask, VK_IMAGE_ASPECT_COLOR_BIT)
|
|
Vk.put_i32(bic, VkBufferImageCopy_imageSubresource + VkImageSubresourceLayers_mipLevel, l)
|
|
Vk.put_i32(bic, VkBufferImageCopy_imageSubresource + VkImageSubresourceLayers_layerCount, 1)
|
|
Vk.put_i32(bic, VkBufferImageCopy_imageExtent + VkExtent3D_width, max(w >> l, 1))
|
|
Vk.put_i32(bic, VkBufferImageCopy_imageExtent + VkExtent3D_height, max(h >> l, 1))
|
|
Vk.put_i32(bic, VkBufferImageCopy_imageExtent + VkExtent3D_depth, 1)
|
|
Vk.cmd_copy_buffer_to_image(cb, render3d_st.gvk_st_buf, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, bic)
|
|
}
|
|
gvk_barrier(render3d_st, cb, image, false, 0, levels, 1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
|
let ok = gvk_once_end(render3d_st, cb)
|
|
gvk_staging_free(render3d_st)
|
|
return ok
|
|
}
|