aboutsummaryrefslogtreecommitdiff
path: root/dxg/shaders
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-02 16:39:36 -0800
committer3gg <3gg@shellblade.net>2025-12-02 16:39:36 -0800
commit6c8ae19be66cee247980a48e736a4e05d14de179 (patch)
treed860767907bf0cbe17ec66422e11bea700cf56d9 /dxg/shaders
parent8f594c8ebd11f0e5f8a0c6369c3fe7383d250cbe (diff)
Immediate-mode renderer, triangle demo, shader compilation in cmake, Agility SDKHEADmain
Diffstat (limited to 'dxg/shaders')
-rw-r--r--dxg/shaders/CMakeLists.txt98
-rw-r--r--dxg/shaders/imm.hlsl23
2 files changed, 121 insertions, 0 deletions
diff --git a/dxg/shaders/CMakeLists.txt b/dxg/shaders/CMakeLists.txt
new file mode 100644
index 0000000..c6ec687
--- /dev/null
+++ b/dxg/shaders/CMakeLists.txt
@@ -0,0 +1,98 @@
1set(SHADER_MODEL "6_5")
2set(DXC ${PROJECT_SOURCE_DIR}/../contrib/dxc_2025_07_14/bin/x64/dxc.exe)
3set(SHADERS_PATH ${CMAKE_CURRENT_SOURCE_DIR})
4set(BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
5
6# Compile HLSL to binary DXIL.
7#
8# This defines a custom command so that the shader is compiled at cmake build
9# instead of configure.
10#
11# hlsl_file: "foo.hlsl"; just the file name, not the path.
12# shader_type: "vs", "ps", "cs", etc.
13# entry_point: "main", etc.
14function(compile_shader hlsl_file shader_type entry_point dxil_file)
15 #string(REPLACE ".hlsl" ".dxil" dxil_file ${hlsl_file})
16 set(hlsl_path "${SHADERS_PATH}/${hlsl_file}")
17 set(dxil_path "${BUILD_DIR}/${dxil_file}")
18 set(target_profile "${shader_type}_${SHADER_MODEL}")
19 message("COMPILING ${dxil_path}")
20 message("DXC = ${DXC}")
21 add_custom_command(
22 OUTPUT ${dxil_path}
23 COMMAND ${DXC} -T ${target_profile} -E ${entry_point} ${hlsl_path} -Fo ${dxil_path}
24 WORKING_DIRECTORY ${BUILD_DIR}
25 DEPENDS ${hlsl_path}
26 COMMENT "Generating ${dxil_path}")
27endfunction()
28
29# Inline a binary file into C code.
30# This is a workaround for the lack of C23 #embed in MSVC.
31#
32# identifier: Identifier to use for the global array that will contain the file,
33# the generated file names, and the cmake target.
34# file_path: Path to the binary file to embed.
35#
36# Reference: https://github.com/andoalon/embed-binaries
37function(generate_c file_path identifier out_header_path out_source_path)
38 file(READ "${file_path}" file_contents HEX)
39 string(LENGTH "${file_contents}" file_contents_length)
40 math(EXPR file_bytes "${file_contents_length} / 2")
41
42 set(bytes_per_line 32)
43 string(REPEAT "[0-9a-f]" ${bytes_per_line} column_pattern)
44 string(REGEX REPLACE "(${column_pattern})" "\\1\n" code "${file_contents}")
45 string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," code "${code}")
46
47 set(declaration "const uint8_t ${identifier}[${file_bytes}]")
48
49 string(APPEND header "#pragma once\n\n#include <stdint.h>\n\nextern ${declaration}\;\n")
50 string(APPEND implementation "#include \"${identifier}.h\"\n\n${declaration} = {\n${code}}\;\n")
51
52 file(WRITE "${BUILD_DIR}/${identifier}.h" ${header})
53 file(WRITE "${BUILD_DIR}/${identifier}.c" ${implementation})
54endfunction()
55
56# Create a target that embeds the given DXIL file in a C header/source.
57# Like compile_shader, this just adds the target so that the embedding is done
58# at cmake build and not configure.
59function(create_c_target dxil_file identifier)
60 set(dxil_path "${BUILD_DIR}/${dxil_file}")
61 string(REPLACE ".dxil" ".h" header_path ${dxil_path})
62 string(REPLACE ".dxil" ".c" source_path ${dxil_path})
63 add_custom_command(
64 OUTPUT "${header_path}" "${source_path}"
65 COMMAND ${CMAKE_COMMAND} -D dxil_path=${dxil_path} -D identifier=${identifier} -D out_header_path=${header_path} -D out_source_path=${source_path} -P ${CMAKE_CURRENT_LIST_FILE}
66 WORKING_DIRECTORY ${BUILD_DIR}
67 DEPENDS ${dxil_path}
68 COMMENT "Generating ${source_path}"
69 )
70endfunction()
71
72# Running in script mode.
73# https://stackoverflow.com/questions/51427538/cmake-test-if-i-am-in-scripting-mode
74#
75# When running in script mode, we embed the binary DXIL into a generated C file.
76if(CMAKE_SCRIPT_MODE_FILE AND NOT CMAKE_PARENT_LIST_FILE)
77 foreach(variable "dxil_path" "identifier" "out_header_path" "out_source_path")
78 if (NOT DEFINED ${variable})
79 message(FATAL_ERROR "'${variable}' is not defined")
80 endif()
81 endforeach()
82 generate_c("${dxil_path}" ${identifier} "${out_header_path}" "${out_source_path}")
83else()
84 compile_shader("imm.hlsl" "vs" "vs" "imm_vs.dxil")
85 compile_shader("imm.hlsl" "ps" "ps" "imm_ps.dxil")
86
87 create_c_target("imm_vs.dxil" "imm_vs")
88 create_c_target("imm_ps.dxil" "imm_ps")
89
90 add_library(shaders
91 "${BUILD_DIR}/imm_ps.c"
92 "${BUILD_DIR}/imm_ps.h"
93 "${BUILD_DIR}/imm_vs.c"
94 "${BUILD_DIR}/imm_vs.h")
95
96 target_include_directories(shaders PUBLIC
97 ${BUILD_DIR})
98endif()
diff --git a/dxg/shaders/imm.hlsl b/dxg/shaders/imm.hlsl
new file mode 100644
index 0000000..da6b1f6
--- /dev/null
+++ b/dxg/shaders/imm.hlsl
@@ -0,0 +1,23 @@
1struct VertexIn {
2 float3 position : POSITION;
3};
4
5struct VertexOut {
6 float4 position : SV_POSITION;
7};
8
9struct PixelOut {
10 float4 color : SV_TARGET;
11};
12
13VertexOut vs(VertexIn vin) {
14 VertexOut vout;
15 vout.position = float4(vin.position, 1.0f);
16 return vout;
17}
18
19PixelOut ps(VertexOut vout) {
20 PixelOut pixel;
21 pixel.color = float4(0.9f, 0.2f, 0.9f, 1.0f);
22 return pixel;
23}