Why does this HLSL pixel shader not compile? - hlsl

I'm working on a ray tracing pixel shader and came across a weird error. I wrote the following code solely to generate the error, it's pointless but I can't figure out what's wrong with it.
float4 main(/*Any input*/) : SV_TARGET
{
uint uints[2];
float4 light[2];
uints[0] = 0;
uints[1] = 0;
uint c = 1;
[loop] while (c > 0) {
if (uints[c] == 0)
light[c - 1] = 0.0f;
else
light[c - 1] = 0.0f;
c--;
break;
}
return light[0];
}
When compiled with shader model 5_0 (with and without optimizations) I get the following error:
error MSB6006: "fxc.exe" exited with code -1073741819
Doing seemingly meaningless things to the code, like removing c--;, gets rid of the error. Can anyone figure out what this weird error comes from?

In my case it compiles if I remove the [loop] tag.
// Compiling pixel shader
ComPtr<ID3DBlob> pixelBlob = nullptr;
ComPtr<ID3DBlob> pixelErrorBlob = nullptr;
result = D3DCompile(pixelShaderByteCode.c_str(),
pixelShaderByteCode.length(),
nullptr,
nullptr,
nullptr,
"main", "ps_5_0",
compileFlags, 0,
pixelBlob.GetAddressOf(),
pixelErrorBlob.GetAddressOf());
float4 main(PixelInput input) : SV_TARGET
{
uint uints[2];
float4 light[2];
uints[0] = 0;
uints[1] = 0;
uint c = 1;
while (c > 0) {
if (uints[c] == 0)
light[c - 1] = 0.0f;
else
light[c - 1] = 0.0f;
c--;
break;
}
return light[0];
}

Related

Why "Warning X4000: use of potentially uninitialized variable" shows for more than one usage of common method?

I have a common method in hlsli
/// RendererShaderTypes.hlsli
///
static inline float4 OverlayColor(float2 texOverlay, float4 videoColor)
{
float4 texColor = float4(imageMixTexture[4].Sample(imageMixSampler[4], texOverlay));
if (texColor.r == keyColor.r &&
texColor.g == keyColor.g &&
texColor.b == keyColor.b)
{
return videoColor;
}
return lerp(texColor, videoColor, transparency);
}
It's called from more than one hlsl pixel shaders.
#include "RendererShaderTypes.hlsli"
float4 main(PSPosTexOverlay input) : SV_TARGET
{
return OverlayColor(input.texOverlay, backColor);
}
also called to another pixel shader
#include "RendererShaderTypes.hlsli"
float4 main(PSPosVideoTexture input) : SV_TARGET
{
// lookup color of video
float4 mixColor = mul(colorMatrix[0], VideoColor(imageMixSampler[0], imageMixTexture[0], input.texImage));
mixColor.rgb *= mixColor.a;
mixColor.a = 1.0f;
return OverlayColor(input.texOverlay, mixColor);
}
when compiled shows following warning. Any idea why it's showing?
warning X4000: use of potentially uninitialized variable (OverlayColor)
I don't know yet any satisfactory reason but I have solved the issue. Any function that calls a mid-function return statement will show the warning during compilation. I have re-writed one of above like this and the warning went away.
static inline float4 OverlayColor(int texIndex, float2 texOverlay, float4 videoColor)
{
float4 texColor = float4(imageMixTexture[4].Sample(imageMixSampler[4], texOverlay));
float4 overlayColor;
if (texColor.r == keyColor.r &&
texColor.g == keyColor.g &&
texColor.b == keyColor.b)
{
overlayColor = videoColor;
}
else
overlayColor = lerp(texColor, videoColor, transparency);
return overlayColor;
}

Shaders and Directx11 compilation in c++

I am trying to create a Directx 11 program using c++ . The code used to work before I added Normal to the code .Now it doesnt compile the shader at all .It keeps giving me access Violation 0X0000 Error.
I tried using d3dErrorBlolb but wasnt very helpful.The problem seems to lie in this part of the code.
void InitPipeline(HWND hwnd)
{
ID3D10Blob * BVS = 0,*BPS = 0;
ID3D10Blob * BErrorVS,*BErrorPs;
HRESULT hr1 = D3DX11CompileFromFile(L"Test.fx",0,0,"VS","vs_4_0",0,0,0,&BVS,&BErrorVS,0);
HRESULT hr = D3DX11CompileFromFile(L"Test.fx",0,0,"PS","ps_4_0",0,0,0,&BPS,&BErrorPs,0);
if(FAILED(hr))
{
printf("Error %08X %5s\n",hr,(char*)BErrorVS);
MessageBox(hwnd,L"Pixel shader not created ",L"",0);
}
if(FAILED(hr1))
{ MessageBox(hwnd,L"Vertex shader not created ",L"",0);}
dev->CreateVertexShader(BVS->GetBufferPointer(),BVS->GetBufferSize(),0,&BoxVShader);
dev->CreatePixelShader(BPS->GetBufferPointer(),BPS->GetBufferSize(),0,&BoxPixelShader);
// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}
// {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
//SecureZeroMemory(&Bin);
dev->CreateInputLayout(ied,2,BVS->GetBufferPointer(),BVS->GetBufferSize(),&BInputLayout);
devcon->VSSetShader(BoxVShader,0,0);
devcon->PSSetShader(BoxPixelShader,0,0);
devcon->IASetInputLayout(BInputLayout);
}
The Test.fx file
ecbuffer ConstantBuffer:register(b0)
{
matrix world;
matrix view;
matrix project;
float3[2] LightDir;
float4[2] LightColor;
}
struct Vout{
float4 pos:SV_POSITION;
float4 normal : NORMAL;
};
Vout VS(float3 pos:POSITION,float3 Norm:NORMAL)
{
Vout vo = (Vout)0;
vo.pos = mul(float4(pos,1),world);
vo.pos = mul(vo.pos,view);
vo.pos = mul(vo.pos,project);
vo.normal = mul(float4(Norm,1),world);
return vo;
}
float4 PS(float4 pos:SV_POSITION,float4 normal:NORMAL):SV_TARGET
{
float4 col;
for(int i=0; i < 2;++i)
{
col += saturate(dot(normal,LightDir[i])) * LightColor[i] ;
}
return col;
}
Can anyone please be kind enough to help me out...
If possible please do explain why this keeps happening always..What am I doing wrong here
Please do help me.I desperately need to solve this problem....
Thank you...
While compiling HLSL at runtime is nice for learning and iteration, it's actually a lot easier to debug the HLSL by compiling it with the command-line:
fxc test.fx /Tvs_4_0 /EVS and fxc test.fx /Tps_4_0 /EPS
The second fails because you failed to set the initial value for col in the Pixel Shader:
test.fx(40,25-47): warning X3206: 'dot': implicit truncation of vector type
test.fx(40,9-64): error X4000: variable 'col' used without having been completely initialized
compilation failed; no code produced
The fix is trivial:
float4 PS(float4 pos:SV_POSITION,float4 normal:NORMAL):SV_TARGET
{
float4 col = 0;
for(int i=0; i < 2;++i)
{
col += saturate(dot(normal,LightDir[i])) * LightColor[i] ;
}
return col;
}
You are getting an AV because you have the wrong handling of the failed compiler output, you forgot to initialize both BErrorVS and BErrorPS to null, and you are trying to output BErrorVS when the VS succeeded, but the PS failed. It should be:
if(FAILED(hr))
{
printf("Error %08X %5s\n",hr,(char*)BErrorPS->GetBufferPointer());
MessageBox(hwnd,L"Pixel shader not created ",L"",0);
}
Also you should remember that BErrorVS and BErrorPS can be set to a non-null value even if SUCCEEDED(hr)) since it can be reporting only non-fatal warnings.
See HLSL, FXC, and D3DCompile

DirectX 11: Text output: HLSL/ InputLayout troubles

I've been search for a good text methodolgy recently and found one at http://www.braynzarsoft.net/Articles/index.php?p=VA&article=Easy-Font-Rendering-in-DirectX-11 , which is a good site. I can't seem to get it to run! I've resolved most of the errors but, however on debug, I get HLSL errors:
D3D11: ERROR: ID3D11DeviceContext::Draw: The Vertex Shader expects application provided input data (which is to say data other than hardware auto-generated values such as VertexID or InstanceID). Therefore an Input Assembler object is expected, but none is bound. [ EXECUTION ERROR #349: DEVICE_DRAW_INPUTLAYOUT_NOT_SET ]
Creeped? I am! Since this message is spamming like mad, the issue is most likely happening in my DrawText() function or a bad implementation in the initialize function (Below)
The InitializeGeneralResources() function:
void InfiniteText::InitializeGeneralResources(){
float textureWidth=1024.0f;
UINT numLetters=32;
D3DX11CompileFromFile(L"Font.hlsl", NULL, NULL, "FONT_VS", "vs_5_0",0,0,0,&FontvsBuffer,0,0);
D3DX11CompileFromFile(L"Font.hlsl", NULL, NULL, "FONT_PS", "ps_5_0",0,0,0,&FontpsBuffer,&ppErrorMsgs,0);
iD3D.Device->CreateVertexShader(FontvsBuffer->GetBufferPointer(),FontvsBuffer->GetBufferSize(), NULL, &Fontvs);
iD3D.Device->CreatePixelShader(FontpsBuffer->GetBufferPointer(),FontpsBuffer->GetBufferSize(), NULL, &Fontps);
ID3D11InputLayout* InLayout;
D3D11_INPUT_ELEMENT_DESC IEDesc[]={
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
{"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},
};
UINT NumElements = ARRAYSIZE(IEDesc);
iD3D.Device->CreateInputLayout(IEDesc,NumElements,FontvsBuffer->GetBufferPointer(),FontvsBuffer->GetBufferSize(),&InLayout);
iD3D.DeviceContext->IASetInputLayout(InLayout);
D3D11_SAMPLER_DESC FontSamplerDesc;
FontSamplerDesc.MaxAnisotropy=1;
FontSamplerDesc.AddressU=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.AddressV=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.AddressW=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.Filter=D3D11_FILTER_MIN_MAG_MIP_LINEAR;
FontSamplerDesc.MipLODBias=0.0f;
D3DX11CreateShaderResourceViewFromFile(iD3D.Device, L"Font.dds", NULL, NULL, &FontSRV, NULL);
iD3D.Device->CreateSamplerState(&FontSamplerDesc, &FontSRVSampler);
D3D11_BUFFER_DESC Vbufferdescription;
ZeroMemory(&Vbufferdescription, sizeof(Vbufferdescription));
Vbufferdescription.BindFlags=D3D11_BIND_VERTEX_BUFFER;
Vbufferdescription.Usage=D3D11_USAGE_DYNAMIC;
Vbufferdescription.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;
Vbufferdescription.ByteWidth=sizeof(VertexText)*6*numLetters;
Vbufferdescription.MiscFlags=0;
iD3D.Device->CreateBuffer(&Vbufferdescription, NULL, &FontVertexBuffer);
}
I have a rather simple HLSL file:
cbuffer ConstantBuffer:register( b0 )
{
float4x4 WVP;
}
struct VOut
{
float4 position : SV_POSITION;
float2 TexCoord : TEXCOORD0;
};
VOut FONT_VS(float4 position : POSITION, float2 TexCoord : TEXCOORD)
{
VOut output;
output.position = mul(position, WVP);
output.TexCoord = TexCoord;
return output;
}
float2 FONT_PS(float4 position : SV_POSITION, float2 TexCoord : TEXCOORD0) : SV_TARGET
{
return TexCoord;
}
(The DrawString() function)
bool InfiniteText::DrawString(char* Text, float xPos, float yPos){
int letterSize = sizeof(VertexText)*6;
int textSize = strlen(Text);
if(textSize > numLetters)
textSize=numLetters;
float cScreenWidth = 32.0f/iD3D.cWidth;
float cScreenHeight= 32.0f/iD3D.cHeight;
float TexelWidth= 32.0f/textureWidth;
D3D11_MAPPED_SUBRESOURCE MappedSub;
iD3D.DeviceContext->Map(FontVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedSub);
VertexText* Sprite = (VertexText*)MappedSub.pData;
const int indexA = static_cast<int>('A');
const int indexZ = static_cast<int>('Z');
for(int i=0; i<textSize;i++){
float thisStartX=xPos+(cScreenWidth*static_cast<char>(i));
float thisEndX=thisStartX + cScreenWidth;
float thisStartY=yPos;
float thisEndY=thisStartY + cScreenHeight;
Sprite[0].Translation=XMFLOAT3(thisEndX,thisEndY,1.0f);
Sprite[1].Translation=XMFLOAT3(thisEndX,yPos,1.0f);
Sprite[2].Translation=XMFLOAT3(thisStartX,yPos,1.0f);
Sprite[3].Translation=XMFLOAT3(thisStartX,yPos,1.0f);
Sprite[4].Translation=XMFLOAT3(thisStartX,thisEndY,1.0f);
Sprite[5].Translation=XMFLOAT3(thisEndX,thisEndY,1.0f);
UINT TexLookup=0;
UINT Letter= static_cast<int>(Text[i]);
if (Letter < indexA || Letter > indexZ){
TexLookup=(indexA - indexZ) +1;
}
else{
TexLookup=(Letter-indexA);
}
float texStart = 0.0f + (TexelWidth*static_cast<float>(TexLookup));
float TexEnd = texStart + TexelWidth;
Sprite[0].TextureCoord = XMFLOAT2(TexEnd,0.0f);
Sprite[1].TextureCoord = XMFLOAT2(TexEnd,1.0f);
Sprite[2].TextureCoord = XMFLOAT2(texStart,1.0f);
Sprite[3].TextureCoord = XMFLOAT2(texStart,1.0f);
Sprite[4].TextureCoord = XMFLOAT2(texStart,0.0f);
Sprite[5].TextureCoord = XMFLOAT2(TexEnd,0.0f);
Sprite= Sprite + 6;
}
iD3D.DeviceContext->Unmap(FontVertexBuffer,0); //MAP END
UINT stride=sizeof(VertexText);
UINT offset=0;
iD3D.DeviceContext->VSSetShader(iText.Fontvs,0,0);
iD3D.DeviceContext->PSSetShader(iText.Fontps,0,0);
//Projection=XMMatrixPerspectiveFovLH(XM_PIDIV2, 1.0, 0.0f, 1000.0f);
Projection=iD3D.mProjection;
iD3D.WorldCB.mWorldVP=XMMatrixTranspose(Projection);
iD3D.DeviceContext->UpdateSubresource(iD3D.MatrixBuffer, 0, NULL, &iD3D.WorldCB, 0, 0);
iD3D.DeviceContext->VSSetConstantBuffers(0,1,&iD3D.MatrixBuffer);
iD3D.DeviceContext->IASetVertexBuffers(0,1, &iText.FontVertexBuffer, &stride, &offset);
iD3D.DeviceContext->PSSetShaderResources(0,1, &iText.FontSRV);
iD3D.DeviceContext->PSSetSamplers(0,1,&iText.FontSRVSampler);
iD3D.DeviceContext->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
iD3D.DeviceContext->Draw(6*textSize,0);
return true;
}
If you made it this far, thank you. I think that it might be that my .hlsl file might not be configured properly to receive textures, and I might need to know how textures interface properly with the shader to produce the output. Thanks!
The HLSL was not written correctly to include Texture2D x: register( t0 ) or SamplerState x : register( s0 ), taking in necessary resources for the texture. Another problem has surfaced, but this question has been solved.

DirectX 11 Compute Shader 5 loop

I have the following compute shader code for computing depth of field. However, very unusually, the loop executes just once, even if g_rayCount is 10. Please have a look in the main function raycastercs where the for loop lies.
//--------------------------------------------------------------------------------------
// Compute Shader
//-------------------------------------------------------------------------------------
SamplerState SSLinear
{
Filter = Min_Mag_Linear_Mip_Point;
AddressU = Border;
AddressV = Border;
AddressW = Border;
};
float3 CalculateDoF(uint seedIndex, uint2 fragPos)
{
;
}
[numthreads(RAYCASTER_THREAD_BLOCK_SIZE, RAYCASTER_THREAD_BLOCK_SIZE, 1)]
void RaycasterCS(in uint3 threadID: SV_GroupThreadID, in uint3 groupID: SV_GroupID, in uint3 dispatchThreadID :SV_DispatchThreadID)
{
uint2 fragPos = groupID.xy * RAYCASTER_THREAD_BLOCK_SIZE + threadID.xy;
float4 dstColor = g_texFinal[fragPos];
uint seedIndex = dispatchThreadID.x * dispatchThreadID.y;
float3 final = float3(0, 0, 0);
float color = 0;
[loop][allow_uav_condition]
for (int i = 0; i < g_rayCount; ++i);
{
float3 dof = CalculateDoF(seedIndex, fragPos);
final += dof;
}
final *= 1.0f / ((float) g_rayCount);
g_texFinalRW[fragPos] = float4(final, 1);
}
//--------------------------------------------------------------------------------------
technique10 Raycaster
{
pass RaycastDefault
{
SetVertexShader(NULL);
SetGeometryShader(NULL);
SetPixelShader(NULL);
SetComputeShader(CompileShader(cs_5_0, RaycasterCS()));
}
}
Remove the semicolon at the end of the for statement
for (int i = 0; i < g_rayCount; ++i) // removed semicolon
{
float3 dof = CalculateDoF(seedIndex, fragPos);
final += dof;
}
As I guess you know, the semicolon was just running an empty for loop, then the code in braces was thereafter executed just once.

GLSL for loop acting weird

I tried to implement something in glsl to do texture splatting, but the for loop is acting weird and gives different results for code that does exactly the same.
Code 1:
for(int i = 0; i < 5; ++i) {
if(i == 1) {
float fade = texture2D(alphaTextures[i], texCoord.st).r;
vec4 texCol = texture2D(textures[i], texCoord.ba);
texColor = mix(texColor, texCol, fade);
}
}
Code 2:
for(int i = 0; i < 6; ++i) {
if(i == 1) {
float fade = texture2D(alphaTextures[i], texCoord.st).r;
vec4 texCol = texture2D(textures[i], texCoord.ba);
texColor = mix(texColor, texCol, fade);
}
}
The if statement is just for testing purposes so that it should give the same result. The only difference is the loop condition. I really have no idea why only Code 1 gives the correct result. Here are two pictures:
Code1
Code2
The result should be like in picture 1.
According to this answer, you can't iterate over a sampler array. The index alphaTextures[i] is invalid, you can only use alphaTextures[1].
This changes in GLSL 4.00+ (OpenGL 4.0+), where you can have a variable index, but it cannot be from a shader input/derived value.
One reason could be that Graphic processors don't like branched texture fetches.
Try this instead:
for(int i = 0; i < 6; ++i) {
float fade = texture2D(alphaTextures[i], texCoord.st).r;
vec4 texCol = texture2D(textures[i], texCoord.ba);
if(i == 1) {
texColor = mix(texColor, texCol, fade);
}
}
(disclaimer) i am only guessing and this error is really weird.