unifica shader compile script com a compile_spirv.cmake i regenera headers

This commit is contained in:
2026-05-14 17:39:50 +02:00
parent 118626dff6
commit 2282377ae7
8 changed files with 141 additions and 105 deletions
-61
View File
@@ -1,61 +0,0 @@
# compile_shader.cmake
# Compila un shader GLSL a header C++ embebible con datos SPIR-V.
# Funciona en Windows, Linux y macOS sin bash ni herramientas Unix.
#
# Variables requeridas (pasar con -D al invocar cmake -P):
# GLSLC - ruta al ejecutable glslc
# SRC - archivo fuente GLSL
# OUT_H - archivo header de salida
# VAR - nombre base de la variable C++ (e.g. "postfx_vert_spv")
# STAGE - (opcional) stage explícito para glslc (e.g. "fragment")
cmake_minimum_required(VERSION 3.10)
# Nom intermedi únic per stage (vert/frag/comp) per evitar col·lisions en
# builds paral·lels: postfx.vert i postfx.frag generarien el mateix
# `postfx.spv` si féssim servir el nom del SRC. Usem el del OUT_H, que ja
# inclou el stage (p.ex. `postfx_frag_spv.h` → `postfx_frag_spv.spv`).
get_filename_component(OUT_DIR "${OUT_H}" DIRECTORY)
get_filename_component(OUT_NAME "${OUT_H}" NAME_WE)
set(OUT_SPV "${OUT_DIR}/${OUT_NAME}.spv")
# Compilar GLSL → SPIR-V
if(DEFINED STAGE AND NOT STAGE STREQUAL "")
execute_process(
COMMAND "${GLSLC}" "-fshader-stage=${STAGE}" "${SRC}" -o "${OUT_SPV}"
RESULT_VARIABLE RESULT
ERROR_VARIABLE ERROR_MSG
)
else()
execute_process(
COMMAND "${GLSLC}" "${SRC}" -o "${OUT_SPV}"
RESULT_VARIABLE RESULT
ERROR_VARIABLE ERROR_MSG
)
endif()
if(NOT RESULT EQUAL 0)
message(FATAL_ERROR "glslc falló compilando ${SRC}:\n${ERROR_MSG}")
endif()
# Leer binario SPIR-V como cadena hexadecimal
file(READ "${OUT_SPV}" SPV_HEX HEX)
file(REMOVE "${OUT_SPV}")
string(LENGTH "${SPV_HEX}" HEX_LEN)
math(EXPR BYTE_COUNT "${HEX_LEN} / 2")
# Convertir a array C++ con formato " 0xXX,\n" por byte
string(REGEX REPLACE "([0-9a-f][0-9a-f])" " 0x\\1,\n" SPV_BYTES "${SPV_HEX}")
# Eliminar la última coma y sustituir por el "}" de cierre
string(REGEX REPLACE ",\n$" "}" SPV_BYTES "${SPV_BYTES}")
# Escribir el header
file(WRITE "${OUT_H}"
"#pragma once\n"
"#include <cstddef>\n"
"#include <cstdint>\n"
"static const uint8_t k${VAR}[] = {\n"
"${SPV_BYTES};\n"
"static const size_t k${VAR}_size = ${BYTE_COUNT};\n"
)
+101
View File
@@ -0,0 +1,101 @@
# compile_spirv.cmake
# Compila shaders GLSL a SPIR-V y genera headers C++ embebibles.
# Multiplataforma: Windows, macOS, Linux (no requiere bash, xxd ni /tmp/).
#
# Invocado por CMakeLists.txt con:
# cmake -D GLSLC=<path> -D SHADERS_DIR=<path> -D HEADERS_DIR=<path> -P compile_spirv.cmake
#
# También puede ejecutarse manualmente desde la raíz del proyecto:
# cmake -D GLSLC=glslc -D SHADERS_DIR=data/shaders -D HEADERS_DIR=source/core/rendering/sdl3gpu -P tools/shaders/compile_spirv.cmake
cmake_minimum_required(VERSION 3.10)
cmake_policy(SET CMP0007 NEW)
# Lista de shaders: fuente relativa a SHADERS_DIR
set(SHADER_SOURCES
"postfx.vert"
"postfx.frag"
"upscale.frag"
"downscale.frag"
"crtpi_frag.glsl"
)
# Nombre de la variable C++ para cada shader (mismo orden)
set(SHADER_VARS
"kpostfx_vert_spv"
"kpostfx_frag_spv"
"kupscale_frag_spv"
"kdownscale_frag_spv"
"kcrtpi_frag_spv"
)
# Flags extra de glslc para cada shader (vacío si no hay)
set(SHADER_FLAGS
""
""
""
""
"-fshader-stage=frag"
)
list(LENGTH SHADER_SOURCES NUM_SHADERS)
math(EXPR LAST_IDX "${NUM_SHADERS} - 1")
foreach(IDX RANGE ${LAST_IDX})
list(GET SHADER_SOURCES ${IDX} SRC_NAME)
list(GET SHADER_VARS ${IDX} VAR)
list(GET SHADER_FLAGS ${IDX} EXTRA_FLAG)
# Derivar nombre del header desde la variable: kpostfx_vert_spv → postfx_vert_spv.h
string(REGEX REPLACE "^k" "" HDR_BASE "${VAR}")
set(SRC "${SHADERS_DIR}/${SRC_NAME}")
set(SPV "${HEADERS_DIR}/${HDR_BASE}.spv")
set(HDR "${HEADERS_DIR}/${HDR_BASE}.h")
message(STATUS "Compilando ${SRC} ...")
if(EXTRA_FLAG)
execute_process(
COMMAND "${GLSLC}" "${EXTRA_FLAG}" "${SRC}" -o "${SPV}"
RESULT_VARIABLE GLSLC_RESULT
ERROR_VARIABLE GLSLC_ERROR
)
else()
execute_process(
COMMAND "${GLSLC}" "${SRC}" -o "${SPV}"
RESULT_VARIABLE GLSLC_RESULT
ERROR_VARIABLE GLSLC_ERROR
)
endif()
if(NOT GLSLC_RESULT EQUAL 0)
message(FATAL_ERROR "glslc falló para ${SRC}:\n${GLSLC_ERROR}")
endif()
# Leer binario SPV como hex (sin separadores: "0302230700...")
file(READ "${SPV}" HEX_DATA HEX)
# Dividir en pares de caracteres hex → lista de bytes
string(REGEX MATCHALL ".." BYTES "${HEX_DATA}")
list(LENGTH BYTES NUM_BYTES)
# Construir el cuerpo del array C++ con un byte por línea
set(ARRAY_BODY "")
foreach(BYTE ${BYTES})
string(APPEND ARRAY_BODY " 0x${BYTE},\n")
endforeach()
file(WRITE "${HDR}"
"#pragma once\n"
"#include <cstddef>\n"
"#include <cstdint>\n"
"static const uint8_t ${VAR}[] = {\n"
"${ARRAY_BODY}"
"};\n"
"static const size_t ${VAR}_size = ${NUM_BYTES};\n"
)
file(REMOVE "${SPV}")
message(STATUS " -> ${HDR} (${NUM_BYTES} bytes)")
endforeach()
message(STATUS "Shaders SPIR-V compilados correctamente.")