From 2e21ca4b9a6e07f977c7a36fa584f34c403093a5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2022 09:26:17 +0900 Subject: [PATCH] [vulkan] Upload palette as a 16x16 image It turns out my approach to alias skin coloring just doesn't work for the quake data due to the color curves not having a linear relationship, especially the bottom colors. --- include/QF/Makemodule.am | 1 + include/QF/Vulkan/qf_palette.h | 49 +++++++++++ include/vid_vulkan.h | 1 + libs/video/renderer/Makemodule.am | 1 + libs/video/renderer/vid_render_vulkan.c | 9 +- libs/video/renderer/vulkan/qfpipeline.plist | 17 ++++ libs/video/renderer/vulkan/vulkan_palette.c | 96 +++++++++++++++++++++ 7 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 include/QF/Vulkan/qf_palette.h create mode 100644 libs/video/renderer/vulkan/vulkan_palette.c diff --git a/include/QF/Makemodule.am b/include/QF/Makemodule.am index 36ddd9f6f..0512d7a13 100644 --- a/include/QF/Makemodule.am +++ b/include/QF/Makemodule.am @@ -199,6 +199,7 @@ include_qf_vulkan = \ include/QF/Vulkan/qf_main.h \ include/QF/Vulkan/qf_matrices.h \ include/QF/Vulkan/qf_model.h \ + include/QF/Vulkan/qf_palette.h \ include/QF/Vulkan/qf_particles.h \ include/QF/Vulkan/qf_renderpass.h \ include/QF/Vulkan/qf_scene.h \ diff --git a/include/QF/Vulkan/qf_palette.h b/include/QF/Vulkan/qf_palette.h new file mode 100644 index 000000000..a6cd01387 --- /dev/null +++ b/include/QF/Vulkan/qf_palette.h @@ -0,0 +1,49 @@ +/* + qf_palette.h + + Vulkan matrix "pass" + + Copyright (C) 2021 Bill Currie + + Author: Bill Currie + Date: 2021/12/8 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifndef __QF_Vulkan_qf_palette_h +#define __QF_Vulkan_qf_palette_h + +#include "QF/darray.h" +#include "QF/Vulkan/qf_vid.h" +#include "QF/Vulkan/command.h" +#include "QF/Vulkan/image.h" + +typedef struct palettectx_s { + struct qfv_tex_s *palette; + VkSampler sampler; +} palettectx_t; + +struct vulkan_ctx_s; + +void Vulkan_Palette_Update (struct vulkan_ctx_s *ctx, const byte *palette); +void Vulkan_Palette_Init (struct vulkan_ctx_s *ctx, const byte *palette); +void Vulkan_Palette_Shutdown (struct vulkan_ctx_s *ctx); + +#endif//__QF_Vulkan_qf_palette_h diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index cd714d093..b3ecf0a60 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -70,6 +70,7 @@ typedef struct vulkan_ctx_s { struct bspctx_s *bsp_context; struct iqmctx_s *iqm_context; struct scenectx_s *scene_context; + struct palettectx_s *palette_context; struct particlectx_s *particle_context; struct spritectx_s *sprite_context; struct drawctx_s *draw_context; diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index bec2f52d3..0eea5d10b 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -243,6 +243,7 @@ libs_video_renderer_librender_vulkan_la_SOURCES = \ libs/video/renderer/vulkan/vulkan_lighting.c \ libs/video/renderer/vulkan/vulkan_main.c \ libs/video/renderer/vulkan/vulkan_matrices.c \ + libs/video/renderer/vulkan/vulkan_palette.c \ libs/video/renderer/vulkan/vulkan_particles.c \ libs/video/renderer/vulkan/vulkan_renderpass.c \ libs/video/renderer/vulkan/vulkan_scene.c \ diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 2683a48e4..4a614498a 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -50,6 +50,7 @@ #include "QF/Vulkan/qf_lightmap.h" #include "QF/Vulkan/qf_main.h" #include "QF/Vulkan/qf_matrices.h" +#include "QF/Vulkan/qf_palette.h" #include "QF/Vulkan/qf_particles.h" #include "QF/Vulkan/qf_renderpass.h" #include "QF/Vulkan/qf_scene.h" @@ -89,6 +90,7 @@ vulkan_R_Init (void) Vulkan_CreateStagingBuffers (vulkan_ctx); Vulkan_CreateFrames (vulkan_ctx); Vulkan_Texture_Init (vulkan_ctx); + Vulkan_Palette_Init (vulkan_ctx, vid.palette); Vulkan_CreateSwapchain (vulkan_ctx); Vulkan_CreateCapture (vulkan_ctx); @@ -669,9 +671,9 @@ vulkan_Skin_InitTranslations (void) static void set_palette (void *data, const byte *palette) { - //FIXME really don't want this here: need an application domain - //so Quake can be separated from QuakeForge (ie, Quake itself becomes - //an app using the QuakeForge engine) + if (vulkan_ctx->palette_context) { + Vulkan_Palette_Update (vulkan_ctx, palette); + } } static void @@ -774,6 +776,7 @@ vulkan_vid_render_shutdown (void) Vulkan_Scene_Shutdown (vulkan_ctx); Vulkan_Matrix_Shutdown (vulkan_ctx); + Vulkan_Palette_Shutdown (vulkan_ctx); Vulkan_Texture_Shutdown (vulkan_ctx); Vulkan_DestroyRenderPasses (vulkan_ctx); diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 1046818e0..02a54335c 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -23,6 +23,23 @@ borderColor = float_transparent_black; unnormalizedCoordinates = false; }; + palette_sampler = { + magFilter = nearest; + minFilter = nearest; + mipmapMode = nearest; + addressModeU = clamp_to_edge; + addressModeV = clamp_to_edge; + addressModeW = clamp_to_edge; + mipLodBias = 0; + anisotropyEnable = false; + maxAnisotropy = 0; + compareEnable = false; + compareOp = always; + minLod = 0; + maxLod = 4; + borderColor = float_transparent_black; + unnormalizedCoordinates = false; + }; quakebsp_sampler = { magFilter = linear; minFilter = linear; diff --git a/libs/video/renderer/vulkan/vulkan_palette.c b/libs/video/renderer/vulkan/vulkan_palette.c new file mode 100644 index 000000000..ac1c17b59 --- /dev/null +++ b/libs/video/renderer/vulkan/vulkan_palette.c @@ -0,0 +1,96 @@ +/* + vulkan_palette.c + + Vulkan palette image + + Copyright (C) 2022 Bill Currie + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#ifdef HAVE_MATH_H +# include +#endif + +#include "QF/sys.h" +#include "QF/va.h" +#include "QF/Vulkan/instance.h" +#include "QF/Vulkan/qf_palette.h" +#include "QF/Vulkan/qf_texture.h" + +#include "vid_vulkan.h" + +void +Vulkan_Palette_Update (vulkan_ctx_t *ctx, const byte *palette) +{ + palettectx_t *pctx = ctx->palette_context; + tex_t tex = { + .width = 16, + .height = 16, + .format = tex_rgb, + .loaded = 1, + .data = (byte *) palette, + }; + Vulkan_UpdateTex (ctx, pctx->palette, &tex, 0, 0, 0, 0); +} + +void +Vulkan_Palette_Init (vulkan_ctx_t *ctx, const byte *palette) +{ + qfvPushDebug (ctx, "palette init"); + + palettectx_t *pctx = calloc (1, sizeof (palettectx_t)); + ctx->palette_context = pctx; + + pctx->sampler = Vulkan_CreateSampler (ctx, "palette_sampler"); + tex_t tex = { + .width = 16, + .height = 16, + .format = tex_rgb, + .loaded = 1, + .data = (byte *) palette, + }; + pctx->palette = Vulkan_LoadTex (ctx, &tex, 0, "palette"); + + qfvPopDebug (ctx); +} + +void +Vulkan_Palette_Shutdown (vulkan_ctx_t *ctx) +{ + qfvPushDebug (ctx, "palette shutdown"); + + __auto_type pctx = ctx->palette_context; + + Vulkan_UnloadTex (ctx, pctx->palette); + free (pctx); + + qfvPopDebug (ctx); +}