如何在透明窗口应用Shader?基于WinRT屏幕捕获的实现问题求助
问题排查点
- 每帧重复创建D3D资源:当前
OnFrameArrived回调中每次触发都会重复创建顶点缓冲区、采样器、渲染目标视图、着色器资源视图等资源,不仅会导致严重的性能损耗,还会引发内存泄漏,最终触发资源耗尽崩溃。 - 捕获纹理创建参数错误:中转捕获帧的纹理设置了
D3D11_USAGE_IMMUTABLE用法,该用法要求创建纹理时必须传入初始数据,后续无法通过拷贝操作写入内容,会导致捕获帧拷贝失败。 - 着色器资源视图参数配置错误:手动填写SRV描述结构体时,
MostDetailedMip参数设置逻辑有误,捕获帧的纹理本身没有Mip链,不需要手动配置SRV参数,直接传空指针创建默认SRV即可避免参数错误。 - 临时资源未释放:每帧创建的纹理、SRV、顶点缓冲、渲染目标视图等临时资源没有执行释放操作,长时间运行会快速占满显存。
- 未设置D3D视口:D3D上下文没有配置对应交换链尺寸的视口,会导致绘制结果黑屏、拉伸变形等异常。
- 关闭了尺寸变化适配逻辑:注释掉了捕获窗口尺寸变化的处理逻辑,当捕获目标窗口大小改变时,交换链和纹理尺寸不匹配会直接引发绘制报错。
实现优化指导
- 预创建固定资源:将顶点着色器、像素着色器、输入布局、采样器、顶点缓冲区、视口这些不会随帧变化的资源,全部放到
SimpleCapture构造函数中一次性创建,避免每帧重复生成。 - 修正纹理创建参数:将中转纹理的
Usage属性从D3D11_USAGE_IMMUTABLE改为D3D11_USAGE_DEFAULT,创建SRV时直接传入空指针使用默认配置即可。 - 规范资源管理:所有D3D资源使用
winrt::com_ptr包裹,自动管理生命周期,不需要手动调用释放接口,避免内存泄漏。 - 补充视口配置:构造阶段根据捕获窗口的初始尺寸创建D3D视口,窗口尺寸变化时同步更新视口参数,每帧绘制前将视口绑定到D3D上下文。
- 恢复尺寸变化处理逻辑:打开注释掉的窗口resize相关代码,交换链重设缓存后同步更新视口、纹理等资源的尺寸配置。
- 分阶段调试:先用最简单的直接复制输入纹理像素的测试像素着色器验证整个渲染流程,确认流程跑通后再替换为自定义的滤镜Shader,排除Shader本身的逻辑问题。
内容的提问来源于stack exchange,提问作者True Vision _ Zunna Berry
相关产品推荐
相关产品推荐

