Is this a bug in DirectX9 Effect Compiler? "Invalid input semantics - POSITIONT0" - c++

I am trying to compile a very simple Effect Shader targeting DirectX9 and shader model 2. I am trying to pass in directly the screen coords for the vertex Positions instead of multiplying by a world, view, and projection matrices so I use the POSITIONT semantic instead of the POSTION0 semantic in the VertexShaderInput structure. However when I try to compile the shader using
fxc.exe /Od /Zi /T fx_2_0 /Fo simple.fxo simple.fx
I get the following error: "error X4502: Invalid input semantics - POSITIONT0"
It seems to be automatically adding a 0 to the end of the semantic for some reason. This seems like I bug to me because POSITIONT is clear described as a valid input semantic here:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx#PS
and it is the only one that does not allow extra integers to be appended at the end of the semantic.
EDIT: I have just discovered that if I change POSITIONT to POSITIONT1 it works fine. This seem counter to what the documentation above describes.
Contents of simple.fx:
struct VertexShaderInput
{
float4 Position : POSITIONT;
float4 Color : COLOR0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
output.Position = input.Position;
output.Color = input.Color;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return input.Color;
}
technique Ambient
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

For legacy Direct3D9 there is a special D3DDECLUSAGE_POSITIONT which means to just skip vertex processing. Therefore, you can only use POSITIONT in the PIXEL SHADER input--i.e. it can't be used in a VERTEX SHADER at all.
Change your shader to use POSITION or POSITION0.

Related

How to "fully bind" a constant buffer view to a descriptor range?

I am currently learning DirectX 12 and trying to get a demo application running. I am currently stuck at creating a pipeline state object using a root signature. I am using dxc to compile my vertex shader:
./dxc -T vs_6_3 -E main -Fo "basic.vert.dxi" -D DXIL "basic.vert"
My shader looks like this:
#pragma pack_matrix(row_major)
struct VertexData
{
float4 Position : SV_POSITION;
float4 Color : COLOR;
};
struct VertexInput
{
float3 Position : POSITION;
float4 Color : COLOR;
};
struct CameraData
{
float4x4 ViewProjection;
};
ConstantBuffer<CameraData> camera : register(b0, space0);
VertexData main(in VertexInput input)
{
VertexData vertex;
vertex.Position = mul(float4(input.Position, 1.0), camera.ViewProjection);
vertex.Color = input.Color;
return vertex;
}
Now I want to define a root signature for my shader. The definition looks something like this:
CD3DX12_DESCRIPTOR_RANGE1 descriptorRange;
descriptorRange.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND);
CD3DX12_ROOT_PARAMETER1 rootParameter;
rootParameter.InitAsDescriptorTable(1, &descriptorRange, D3D12_SHADER_VISIBILITY_VERTEX);
ComPtr<ID3DBlob> signature, error;
CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init_1_1(1, &rootParameter, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
::D3D12SerializeVersionedRootSignature(&rootSignatureDesc, &signature, &error);
ComPtr<ID3D12RootSignature> rootSignature;
device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature));
Finally, I pass the root signature along other state variables to the pipeline state object:
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelineStateDescription = {};
// ...
pipelineStateDescription.pRootSignature = rootSignature.Get();
ComPtr<ID3D12PipelineState> pipelineState;
device->CreateGraphicsPipelineState(&pipelineStateDescription, IID_PPV_ARGS(&pipelineState));
However, no matter what I do, the device keeps on complaining about the root signature not matching the vertex shader:
D3D12 ERROR: ID3D12Device::CreateGraphicsPipelineState: Root Signature doesn't match Vertex Shader: Shader CBV descriptor range (BaseShaderRegister=0, NumDescriptors=1, RegisterSpace=0) is not fully bound in root signature
[ STATE_CREATION ERROR #688: CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH]
D3D12: BREAK enabled for the previous message, which was: [ ERROR STATE_CREATION #688: CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH ]
I am confused about what this error is trying to tell me, since I clearly have a constant buffer bound to register(b0, space0). Or does it mean that I have to allocate a descriptor from a heap before creating the pipeline state object?
I also tried defining a root signature within the shader itself:
#define ShaderRootSignature \
"RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT ), " \
"DescriptorTable( CBV(b0, space = 0, numDescriptors = 1, flags = DATA_STATIC ) ), "
... and compiling it using [RootSignature(ShaderRootSignature)], or specifying -rootsig-define "ShaderRootSignature" for dxc. Then I tried loading the signature as suggested here, however both approaches fail, since the root signature could not be read from the shader bytecode.
Any clarification on how to interpret the error message would be much appreciated, since I really do not know what the binding in a root signature means in this context. Thanks in advance! 🙂
Long story short: shader visibility in DX12 is not a bit field, like in Vulkan, so setting the visibility to D3D12_SHADER_VISIBILITY_VERTEX | D3D12_SHADER_VISIBILITY_PIXEL results in the parameter only being visible to the pixel shader. Setting it to D3D12_SHADER_VISIBILITY_ALL solved my problem.

X3501 'main': entrypoint not found when compiling DirectX11 .hlsl shaders in VS2015

I am trying to follow this tutorial: https://learn.microsoft.com/en-us/windows/uwp/gaming/creating-shaders-and-drawing-primitives
I added two files, named SimplePixelShader.hlsl and `SimpleVertexShader.hlsl to my project with the contents below:
On each file, I went into (Right click file->Properties),
Set it to proper configuration (Debug X64) and changed the fields:
General->Excluded From build = blank
General->Content = blank
General->Item Type = HLSL Compiler
HLSL Compiler->Entrypoint Name = blank (deleted main)
HLSL Compiler->Shader Type = Pixel Shader (/ps)
HLSL Compiler->Shader Model = Shader Model 4 Level 9_1 (/4_0_level_9_1)
All Options->Shader Type = Pixel Shader (/ps)
All Options->Entrypoint Name = blank (deleted main)
All Options->Shader Model = Shader Model 4 Level 9_1 (/4_0_level_9_1)
And then made the sam echanges with corresponding Vertex Shader entries for the SimpleVertexShader.hlsl
But no matter what I try, I still get the same error when compiling:
X3501 'main':entrypoint not found
How is this possible if I deleted the entrypoints from all fields? What am I missing?
Thanks,
SimpleVertexShader.hlsl:
struct VertexShaderInput
{
DirectX::XMFLOAT2 pos : POSITION;
};
struct PixelShaderInput
{
float4 pos : SV_POSITION;
};
PixelShaderInput SimpleVertexShader(VertexShaderInput input)
{
PixelShaderInput vertexShaderOutput;
// For this lesson, set the vertex depth value to 0.5, so it is guaranteed to be drawn.
vertexShaderOutput.pos = float4(input.pos, 0.5f, 1.0f);
return vertexShaderOutput;
}
Here is the code in SimplePixelShader.hlsl:
struct PixelShaderInput
{
float4 pos : SV_POSITION;
};
float4 SimplePixelShader(PixelShaderInput input) : SV_TARGET
{
// Draw the entire triangle yellow.
return float4(1.0f, 1.0f, 0.0f, 1.0f);
}
Ok I did some testing, it seems that when you leave the Entrypoint Name field blank, it tries to use main. Instead I just typed in SimpleVertexShader and SimplePixelShader accordingly, and they both compiled. Thanks
I can add this for DX-12: when you use more than 1 shader file, I found consistent hurdles with the VS-2019 HLSL Compiler. This "main" error message always appears when 2 files both use "HLSL Compiler" . You can set the entry points to avoid it, but then, the program won't be able to compile your shader at runtime, for some reason.
Consider to skip things alltogether: just replace the type "HLSL Compiler" into an unassigned (default) "Custom Build tool". That will (by default) just copy your HLSL next to your exe-application. In DX-12 you'll compile the shader yourself with D3DCompileFromFile(), so there will be no issue in the end.

DirectX11 pixel shader in pipeline is missing

I'm writing a program which displays a MS3D model using DirectX, and unfortunately, the result shows nothing on the screen.
When I use the Graphics Debugger from Visual Studio 13, I notice that the pixel shader is missing from the pipeline, as it is shown in the below picture
This is my pixel shader source code:
cbuffer SkinningTransforms
{
matrix WorldMatrix;
matrix ViewProjMatrix;
};
//--------------------------------------------------------------------------------
// Inter-stage structures
//--------------------------------------------------------------------------------
struct VS_INPUT
{
float3 position : POSITION;
int4 bone : BONEID;
float4 weights : BONEWEIGHT;
float3 normal : NORMAL;
float3 tangent : TANGENT;
float2 tex : TEXCOORD;
};
//--------------------------------------------------------------------------------
struct VS_OUTPUT
{
float4 position : SV_Position;
float3 normal : NORMAL;
float3 light : LIGHT;
float2 tex : TEXCOORDS;
};
Texture2D ColorTexture : register( t0 );
SamplerState LinearSampler : register( s0 );
//--------------------------------------------------------------------------------
VS_OUTPUT VSMAIN( in VS_INPUT input )
{
VS_OUTPUT output;
//Transform vertex and pass them to the pixel shader
return output;
}
//--------------------------------------------------------------------------------
float4 PSMAIN( in VS_OUTPUT input ) : SV_Target
{
// Calculate the lighting
float3 n = normalize( input.normal );
float3 l = normalize( input.light );
float4 texColor = ColorTexture.Sample( LinearSampler, input.tex );
float4 color = texColor * (max(dot(n,l),0) + 0.05f );
return( color );
}
As I was known from Graphics Debugger, all of the graphics event are right. I listed in below important events, which might be relating to Pixel Shader:
106:(obj:4) ID3D11Device::CreateDepthStencilView(obj:24,NULL,obj:25)*
108:(obj:5) ID3D11DeviceContext::OMSetRenderTargets(8,{obj:1,NULL,NULL,NULL,NULL,NULL,NULL,NULL},obj:25)*
109:(obj:5) ID3D11DeviceContext::ClearRenderTargetView(obj:1,addr:21)*
111:(obj:5) ID3D11DeviceContext::ClearDepthStencilView(obj:25,1,1.000f,0)*
119:(obj:4) ID3D11Device::CreateSamplerState(addr:24,obj:27)*
134:(obj:4) ID3D11Device::CreatePixelShader(addr:27,21056,NULL,obj:30)*
135:CreateObject(D3D11 Pixel Shader,obj:30)
136:(obj:5) ID3D11DeviceContext::PSSetShader(obj:30,NULL,0)*
137:(obj:5) ID3D11DeviceContext::PSSetSamplers(0,1,{obj:27})*
139:(obj:4) ID3D11Device::CreateTexture2D(addr:28,addr:5,obj:31)*
140:CreateObject(D3D11 Texture2D,obj:31)
142:(obj:4) ID3D11Device::CreateShaderResourceView(obj:31,NULL,obj:32)*
143:CreateObject(D3D11 Shader Resource View,obj:32)
144:(obj:5) ID3D11DeviceContext::PSSetShaderResources(0,1,{obj:32})*
146:(obj:4) ID3D11Device::CreateRasterizerState(addr:29,obj:33)*
147:CreateObject(D3D11 Rasterizer State,obj:33)
152:(obj:5) ID3D11DeviceContext::RSSetState(obj:33)*
154:(obj:5) ID3D11DeviceContext::RSSetViewports(1,addr:30)*
156:(obj:4) ID3D11Device::CreateBlendState(addr:11,obj:34)*
157:CreateObject(D3D11 Blend State,obj:34)
159:(obj:5) ID3D11DeviceContext::OMSetBlendState(obj:34,addr:31,-1)*
162:(obj:4) ID3D11Device::CreateDepthStencilState(addr:32,obj:35)*
163:CreateObject(D3D11 Depth-Stencil State,obj:35)
165:(obj:5) ID3D11DeviceContext::OMSetDepthStencilState(obj:35,0)*
I debugged all of the function in the above list, and all of them return OK. Nothing wrong.
My question is what is the reason the pixex shader is missing from pipleline, which in turn may result in the empty screen.
Adding to the other answers, constant buffer organization can be the cause of this problem. In my case, the pixel shader was missing from the pipeline but also the vertex shader wasn't transforming the vertices correctly. Upon inspection it was revealed that the world matrix had incorrect values because the boolean value at the top of the constant buffer was causing data misalignment. HLSL packs data into 16 byte boundries which are so called vectors that have 4 components. A boolean is 4 bytes which is the same with a float.
cbuffer cbPerObject : register( b1 )
{
bool gUseTexture ;
row_major float4x4 gWorld ;
row_major float4x4 gWorldInvTranspose ;
row_major float4x4 gWorldViewProj ;
row_major float4x4 gTexTransform ;
Material gMaterial ;
} ;
So in the constant buffer above, the boolean + the first 3 components of the first row of the world matrix gets mapped to the first vector and this causes everything to get shifted by 3 components, misaligning the world matrix (and the other matrices following and possibly other data).
Two possible solutions :
Move the boolean to the end of the structure. I did this and it worked.
Add a 3-component sized padding variable between the world matrix and the boolean.
I tried this by adding an XMFLOAT3 in the c++ structure and a float3 in HLSL. This worked too.
Long story short, pay attention to HLSL packing.
EDIT : At the time I thought these methods worked, as all variables except the boolean had correct values. I didn't use the bool at the time so I assumed that was fine too. Turns out it's not.
HLSL bools and c++ bools have different sizes. HLSL bools are 4 bytes, whereas c++ bools are implementation defined (1 byte on my machine for example). Anyways, they will most likely be different and it causes problems.
Either use Windows BOOL type or another appropriately-sized value like an int or a uint.
Take a look at https://gamedev.stackexchange.com/a/22605.
Also the second to last post here explains the situation clearly (this link is referenced in the answer in the gamedev link above also).
Beware though because packing is still an issue. Even if you use a BOOL or a uint or whatever, if you place it in the beginning in the above structure as before, you will get incorrect values in your constant buffer. So take both of these issues (data alignment and the boolean problem) into consideration when working with constant buffers.
As I wrote in my comment, I had a similar problem.
In my case, the pixel shader was correctly bound (see http://msdn.microsoft.com/en-us/library/jj191650.aspx). Furthermore, I ensured by debugging the vertex shader that the result of the Transformation should be visible and hence should generate visible fragments.
In this case (which seems to be the same you describe), make sure that your rasteriser state is correct. You might want to check that it is actually set (using the graphics object view of the immediate context) and that it lets your geometry through. For debugging purposes, I found it helpful disabling backface culling. I use
D3D11_RASTERIZER_DESC rasterDesc;
ZeroMemory(&rasterDesc, sizeof(rasterDesc));
rasterDesc.CullMode = D3D11_CULL_MODE::D3D11_CULL_NONE;
rasterDesc.FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID;

loading from RWTexture2D<float4> in a compute shader

I understand there's a limitation in HLSL shader model 5.0 where one cannot load data from a non-scalar typed RWTexture2D resource. That is to say, the following is illegal:
RWTexture2D<float4> __color;
float4 c = __color[PixelCoord]; // error here
So what exactly is the workaround? I'm trying to accumulate into a float4 buffer in a compute shader, like so:
c = computeColor( ... );
__color[PixelCoord] += c;
Try doing:
float4 c = __color.Load( int3( UV, 0 ) );
Where UV is the xy coordinate in screen space (0 -> Resolution) of the texel you want to sample.
If you need to write to it, make sure it is bound from a UAV and not a shader resource view.

HLSL and ID3DXFont/ID3DXSprite

I've started at the beginning, and my code will capably display the grand total of some text. I've been adding support for sprites. The trouble that I've run in to, is that it doesn't seem to recognize my HLSL. I set the technique, began it, began the pass, drew the sprites, flushed them, ended the pass, the technique. And D3D comes up with this little "Using FF to PS converter" in the VS output. Same for VS. I'm not trying to do anything advanced with my HLSL - just use it and get a little more familiar with it and make sure I know how to implement it. That's C++0x auto, by the way, so automatic type deduction (because I'm lazy).
#define D3DCALL(a) { auto __ = a; if (FAILED(__)) DXTrace(__FILE__, __LINE__, __, WIDEN(#a), TRUE); }
D3DCALL(spriteeffect->SetTechnique(spritetechnique));
D3DCALL(spriteeffect->Begin(&passes, NULL));
D3DCALL(spriteeffect->BeginPass(0)); // We know this is zero.
D3DCALL(sprite->Begin(D3DXSPRITE_OBJECTSPACE | D3DXSPRITE_DO_NOT_ADDREF_TEXTURE | D3DXSPRITE_SORT_TEXTURE | D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_FRONTTOBACK));
RenderAndCleanUp(common->sprites);
D3DCALL(sprite->End());
D3DCALL(spriteeffect->EndPass());
D3DCALL(spriteeffect->End());
where RenderAndCleanUp is a simple templated function that loops through the sprites, destroys those that need to be, and renders the rest, and common->sprites is a simple vector of all the sprite objects. Since DXTrace never goes off, I'll guarantee that none of the functions fail. I've also set the control panel to max debugging.
I checked the D3DXHANDLEs and they're all non-NULL. It doesn't report any compilation errors, or any errors or warnings.
// Contains the HLSL for sprites.
// Based on transform.fx, by Frank Luna.
// FX parameter (global variable to the shader).
uniform extern float4x4 gWVP;
// Structure
struct OutputVS
{
float4 posH : POSITION0;
float4 color : COLOR0;
};
// Vertex shader
OutputVS SpriteVS(float3 post : POSITION0,
float4 col : COLOR0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;
outVS.posH = mul(float4(post, 1.0f), gWVP); // Transform
outVS.color = col;
// Done--return the output.
return outVS;
}
// Pixel shader - take the original colour of the pixel and just return it. Nothing fancy.
float4 SpritePS( float4 col : COLOR0 ) : COLOR
{
return col;
}
technique Sprite
{
pass P0
{
// Specify the vertex and pixel shader associated
// with this pass.
vertexShader = compile vs_3_0 SpriteVS();
pixelShader = compile ps_3_0 SpritePS();
}
}
This is native C++ looking at Direct3D9.
AFAIR D3DXSprite and D3DXFont rendering is implemented inside of D3DX itself. So, it sets its own shaders, states (emulates fixed-function pipeline) and renders text/sprites. So, your shaders and states have no effect on these objects.
You may implement your own text/sprite rendering subsystem, it's not so hard. Another vote for this is that Microsoft officially deprecated D3DX.