mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-12 19:06:09 -10:00
Name vulkan_preload's is_aabitmap parameter. The previous commit reads it but left the name commented out, so Vulkan builds failed. The sibling-frame change matters for EFF animations of 8-bit PCX frames, not ANI: ANI and APNG decode every frame in the triggering lock. Say so, and name why other 8bpp sources are safe to treat as AABITMAP. Log the chosen format for AABITMAP preloads and let them bypass the log cap, so a playtest can confirm R8 for HUD handles. Co-Authored-By: Claude Opus 5.5 <[email protected]>
185 lines
4.9 KiB
C++
185 lines
4.9 KiB
C++
#include "VulkanTexture.h"
|
|
|
|
#include <algorithm>
|
|
#include "VulkanBuffer.h"
|
|
#include "VulkanDeletionQueue.h"
|
|
#include "VulkanRenderer.h"
|
|
#include "gr_vulkan.h"
|
|
|
|
#include "graphics/util/pixel_swizzle.h"
|
|
#include "bmpman/bmpman.h"
|
|
#include "ddsutils/ddsutils.h"
|
|
#include "ddsutils/bcdec.h"
|
|
#include "globalincs/systemvars.h"
|
|
#include "ktxutils/ktxutils.h"
|
|
|
|
namespace graphics::vulkan {
|
|
|
|
// ========== gr_screen function pointer implementations ==========
|
|
|
|
int vulkan_preload(int bitmap_num, int is_aabitmap)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
|
|
// Check if texture is already loaded
|
|
auto* slot = texManager->getTextureSlot(bitmap_num);
|
|
if (slot && slot->imageView) {
|
|
return 1; // Already loaded
|
|
}
|
|
|
|
// Determine lock parameters based on compression type.
|
|
// For compressed DDS/KTX textures, lock with the matching DXT/BC7/ETC2
|
|
// flags to get raw compressed data with all pre-baked mipmap levels.
|
|
int compType = bm_is_compressed(bitmap_num);
|
|
int lockBpp = 32;
|
|
uint lockFlags = BMP_TEX_XPARENT;
|
|
|
|
switch (compType) {
|
|
case DDS_DXT1:
|
|
lockBpp = 24;
|
|
lockFlags = BMP_TEX_DXT1;
|
|
break;
|
|
case DDS_DXT3:
|
|
lockBpp = 32;
|
|
lockFlags = BMP_TEX_DXT3;
|
|
break;
|
|
case DDS_DXT5:
|
|
lockBpp = 32;
|
|
lockFlags = BMP_TEX_DXT5;
|
|
break;
|
|
case DDS_BC7:
|
|
lockBpp = 32;
|
|
lockFlags = BMP_TEX_BC7;
|
|
break;
|
|
case DDS_CUBEMAP_DXT1:
|
|
lockBpp = 24;
|
|
lockFlags = BMP_TEX_CUBEMAP;
|
|
break;
|
|
case DDS_CUBEMAP_DXT3:
|
|
case DDS_CUBEMAP_DXT5:
|
|
lockBpp = 32;
|
|
lockFlags = BMP_TEX_CUBEMAP;
|
|
break;
|
|
case KTX_ETC2_RGB:
|
|
case KTX_ETC2_SRGB:
|
|
lockBpp = 24;
|
|
lockFlags = BMP_TEX_ETC2_RGB8;
|
|
break;
|
|
case KTX_ETC2_RGBA_EAC:
|
|
case KTX_ETC2_SRGBA_EAC:
|
|
lockBpp = 32;
|
|
lockFlags = BMP_TEX_ETC2_RGBA8;
|
|
break;
|
|
case KTX_ETC2_RGB_A1:
|
|
case KTX_ETC2_SRGB_A1:
|
|
lockBpp = 24;
|
|
lockFlags = BMP_TEX_ETC2_RGBA1;
|
|
break;
|
|
default:
|
|
// AABITMAP art is a palette-index mask. Keep the indices as R8 so
|
|
// the HUD shader can use them as coverage instead of RGB color data,
|
|
// matching the draw-time AABITMAP lock in bindMaterialTextures.
|
|
compType = 0;
|
|
if (is_aabitmap) {
|
|
lockBpp = 8;
|
|
lockFlags = BMP_AABITMAP;
|
|
}
|
|
break;
|
|
}
|
|
|
|
bitmap* bmp = bm_lock(bitmap_num, static_cast<ubyte>(lockBpp), lockFlags);
|
|
if (!bmp) {
|
|
static int warnCount = 0;
|
|
if (warnCount < 10) {
|
|
nprintf(("vulkan", "vulkan_preload: Failed to lock bitmap %d (compType=%d)\n", bitmap_num, compType));
|
|
warnCount++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Upload the texture
|
|
bool success = texManager->bm_data(bitmap_num, bmp, compType);
|
|
|
|
// Unlock bitmap
|
|
bm_unlock(bitmap_num);
|
|
|
|
if (success) {
|
|
static int successCount = 0;
|
|
// AABITMAP uploads bypass the cap so a playtest can confirm R8 for HUD handles,
|
|
// which page in long after the first few textures.
|
|
if (successCount < 10 || is_aabitmap) {
|
|
auto* uploaded = texManager->getTextureSlot(bitmap_num);
|
|
nprintf(("vulkan", "vulkan_preload: Successfully uploaded texture %d (compressed=%d, aabitmap=%d, format=%s)\n",
|
|
bitmap_num, compType, is_aabitmap,
|
|
uploaded ? vk::to_string(uploaded->format).c_str() : "none"));
|
|
successCount++;
|
|
}
|
|
}
|
|
|
|
return success ? 1 : 0;
|
|
}
|
|
|
|
void vulkan_bm_create(bitmap_slot* slot)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
texManager->bm_create(slot);
|
|
}
|
|
|
|
void vulkan_bm_free_data(bitmap_slot* slot, bool release)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
texManager->bm_free_data(slot, release);
|
|
}
|
|
|
|
void vulkan_bm_init(bitmap_slot* slot)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
texManager->bm_init(slot);
|
|
}
|
|
|
|
bool vulkan_bm_data(int handle, bitmap* bm)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
int compType = bm_is_compressed(handle);
|
|
return texManager->bm_data(handle, bm, compType);
|
|
}
|
|
|
|
void vulkan_bm_page_in_start()
|
|
{
|
|
// Flush all GPU texture resources so that textures not needed in the next
|
|
// mission are freed. Matches the OpenGL pattern (opengl_tcache_flush in
|
|
// opengl_preload_init, currently commented out there). Textures that ARE
|
|
// needed will be re-uploaded on demand during level load / first use.
|
|
// Without this, Vulkan VkImage/VMA allocations accumulate across missions
|
|
// because bm_unload_fast() only frees CPU-side pixel data.
|
|
auto* texManager = getTextureManager();
|
|
texManager->flushTextures();
|
|
}
|
|
|
|
int vulkan_bm_make_render_target(int handle, int* width, int* height, int* bpp, int* mm_lvl, int flags)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
return texManager->bm_make_render_target(handle, width, height, bpp, mm_lvl, flags);
|
|
}
|
|
|
|
int vulkan_bm_set_render_target(int handle, int face)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
return texManager->bm_set_render_target(handle, face);
|
|
}
|
|
|
|
void vulkan_update_texture(int bitmap_handle, int bpp, const ubyte* data, int width, int height)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
texManager->update_texture(bitmap_handle, bpp, data, width, height);
|
|
}
|
|
|
|
ubyte* vulkan_get_bitmap_from_texture(const int bitmap_num, int* width_out, int* height_out)
|
|
{
|
|
auto* texManager = getTextureManager();
|
|
return texManager->get_bitmap_from_texture(bitmap_num, width_out, height_out);
|
|
}
|
|
|
|
} // namespace graphics::vulkan
|
|
|