修复D3D11着色器加载失败,修复pipeline创建警告

This commit is contained in:
2025-06-19 15:29:53 +08:00
parent a501d409ff
commit 0adc357d8a
7 changed files with 72 additions and 43 deletions

View File

@@ -4,7 +4,7 @@ include(CMakeParseArguments)
find_package(Python3 REQUIRED)
# 存储脚本路径
set(SHADER_COMPILE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/tools/compile_shaders.py")
set(SHADER_COMPILE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/tools/main.py")
# 在cache目录下创建着色器目录.txt
set(SHADER_PATH_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cache/shader_paths.txt)
@@ -80,30 +80,25 @@ function(add_mirage_shader_directory path)
endfunction()
set(SHADER_COMPILE_ARGS "")
set(SHADER_SHDC "")
if (WIN32 OR CYGWIN)
list(APPEND SHADER_COMPILE_ARGS "--hlsl")
set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/win_mirage_shdc.exe)
list(APPEND SHADER_COMPILE_ARGS "-t" "dxbc")
elseif (APPLE)
list(APPEND SHADER_COMPILE_ARGS "--metal")
set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/mac_mirage_shdc)
list(APPEND SHADER_COMPILE_ARGS "-t" "msl")
else()
list(APPEND SHADER_COMPILE_ARGS "--glsl")
set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/linux_mirage_shdc)
list(APPEND SHADER_COMPILE_ARGS "-t" "glsl")
endif()
message(STATUS "使用着色器编译器: ${SHADER_SHDC}")
# 如果是Debug模式, 添加--debug选项
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND SHADER_COMPILE_ARGS "--debug")
list(APPEND SHADER_COMPILE_ARGS "-d")
endif ()
# 添加编译目标, 调用tools/compile_shaders.py
add_custom_target(compile_shaders ALL
COMMAND ${Python3_EXECUTABLE} ${SHADER_COMPILE_SCRIPT}
--shdc ${SHADER_SHDC}
--shader_list ${SHADER_PATH_FILE}
-l ${SHADER_PATH_FILE}
${SHADER_COMPILE_ARGS}
COMMENT "编译着色器"
VERBATIM

View File

@@ -2,15 +2,12 @@
#include "font/font_system.h"
#include "geometry/dpi_helper.h"
#include "shaders/mirage_rounded_rect.hlsl.h"
#include "shaders/mirage_image.hlsl.h"
#include "shaders/mirage_text.hlsl.h"
#include "shaders/mirage_wireframe.hlsl.h"
#include "shaders/mirage_line.hlsl.h"
#include "shaders/mirage_line.shader.h"
#include "shaders/mirage_rounded_rect.shader.h"
#include "shaders/mirage_image.shader.h"
#include "shaders/mirage_text.shader.h"
#include "shaders/mirage_wireframe.shader.h"
#include "shaders/mirage_line.shader.h"
template<typename Derived>
void compute_rect_vertices(const Eigen::MatrixBase<Derived>& in_pos,
@@ -468,23 +465,23 @@ void render_elements::load_mirage_pipelines() {
#else
auto format = MIRAGE_PIXEL_FORMAT;
#endif
const auto rounded_rect_shader = sg_make_shader(get_mirage_rounded_rect_shader_desc());
const auto rounded_rect_pipeline_desc = get_mirage_rounded_rect_pipeline_desc(rounded_rect_shader, format, 1);
const auto rounded_rect_shader = sg_make_shader(mirage_rounded_rect::get_shader_desc());
const auto rounded_rect_pipeline_desc = mirage_rounded_rect::get_pipeline_desc(rounded_rect_shader, format);
rounded_rect_pipeline_ = sg_make_pipeline(rounded_rect_pipeline_desc);
const auto image_shader = sg_make_shader(get_mirage_image_shader_desc());
const auto image_pipeline_desc = get_mirage_image_pipeline_desc(image_shader, format, 1);
const auto image_shader = sg_make_shader(mirage_image::get_shader_desc());
const auto image_pipeline_desc = mirage_image::get_pipeline_desc(image_shader, format);
image_pipeline_ = sg_make_pipeline(image_pipeline_desc);
const auto font_shader = sg_make_shader(get_mirage_text_shader_desc());
const auto font_pipeline_desc = get_mirage_text_pipeline_desc(font_shader, format, 1);
const auto font_shader = sg_make_shader(mirage_text::get_shader_desc());
const auto font_pipeline_desc = mirage_text::get_pipeline_desc(font_shader, format);
text_pipeline_ = sg_make_pipeline(font_pipeline_desc);
const auto wireframe_shader = sg_make_shader(get_mirage_wireframe_shader_desc());
const auto wireframe_pipeline_desc = get_mirage_wireframe_pipeline_desc(wireframe_shader, format, 1);
const auto wireframe_shader = sg_make_shader(mirage_wireframe::get_shader_desc());
const auto wireframe_pipeline_desc = mirage_wireframe::get_pipeline_desc(wireframe_shader, format);
wireframe_pipeline_ = sg_make_pipeline(wireframe_pipeline_desc);
const auto line_shader = sg_make_shader(get_mirage_line_shader_desc());
const auto line_pipeline_desc = get_mirage_line_pipeline_desc(line_shader, format, 1);
const auto line_shader = sg_make_shader(mirage_line::get_shader_desc());
const auto line_pipeline_desc = mirage_line::get_pipeline_desc(line_shader, format);
line_pipeline_ = sg_make_pipeline(line_pipeline_desc);
}

View File

@@ -6,7 +6,7 @@ cbuffer ParamBuffer
};
SamplerState textureSampler;
Texture2D texture;
Texture2D inputTexture;
struct PSInput {
float4 position : SV_POSITION;
@@ -31,7 +31,7 @@ PSInput vertex_main(VSInput input)
[shader("pixel")]
float4 pixel_main(PSInput input) : SV_Target
{
float4 color = texture.Sample(textureSampler, input.uv);
float4 color = inputTexture.Sample(textureSampler, input.uv);
float4 final_color = input.color;
final_color.a *= color.r;
return final_color;

View File

@@ -26,7 +26,7 @@ class CodeGenerator:
"""写入完整的文件内容"""
self._write_header(writer)
with writer.indent(f'namespace {global_vars.source_file_name}_shaders {{', '}'):
with writer.indent(f'namespace {global_vars.source_file_name} {{', '}'):
self._write_shader_bindings_class(writer, binding_infos)
writer.write()
@@ -79,7 +79,7 @@ class CodeGenerator:
def _write_get_shader_info_method(self, writer: IndentManager, binding_infos: ShaderInfos) -> None:
"""写入getShaderInfo方法"""
with writer.indent(f'static sg_shader_desc get_{global_vars.source_file_name}_shader_desc() {{', '}'):
with writer.indent(f'static sg_shader_desc get_shader_desc() {{', '}'):
writer.write('sg_shader_desc desc = {};')
writer.write(f'desc.label = "{global_vars.source_file_name}_shader_desc";')
writer.write()
@@ -106,6 +106,7 @@ class CodeGenerator:
else:
writer.write(f'// desc.{stage_name}_func.bytecode = SG_RANGE({entry_point_name}); // No blob data')
writer.write(f'desc.{stage_name}_func.entry = "{entry_point}";')
writer.write(f'desc.{stage_name}_func.d3d11_target = "{CodeGenerator.d3d11_target_string(stage)}";')
writer.write()
# 写入该阶段的资源绑定并收集image-sampler pairs
@@ -125,6 +126,18 @@ class CodeGenerator:
writer.write('return desc;')
@staticmethod
def d3d11_target_string(stage: Stage) -> str:
"""获取D3D11目标字符串"""
if stage == Stage.VERTEX:
return 'vs_5_0'
elif stage == Stage.FRAGMENT:
return 'ps_5_0'
elif stage == Stage.COMPUTE:
return 'cs_5_0'
else:
return 'unknown'
def _write_stage_resource_bindings(self, writer: IndentManager, stage_info: ShaderStageInfo,
stage_name: str) -> list:
"""写入单个阶段的资源绑定"""
@@ -138,6 +151,8 @@ class CodeGenerator:
image_sampler_pairs = []
for param in stage_info.parameters:
if not param.binding.used:
continue
binding_kind = param.get_binding_kind()
if binding_kind == BindingKind.CONSTANT_BUFFER:
uniform_blocks.append(param)
@@ -352,7 +367,7 @@ class CodeGenerator:
)
with writer.indent(
f'static sg_pipeline_desc get_{global_vars.source_file_name}_pipeline_desc(\n\t\t{function_params}\n\t) {{',
f'static sg_pipeline_desc get_pipeline_desc(\n\t\t{function_params}\n\t) {{',
'}'):
writer.write('sg_pipeline_desc desc = {};')
writer.write()
@@ -399,10 +414,14 @@ class CodeGenerator:
writer.write('desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;')
writer.write('desc.colors[0].pixel_format = pixel_format;')
writer.write('desc.colors[0].write_mask = SG_COLORMASK_RGBA;')
writer.write('desc.color_count = 1;')
writer.write()
label = f'{global_vars.source_file_name}_pipeline_desc'
# label需要定长, 不足52个字符使用空格填充
label = label.ljust(52)[:52]
writer.write('desc.sample_count = sample_count;')
writer.write(f'desc.label = "{global_vars.source_file_name}_pipeline_desc";')
writer.write(f'desc.label = "{label}";')
writer.write()
writer.write('return desc;')

View File

@@ -48,7 +48,7 @@ def make_cmd(source_file: str, target: TargetFormat, stage: Stage, entry_point:
cmd.extend(['-I', include_path])
if target == TargetFormat.DXBC:
cmd.extend(['-profile', 'sm_5_1'])
cmd.extend(['-profile', 'sm_5_0'])
return cmd

View File

@@ -10,11 +10,21 @@ import os
from compiler import SlangCompiler
from global_vars import *
def do_compile_shader(input_path, includes):
def do_compile_shader(input_file, includes, output_dir):
global_vars.source_file = input_file
global_vars.source_file_name = os.path.splitext(os.path.basename(input_file))[0]
global_vars.source_path = os.path.dirname(input_file)
global_vars.output_dir = output_dir or global_vars.source_path
output_file = os.path.join(global_vars.output_dir, f"{global_vars.source_file_name}.shader.h")
# 判断时间
if os.path.exists(output_file):
output_mtime = os.path.getmtime(output_file)
input_mtime = os.path.getmtime(input_file)
if input_mtime <= output_mtime:
print(f"Output file {output_file} is up-to-date. Skipping compilation.")
return
global_vars.source_file = input_path
global_vars.source_file_name = os.path.splitext(os.path.basename(input_path))[0]
global_vars.source_path = os.path.dirname(input_path)
shader_infos = ShaderInfos(
stages={}
@@ -31,7 +41,7 @@ def do_compile_shader(input_path, includes):
compiler = SlangCompiler()
# 解析着色器
print(f"**Parsing** {input_path}...")
print(f"**Parsing** {input_file}...")
shaders = compiler.parse_slang_shader()
if not shaders:
return
@@ -53,14 +63,16 @@ def main():
parser.add_argument('-t', '--target', choices=['glsl', 'dxbc', 'msl'],
required=True, help='Target shader format')
parser.add_argument('-o', '--output-dir', required=True, help='Output path for binding code')
parser.add_argument('-o', '--output-dir', help='Output path for binding code')
parser.add_argument('-i', '--include-dir', help='Include path for slang shader')
parser.add_argument('-d', '--debug', action='store_true', help='Enable debug mode')
parser.add_argument('-l', '--shader-list', help='List of shaders to compile (comma-separated)')
args = parser.parse_args()
global_vars.output_dir = os.path.abspath(args.output_dir)
if not args.output_dir:
output_path = None
else:
output_path = os.path.abspath(args.output_dir)
global_vars.target = TargetFormat(args.target)
global_vars.debug = args.debug
@@ -87,7 +99,7 @@ def main():
continue
for slang_file in slang_files:
input_path = os.path.join(shader_dir, slang_file)
do_compile_shader(input_path, includes)
do_compile_shader(input_path, includes, output_path)
if __name__ == '__main__':

View File

@@ -480,6 +480,12 @@ class ShaderStageInfo:
p.stage = entryPoint.stage
else:
assert p.stage == entryPoint.stage, f"Parameter stage {p.stage} does not match entry point stage {entryPoint.stage}"
# 将entryPoint的bindings设置到parameters中
for param in self.parameters:
for binding in entryPoint.bindings:
if binding.name == param.name:
param.binding = binding.binding
break
def get_entry_name(self):
return self.entryPoint.name