当我启用 NVidia Optimus 时,为啥在 D3D11 中我的纹理上会出现条纹

Posted

技术标签:

【中文标题】当我启用 NVidia Optimus 时,为啥在 D3D11 中我的纹理上会出现条纹【英文标题】:Why are Stripes appearing on my Textures in D3D11 when I Enable NVidia Optimus当我启用 NVidia Optimus 时,为什么在 D3D11 中我的纹理上会出现条纹 【发布时间】:2020-10-13 19:56:19 【问题描述】:

背景:我一直在使用集成 GPU 进行着色器调试,但我认为它可能已经达到了极限,这促使我使用专用显卡。

唯一的问题是,当我将 NvOptimusEnablement 添加到我的代码中时,我的纹理上开始出现条纹;有趣的是,条纹并没有出现在 Visual Studio 的图形分析器中。

在 Windows 中:

在 Visual Studio 图形分析器中:

如果工件仅用于调试版本,我不会介意,但可执行文件也会显示这些条纹纹理。

注意事项:

好像加了一行:

extern "C" 

    _declspec(dllexport) DWORD NvOptimusEnablement = SomeValue;

无论“SomeValue”的值如何,都会导致 D3D11 使用专用图形,即使 SomeValue 为 0;我必须删除这段代码才能使用集成显卡。

--

我注意到启用 Optimus 会使用更多内存(根据 Visual Studio 的进程内存,61.4MB 与 37.4MB 使用集成显卡)我没有这种编程经验,所以我真的不知道如果这很正常,但我想我还是把我的观察记录下来吧。

编辑:

我的代码目前有相当多的抽象,但是我这里写的东西应该是完全一样的顺序。

开始通话

编译着色器..

设置采样器

ID3D11SamplerState * pSampler = nullptr;
..
D3D11_SAMPLER_DESC default_sampler = ;
default_sampler.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
default_sampler.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
default_sampler.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
default_sampler.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
default_sampler.ComparisonFunc = D3D11_COMPARISON_NEVER;
default_sampler.MinLOD = 0;
default_sampler.MaxLOD = D3D11_FLOAT32_MAX;
m_d3dDevice->CreateSamplerState(&default_sampler, &pSampler);
m_ImmediateContext->PSSetSamplers(0, 1, &pSampler);

加载纹理

//Loading Image from file
ID3D11ShaderResourceView * pTextureRV = nullptr;
..
auto ext = std::filesystem::path(filename).extension();
if (ext == ".dds")

    DirectX::CreateDDSTextureFromFile(m_d3dDevice, filename.c_str(), nullptr, &pTextureRV);

设置顶点..

绘制调用

将纹理设置为方形图案的 PSShaderResource

m_ImmediateContext->PSSetShaderResources(2, 1, &pTextureRV);

设置着色器

m_ImmediateContext->VSSetShader(VShader, nullptr, 0);
m_ImmediateContext->PSSetShader(PShader, nullptr, 0);

设置常量缓冲区..

画三角形

m_ImmediateContext->DrawIndexed(index_count, 0, 0);

着色器

主着色器:

cbuffer CBResize : register(b0)

    matrix Projection;
    float2 Screen;
;

cbuffer CBFrame : register(b1)

    matrix World;
    matrix View;
;

struct Vin

    float3 Pos : POSITION;
    float4 Col : COLOR;
    float2 Tex : TEXCOORD0;
;

struct Pin

    float4 Pos : SV_POSITION;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
;

Pin VS(Vin input)

    Pin output;
    output.Pos = float4(input.Pos, 1);
    output.Pos = mul(output.Pos, World);
    output.Pos = mul(output.Pos, View);
    output.Pos = mul(output.Pos, Projection);
    output.Col = input.Col;
    output.Tex = input.Tex;
    return output;


//t2 contains square pattern
Texture2D txFrame : register( t2 );
SamplerState samLinear : register( s0 );

float4 PS(Pin input) : SV_TARGET

    return txFrame.Sample(samLinear, input.Tex);

非常感谢! :)

【问题讨论】:

是的,你的显卡驱动只寻找符号的存在,它并不关心值。条纹可能是 a) 你的代码有问题(所以请显示出来)或 b) 驱动程序错误。 我的代码现在变得相当大,所以我认为复制粘贴所有内容都不合适,但我已经编辑了我的帖子以包含我用来加载纹理、采样器、和着色器本身。我目前也在使用 Visual Studio 的图形分析器调试框架以检查上下文的状态和值,感谢您的快速响应! 在搜索 D3D11 样本并启用 Optimus 之后,我认为可以安全地得出结论,条纹来自我的代码中的错误,我还不知道它是什么,但我会继续寻找 我又发现了一个问题,由于某种原因,如果我将插槽 0 用于纹理,问题就会自行解决,但任何其他插槽都会给我条纹纹理 【参考方案1】:

我不太确定发生了什么,但是在更新 Windows 10 并重新安装 Visual Studio 和 NVidia 的驱动程序(全新安装)之后,问题现在看起来已经解决了吗?感谢您的帮助!

在此留个便条以防万一:

处理器:i7 6700HQ

GPU:GTX 960M

Windows 版本:Windows 10 专业版 10.0.19041.329

NVidia 驱动程序版本:451.48

Visual Studio 版本:15.9.24

【讨论】:

以上是关于当我启用 NVidia Optimus 时,为啥在 D3D11 中我的纹理上会出现条纹的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio / AVD with bumblebee / nvidia optimus

在 Java/OpenGL 下激活 nVIDIA Optimus?

在交流适配器上使用 NVidia optimus 有啥好处吗?

OpenGL 3.3 两个 GPU 上的两个不同结果 nVidia Optimus 与阴影映射

Per-monitor DPI-Aware:NVIDIA Optimus 出现黑窗故障

为啥我的程序在 nVidia NView 下会消耗 100% CPU?