diff options
Diffstat (limited to 'dxg/shaders')
| -rw-r--r-- | dxg/shaders/CMakeLists.txt | 98 | ||||
| -rw-r--r-- | dxg/shaders/imm.hlsl | 23 |
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 @@ | |||
| 1 | set(SHADER_MODEL "6_5") | ||
| 2 | set(DXC ${PROJECT_SOURCE_DIR}/../contrib/dxc_2025_07_14/bin/x64/dxc.exe) | ||
| 3 | set(SHADERS_PATH ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| 4 | set(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. | ||
| 14 | function(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}") | ||
| 27 | endfunction() | ||
| 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 | ||
| 37 | function(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}) | ||
| 54 | endfunction() | ||
| 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. | ||
| 59 | function(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 | ) | ||
| 70 | endfunction() | ||
| 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. | ||
| 76 | if(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}") | ||
| 83 | else() | ||
| 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}) | ||
| 98 | endif() | ||
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 @@ | |||
| 1 | struct VertexIn { | ||
| 2 | float3 position : POSITION; | ||
| 3 | }; | ||
| 4 | |||
| 5 | struct VertexOut { | ||
| 6 | float4 position : SV_POSITION; | ||
| 7 | }; | ||
| 8 | |||
| 9 | struct PixelOut { | ||
| 10 | float4 color : SV_TARGET; | ||
| 11 | }; | ||
| 12 | |||
| 13 | VertexOut vs(VertexIn vin) { | ||
| 14 | VertexOut vout; | ||
| 15 | vout.position = float4(vin.position, 1.0f); | ||
| 16 | return vout; | ||
| 17 | } | ||
| 18 | |||
| 19 | PixelOut ps(VertexOut vout) { | ||
| 20 | PixelOut pixel; | ||
| 21 | pixel.color = float4(0.9f, 0.2f, 0.9f, 1.0f); | ||
| 22 | return pixel; | ||
| 23 | } | ||
