You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Evergine与DirectX12时出现System.AccessViolationException求助

问题分析与修复方案

异常原因

你遇到的System.AccessViolationException异常,本质是DirectX 12运行时尝试访问无效内存地址。结合异常触发点commandBuffer.SetGraphicsPipelineState(_pipelineState),核心原因大概率是图形管线状态(PipelineState)未正确初始化,或CommandBuffer处于异常状态,具体可能包括:

  • PipelineState对象创建时参数不合法(如输入布局与着色器不匹配、资源关联错误)
  • PipelineState已被提前释放或未完成初始化
  • CommandBuffer未处于正确的录制状态(如未开始录制、已结束录制)

具体修复步骤

1. 确保PipelineState创建参数完全符合DX12要求

检查Renderable.cs中PipelineState的创建逻辑,需保证以下几点:

  • 输入布局与着色器语义严格匹配:顶点数据的类型、语义名称(如POSITION)、语义索引必须和HLSL着色器的输入完全一致。例如顶点数据是Vector3,着色器中必须对应float3 POSITION : SV_POSITION;(或正确的语义绑定)。
  • 显式配置DX12所需的管线状态参数:DX12对管线状态的要求比DX11更严格,不能依赖默认值。需显式设置光栅化状态、混合状态、图元拓扑类型、渲染目标格式等:
var pipelineDesc = new GraphicsPipelineStateDescription
{
    InputLayout = inputLayout,
    VertexShader = vertexShaderByteCode,
    PixelShader = pixelShaderByteCode,
    // 显式设置光栅化状态(按需调整)
    RasterizerState = new RasterizerDescription(CullMode.Back, FillMode.Solid)
    {
        IsDepthClipEnabled = true,
        IsMultisampleEnabled = false
    },
    // 显式设置混合状态(纯色三角形可使用默认)
    BlendState = BlendDescription.Default,
    // 深度模板状态(如果不需要深度可禁用)
    DepthStencilState = new DepthStencilDescription(false, false),
    PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
    // 匹配当前渲染目标的格式
    RenderTargetFormats = new[] { graphicsContext.SurfaceFormat },
    DepthStencilFormat = graphicsContext.DepthStencilFormat
};
// 确保使用DX12上下文的工厂创建管线状态
_pipelineState = graphicsContext.Factory.CreateGraphicsPipelineState(pipelineDesc);

2. 验证CommandBuffer的状态正确性

在Triangle.cs的RenderInternal方法中,确保CommandBuffer处于录制状态时调用SetGraphicsPipelineState:

// 确认CommandBuffer已正确开始录制
commandBuffer.Begin();

// 在此之后执行管线状态设置、绘制等操作
commandBuffer.SetGraphicsPipelineState(_pipelineState);
// ...其他绘制逻辑

// 绘制完成后结束录制并提交
commandBuffer.End();
graphicsContext.CommandQueue.ExecuteCommandBuffer(commandBuffer);

避免在CommandBuffer未开始录制、已结束录制的状态下调用API。

3. 检查着色器编译的完整性

即使使用了Level_12_0配置文件,仍需确认:

  • 顶点着色器和像素着色器都成功编译,无编译错误
  • 着色器的目标Profile与DX12兼容(推荐使用sm_5_1或更高,对应GraphicsProfile.Level_12_1)
var compilerParams = CompilerParameters.Default with 
{ 
    Profile = GraphicsProfile.Level_12_1,
    // 添加调试信息,方便排查着色器问题
    DebugMode = true 
};
var vertexResult = graphicsContext.ShaderCompile(vertexSource, "VS", ShaderStages.Vertex, compilerParams);
var pixelResult = graphicsContext.ShaderCompile(pixelSource, "PS", ShaderStages.Pixel, compilerParams);

// 检查编译是否成功
if (!vertexResult.Success || !pixelResult.Success)
{
    throw new InvalidOperationException($"Shader compile error: {vertexResult.ErrorMessage}\n{pixelResult.ErrorMessage}");
}

4. 确保资源生命周期正确管理

在Evergine中,PipelineState等资源需正确关联到上下文或资源容器,避免被GC提前回收。可将_pipelineState添加到组件的Resources集合中:

// 在Renderable.cs的Initialize方法中创建PipelineState后
this.Resources.Add(_pipelineState);

总结

DirectX 12的异常大多源于资源初始化不规范或状态管理错误,重点排查PipelineState的创建参数、CommandBuffer的录制状态,以及资源生命周期管理。对比Evergine官方LowLevelAPIDemo项目的管线创建逻辑,逐步验证每一步的参数是否匹配DX12的要求。

内容的提问来源于stack exchange,提问作者bertiooo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:02:39