NVIDIA specific rendering artifact

Started by
10 comments, last by Blasp 8 years ago

My 3D game looks fine on AMD gpus (radeon HD 5800, 6300m) and on integrated gpus (intel), but looks grainy on nvidia gpus (tested on 635m, 930m). Changing the shader, blending, depth buffer settings, fullscreen, doesnt seem to help. Anyone knows why this happens?

screen_bad.png

screen_good.png

Here is my D3D initialization code, it could be relevant:

bool InitializeDirect3d11App(HINSTANCE const hInstance)
{
std::cout << NEWLINE << "InitializeDirect3d11App(" << hInstance << ")" << NEWLINE;
// Describe our Display Mode
DXGI_MODE_DESC bufferDesc = {};
bufferDesc.Width = Width;
bufferDesc.Height = Height;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

// Describe our Swap Chain
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.Windowed = windowed;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

// Create our Direct3D 11 Device and SwapChain // D3D11_CREATE_DEVICE_DEBUG, D3D11_CREATE_DEVICE_BGRA_SUPPORT, D3D11_CREATE_DEVICE_SINGLETHREADED
D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED,
nullptr, NULL, D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, nullptr, &d3d11DevCon);

// BackBuffer
D3D11_TEXTURE2D_DESC BackBuffer_Texture2D_Desc = {};
BackBuffer_Texture2D_Desc.Width = Width;
BackBuffer_Texture2D_Desc.Height = Height;
BackBuffer_Texture2D_Desc.MipLevels = 1;
BackBuffer_Texture2D_Desc.ArraySize = 1;
BackBuffer_Texture2D_Desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
BackBuffer_Texture2D_Desc.SampleDesc.Count = 1;
BackBuffer_Texture2D_Desc.SampleDesc.Quality = 0;
BackBuffer_Texture2D_Desc.Usage = D3D11_USAGE_DEFAULT;
BackBuffer_Texture2D_Desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
//BackBuffer_Texture2D_Desc.BindFlags = D3D11_BIND_RENDER_TARGET;
BackBuffer_Texture2D_Desc.CPUAccessFlags = 0;
BackBuffer_Texture2D_Desc.MiscFlags = 0;
d3d11Device->CreateTexture2D(&BackBuffer_Texture2D_Desc, nullptr, &BackBuffer);

D3D11_RENDER_TARGET_VIEW_DESC BackBuffer_RTV_Desc = {};
BackBuffer_RTV_Desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
BackBuffer_RTV_Desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
BackBuffer_RTV_Desc.Texture2D.MipSlice = 0;
SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
d3d11Device->CreateRenderTargetView(BackBuffer, nullptr, &BackBuffer_RTV);

// Describe and create our Depth/Stencil Buffer
BackBuffer_Texture2D_Desc.Format = DXGI_FORMAT_D32_FLOAT;
BackBuffer_Texture2D_Desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
d3d11Device->CreateTexture2D(&BackBuffer_Texture2D_Desc, nullptr, &DepthStencilBuffer);
d3d11Device->CreateDepthStencilView(DepthStencilBuffer, nullptr, &DepthStencilBuffer_DSV);

D3D11_DEPTH_STENCIL_DESC depth_write_enabled_desc = {};
depth_write_enabled_desc.DepthEnable = TRUE;
depth_write_enabled_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; // depth write enabled
depth_write_enabled_desc.DepthFunc = D3D11_COMPARISON_LESS;
depth_write_enabled_desc.StencilEnable = false;
depth_write_enabled_desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
depth_write_enabled_desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
depth_write_enabled_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
depth_write_enabled_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depth_write_enabled_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
depth_write_enabled_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depth_write_enabled_desc.BackFace = depth_write_enabled_desc.FrontFace;
d3d11Device->CreateDepthStencilState(&depth_write_enabled_desc, &pDepthenabledStencilState);

depth_write_enabled_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; // depth write disabled
d3d11Device->CreateDepthStencilState(&depth_write_enabled_desc, &pDepthdisabledStencilState);

D3D11_BLEND_DESC blendDesc = {};
blendDesc.AlphaToCoverageEnable = false; // transparency artifacts if true
D3D11_RENDER_TARGET_BLEND_DESC rtbd = {};
rtbd.BlendEnable = true;

rtbd.SrcBlend = D3D11_BLEND_ONE;//D3D11_BLEND_BLEND_FACTOR;
rtbd.DestBlend = D3D11_BLEND_ONE;
rtbd.BlendOp = D3D11_BLEND_OP_ADD;
rtbd.SrcBlendAlpha = D3D11_BLEND_ONE;//D3D11_BLEND_BLEND_FACTOR;
rtbd.DestBlendAlpha = D3D11_BLEND_ZERO;//D3D11_BLEND_ONE;
rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
rtbd.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
blendDesc.RenderTarget[0] = rtbd;
d3d11Device->CreateBlendState(&blendDesc, &Blend_Add);
rtbd.SrcBlend = D3D11_BLEND_SRC_ALPHA;
rtbd.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
rtbd.BlendOp = D3D11_BLEND_OP_ADD;
rtbd.SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
rtbd.DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0] = rtbd;
d3d11Device->CreateBlendState(&blendDesc, &Blend_Alpha);
rtbd.SrcBlend = D3D11_BLEND_BLEND_FACTOR;
rtbd.DestBlend = D3D11_BLEND_INV_BLEND_FACTOR;
rtbd.BlendOp = D3D11_BLEND_OP_ADD;
rtbd.SrcBlendAlpha = D3D11_BLEND_BLEND_FACTOR;
rtbd.DestBlendAlpha = D3D11_BLEND_INV_BLEND_FACTOR;
rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0] = rtbd;
d3d11Device->CreateBlendState(&blendDesc, &Blend_Overwrite);

// Create and set the Viewport (subrectangle of the back buffer)
D3D11_VIEWPORT viewport = {};
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = Width;
viewport.Height = Height;
viewport.MinDepth = 0.0;
viewport.MaxDepth = 1.0;
d3d11DevCon->RSSetViewports(1, &viewport);

// Describe and create the Sampler state
D3D11_SAMPLER_DESC sampDesc = {};
sampDesc.Filter = D3D11_FILTER_ANISOTROPIC;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.MaxAnisotropy = 16;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
d3d11Device->CreateSamplerState(&sampDesc, &TextureSamplerState);
d3d11DevCon->PSSetSamplers(0, 1, &TextureSamplerState);

D3D11_RASTERIZER_DESC rsdesc = {};
rsdesc.FillMode = D3D11_FILL_SOLID;
rsdesc.CullMode = D3D11_CULL_BACK;
rsdesc.FrontCounterClockwise = true;
d3d11Device->CreateRasterizerState(&rsdesc, &CCWcullMode);
rsdesc.FrontCounterClockwise = false;
d3d11Device->CreateRasterizerState(&rsdesc, &CWcullMode);
rsdesc.CullMode = D3D11_CULL_NONE;
d3d11Device->CreateRasterizerState(&rsdesc, &NonecullMode);
rsdesc.FillMode = D3D11_FILL_WIREFRAME;
d3d11Device->CreateRasterizerState(&rsdesc, &WireFrameRState);

//Compile Shaders from shader file
D3DX11CompileFromFile(L"Effects.fx", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_Buffer, 0, 0);
D3DX11CompileFromFile(L"Effects.fx", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_Buffer, 0, 0);

//Create the Shader Objects
d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), nullptr, &VS);
d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), nullptr, &PS);

//Set Vertex and Pixel Shaders
d3d11DevCon->VSSetShader(VS, 0, 0);
d3d11DevCon->PSSetShader(PS, 0, 0);

//Create the buffer to send to the per object cbuffer in effect file
D3D11_BUFFER_DESC cbbd = {};
cbbd.Usage = D3D11_USAGE_DEFAULT;
cbbd.ByteWidth = sizeof(cbVertex);
cbbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbbd.CPUAccessFlags = 0;
cbbd.MiscFlags = 0;
d3d11Device->CreateBuffer(&cbbd, nullptr, &cbVertexBuffer);

//Create the buffer to send to the per frame cbuffer in effect file
cbbd.ByteWidth = sizeof(cbPixel);
d3d11Device->CreateBuffer(&cbbd, nullptr, &cbPixelBuffer);

//Describe, create and set the Input Layout
const D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // 12
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // 8
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // 12
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // 16
// = 48 B
{ "COLORINST", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // 16
{ "ATTRIBUTES", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // 16
{ "WORLD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // 16
{ "WORLD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // 16
{ "WORLD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 64, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // 16
{ "WORLD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 80, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, // 16
{ "TEXTUREIDS", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 96, D3D11_INPUT_PER_INSTANCE_DATA, 1 } // 16
}; // = 112 B
d3d11Device->CreateInputLayout(layout, ARRAYSIZE(layout), VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), &vertLayout);
d3d11DevCon->IASetInputLayout(vertLayout);

d3d11DevCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

FW1CreateFactory(FW1_VERSION, &pFW1Factory);
pFW1Factory->CreateFontWrapper(d3d11Device, L"Arial", &pFontWrapper);

//Set our Render Target
d3d11DevCon->OMSetRenderTargets(1, &BackBuffer_RTV, DepthStencilBuffer_DSV);

QueryPerformanceFrequency(&Frequency);
min_frame_ticks.QuadPart = Frequency.QuadPart / fps_cap;
std::cout << "Performance Counter Frequency: " << Frequency.QuadPart << NEWLINE;

return true;
}

Advertisement

You've not helped anyone by leaving in chunks of commented out code in there. I assume your R32G32B32A32_FLOAT RTVs/SRVs are never used anywhere in the project?

The error looks either like shadow acne or z-fighting. If you have Shadow Mapping, have you tried disabling it to see if it goes away?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

Looks like shadow acne to me too, the second image also seem to suffer from it?

.:vinterberg:.

I have updated the code above to remove unused code. No change. It is not shadow acne because I have no shadow mapping in the engine, and the problem persists even when I simply output diffuse, bypassing almost all of the pixel shader. Diffuse only screenshot:

screen.png

OK, there has been some progress. What we are seeing is two different textures fighting over each other. The correct texture and the one in pixel shader slot/register lower by one. Still cant figure out where the bug is, tough. Here is my texture loading code:

for (Texture& texture : Texture_Vector)
{
if (texture.loaded == Texture_Status::Load_Buffered) // load
{
if (texture.resource != nullptr)
{
texture.resource->Release();
}
texture.resource = nullptr;
if ((hr = D3DX11CreateShaderResourceViewFromMemory(d3d11Device, &(texture.byte_buffer[0]), texture.byte_buffer.size(), nullptr, nullptr, &(texture.resource), nullptr)) != 0)
{
std::wcout << NEWLINE << "ERROR: Texture loading failed. (HRESULT: " << int(hr) << "), path: " << texture.path << " (" << texture.path_unloaded << ") reason: " << d3d11Device->GetDeviceRemovedReason() << NEWLINE;
texture.loaded = Texture_Status::Unloaded;
}
else
{
//std::cout << texture.name << " loaded." << " (" << texture.byte_buffer.size() / 8000 << " kB)" << NEWLINE;
texture.loaded = Texture_Status::Loaded;
}
texture.byte_buffer.clear();
texture.byte_buffer.shrink_to_fit();
}
else if (texture.loaded == Texture_Status::Unload_Buffered) // unload
{
if (texture.resource != nullptr)
{
texture.resource->Release();
}
texture.resource = nullptr;
if ((hr = D3DX11CreateShaderResourceViewFromMemory(d3d11Device, &(texture.byte_buffer[0]), texture.byte_buffer.size(), nullptr, nullptr, &(texture.resource), nullptr)) != 0)
{
std::wcout << NEWLINE << "ERROR: Texture unloading failed. (HRESULT: " << int(hr) << "), path: " << texture.path << " (" << texture.path_unloaded << ") reason: " << d3d11Device->GetDeviceRemovedReason() << NEWLINE;
texture.loaded = Texture_Status::Loaded;
}
else
{
//std::cout << texture.name << " unloaded." << " (" << texture.byte_buffer.size()/8000 << " kB)" << NEWLINE;
texture.loaded = Texture_Status::Unloaded;
}
texture.byte_buffer.clear();
texture.byte_buffer.shrink_to_fit();
}
}

// Set Textures
std::vector<ID3D11ShaderResourceView*> Tex_Vector;
for (Texture& texture : Texture_Vector)
{
if (texture.loaded == Texture_Status::Loaded && texture.resource != nullptr)
{
Tex_Vector.emplace_back(texture.resource);
}
else
{
Tex_Vector.emplace_back(texture.resource_unloaded);
}
}
d3d11DevCon->PSSetShaderResources(0, Tex_Vector.size(), &Tex_Vector[0]);

and my texture sampling HLSL:

Texture2D Texture0 : register(ps, t0);
Texture2D Texture1 : register(ps, t1);
Texture2D Texture2 : register(ps, t2);
Texture2D Texture3 : register(ps, t3);
Texture2D Texture4 : register(ps, t4);
Texture2D Texture5 : register(ps, t5);
Texture2D Texture6 : register(ps, t6);
Texture2D Texture7 : register(ps, t7);
Texture2D Texture8 : register(ps, t8);
Texture2D Texture9 : register(ps, t9);
Texture2D Texture10 : register(ps, t10);
Texture2D Texture11 : register(ps, t11);
Texture2D Texture12 : register(ps, t12);
Texture2D Texture13 : register(ps, t13);
Texture2D Texture14 : register(ps, t14);
Texture2D Texture15 : register(ps, t15);
Texture2D Texture16 : register(ps, t16);
Texture2D Texture17 : register(ps, t17);
Texture2D Texture18 : register(ps, t18);
Texture2D Texture19 : register(ps, t19);
Texture2D Texture20 : register(ps, t20);
Texture2D Texture21 : register(ps, t21);
Texture2D Texture22 : register(ps, t22);
Texture2D Texture23 : register(ps, t23);
Texture2D Texture24 : register(ps, t24);
Texture2D Texture25 : register(ps, t25);
Texture2D Texture26 : register(ps, t26);
Texture2D Texture27 : register(ps, t27);
Texture2D Texture28 : register(ps, t28);
Texture2D Texture29 : register(ps, t29);
Texture2D Texture30 : register(ps, t30);
Texture2D Texture31 : register(ps, t31);
Texture2D Texture32 : register(ps, t32);
Texture2D Texture33 : register(ps, t33);
SamplerState ObjSamplerState : register(ps, s0);

float4 texture_sample(float id, float2 texcoord)
{
[call] switch (id)
{
case 0:
{
return Texture0.Sample(ObjSamplerState, texcoord);
}
break;
case 1:
{
return Texture1.Sample(ObjSamplerState, texcoord);
}
break;
case 2:
{
return Texture2.Sample(ObjSamplerState, texcoord);
}
break;
case 3:
{
return Texture3.Sample(ObjSamplerState, texcoord);
}
break;
case 4:
{
return Texture4.Sample(ObjSamplerState, texcoord);
}
break;
case 5:
{
return Texture5.Sample(ObjSamplerState, texcoord);
}
break;
case 6:
{
return Texture6.Sample(ObjSamplerState, texcoord);
}
break;
case 7:
{
return Texture7.Sample(ObjSamplerState, texcoord);
}
break;
case 8:
{
return Texture8.Sample(ObjSamplerState, texcoord);
}
break;
case 9:
{
return Texture9.Sample(ObjSamplerState, texcoord);
}
break;
case 10:
{
return Texture10.Sample(ObjSamplerState, texcoord);
}
break;
case 11:
{
return Texture11.Sample(ObjSamplerState, texcoord);
}
break;
case 12:
{
return Texture12.Sample(ObjSamplerState, texcoord);
}
break;
case 13:
{
return Texture13.Sample(ObjSamplerState, texcoord);
}
break;
case 14:
{
return Texture14.Sample(ObjSamplerState, texcoord);
}
break;
case 15:
{
return Texture15.Sample(ObjSamplerState, texcoord);
}
break;
case 16:
{
return Texture16.Sample(ObjSamplerState, texcoord);
}
break;
case 17:
{
return Texture17.Sample(ObjSamplerState, texcoord);
}
break;
case 18:
{
return Texture18.Sample(ObjSamplerState, texcoord);
}
break;
case 19:
{
return Texture19.Sample(ObjSamplerState, texcoord);
}
break;
case 20:
{
return Texture20.Sample(ObjSamplerState, texcoord);
}
break;
case 21:
{
return Texture21.Sample(ObjSamplerState, texcoord);
}
break;
case 22:
{
return Texture22.Sample(ObjSamplerState, texcoord);
}
break;
case 23:
{
return Texture23.Sample(ObjSamplerState, texcoord);
}
break;
case 24:
{
return Texture24.Sample(ObjSamplerState, texcoord);
}
break;
case 25:
{
return Texture25.Sample(ObjSamplerState, texcoord);
}
break;
case 26:
{
return Texture26.Sample(ObjSamplerState, texcoord);
}
break;
case 27:
{
return Texture27.Sample(ObjSamplerState, texcoord);
}
break;
case 28:
{
return Texture28.Sample(ObjSamplerState, texcoord);
}
break;
case 29:
{
return Texture29.Sample(ObjSamplerState, texcoord);
}
break;
case 30:
{
return Texture30.Sample(ObjSamplerState, texcoord);
}
break;
case 31:
{
return Texture31.Sample(ObjSamplerState, texcoord);
}
break;
case 32:
{
return Texture32.Sample(ObjSamplerState, texcoord);
}
break;
case 33:
{
return Texture33.Sample(ObjSamplerState, texcoord);
}
break;
default:
{
return Texture0.Sample(ObjSamplerState, texcoord);
}
break;
}
}

That shader is amazing for all the wrong reasons! Are you familiar with Texture Arrays?

What simplifications have you tried making to that Pixel Shader before the problem goes away?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

That shader is amazing for all the wrong reasons! Are you familiar with Texture Arrays?

What simplifications have you tried making to that Pixel Shader before the problem goes away?

I am aware of texture arrays, but not familiar with them. Do you think it could be the cause? I will try to sample the texture directly to see if it helps..

My beautiful texture sampling shader was indeed the cause of the artifact, getting rid of it solves the shimmering. But now I have to redo the whole texturing code.. :(

If all your 34 textures are the same format and dimension then they can be stored in a single ID3D12Texture2D that happens to have 34 'slices'. From HLSL you declare that texture to be a Texture2DArray and then the .Load/.Sample methods take an extra int/float indicating which slice of that array to read from.

If your 34 textures are varying sizes and formats then I would reconsider your approach to rendering whatever it is you're rendering.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

My beautiful texture sampling shader ..

Knowing a little bit about how shaders works in regards to branching and conditionals etc., the word "beautiful" didn't come to mind - at all :lol: :wink:

.:vinterberg:.

This topic is closed to new replies.

Advertisement