Sign in to follow this  
Mortoc

D3D11 Shader Compile question

Recommended Posts

So I'm trying to build a demo using DirectX 11. I've got a simple vertex and pixel shader, the file compiles with no errors or warnings (HRESULT S_OK), but when I try to create either the pixel or the vertex shader, I get HRESULT E_INVALIDARG. Is there anything I can do to get more information about the error? I'm not even sure which argument is invalid. Shader file:
cbuffer PerScene : register( b0 )
{
	row_major float4x4 cameraProjection : packoffset( c0 );
}

struct VertexShaderResult
{
	float4 Pos : SV_POSITION;
	float3 Norm : NORMAL0;
	float2 UV : TEXCOORD0;
	float4 Color : COLOR0;
};

VertexShaderResult vsMain
(
	float4 pos : POSITION, 
	float3 norm : NORMAL, 
	float2 uv : TEXCOORD, 
	float4 color : COLOR
)
{
	VertexShaderResult output = (VertexShaderResult)0;

	output.Pos = mul(pos, cameraProjection);
	output.Norm = norm;
	output.UV = uv;
	output.Color = color;

    return output;
}


float4 psMain( VertexShaderResult vertexIn ) : SV_Target
{
    return vertexIn.Color;
}
Compile shader function:
HRESULT CompileShaderFromFile( const path& shaderFile, const string& entryPoint, const string& shaderModel, ID3DBlob** blobOut )
{
	HRESULT result = S_OK;

	// Open the file
	HANDLE file = CreateFileA
	( 
		shaderFile.file_string().c_str(), 
		GENERIC_READ, 
		FILE_SHARE_READ, 
		0, 
		OPEN_EXISTING,
		FILE_FLAG_SEQUENTIAL_SCAN, 
		0 
	);

	if( INVALID_HANDLE_VALUE == file )
	{
		result = E_FAIL;
	}
	else
	{
		// Allocate a buffer to read the file in to
		DWORD bytesRead;
		LARGE_INTEGER fileSize;
		GetFileSizeEx( file, &fileSize );
		BYTE* fileData = new BYTE[ fileSize.LowPart ];
		if( fileData == 0 )
		{
			result = E_OUTOFMEMORY;
		}
		else if( !ReadFile(file, fileData, fileSize.LowPart, &bytesRead, 0) )
		{
			result = E_FAIL;
		}
		else
		{
			// Compile the shader
			ID3DBlob* errorBlob = 0;
			result = D3DCompile
			( 
				fileData, 
				fileSize.LowPart, 
				"none", 
				0, 
				0, 
				entryPoint.c_str(), 
				shaderModel.c_str(), 
				D3D10_SHADER_ENABLE_STRICTNESS | D3D10_SHADER_DEBUG, 
				0, 
				blobOut, 
				&errorBlob 
			);

			if( FAILED(result) )
			{
				if( errorBlob != 0 )
				{
					AssertHRESULT
					(
						result, 
						format("Error compiling shader(%1%):\n%2%") % 
							shaderFile.filename() % 
							(char*)errorBlob->GetBufferPointer()
					);
				}
				else
				{
					AssertHRESULT
					( 
						result, 
						format("Error loading shader(%1%)") % 
							shaderFile.filename() 
					);
				}
			}
		}

		delete []fileData;
		CloseHandle( file );
	}
	return result;
}
Create VertexShader:

// in .h
class VertexShader : public Shader
{
public:
	VertexShader(Device* device, const boost::filesystem::path& filepath);
	virtual ~VertexShader();

	virtual void Apply(ID3D11DeviceContext* context) const;
	virtual ID3DBlob* GetBlob() const { return mBlob; }

private:
	ID3DBlob* mBlob;
	ID3D11VertexShader* mShader;
	ID3D11InputLayout* mInputLayout;
};

// in .cpp
VertexShader::VertexShader( Device* device, const boost::filesystem::path& filepath )
{
	// Compile Shader
	HRESULT compileResult = CompileShaderFromFile
	(
		filepath, 
		Config::GetData<string>("vs_entry_func", "vsMain"),
		Config::GetData<string>("vs_shader_model", "vs_5_0"),
		&mBlob
	);
	AssertHRESULT(compileResult, format("Error compiling shader(%1%)") % filepath);
	Assert(mBlob != 0);

	// Build the input data layout
	mInputLayout = 0;
	HRESULT createLayoutResult = device->GetDxDevice()->CreateInputLayout
	(
		Mesh::Vertex::InputElementDescription(), 
		Mesh::Vertex::ElementCount, 
		mBlob->GetBufferPointer(), 
		mBlob->GetBufferSize(),
		&mInputLayout
	);
	AssertHRESULT(createLayoutResult, format("Unable to create input layout for shader: %1%") % filepath);
	AssertMsg(mInputLayout != 0, format("Unable to create input layout for shader: %1%") % filepath);
	
	// Build the vertex shader from the compiled blob
	mShader = 0;
	HRESULT createVertexShader = device->GetDxDevice()->CreateVertexShader
	(
		mBlob->GetBufferPointer(),
		mBlob->GetBufferSize(),
		0,
		&mShader
	);
	AssertHRESULT(createVertexShader, format("Error creating vertex shader(%1%)") % filepath);
}

Share this post


Link to post
Share on other sites
Which shader model are you compiling for? Even if it is a simple VS/PS, if you try to compile for an unavailable shader model then it will fail...

EDIT: sorry, I just reread your post and saw that it is already compiling ok... DieterVW's suggestion is a good idea - the debug output should be clear enough to see where the error is coming from.

Share this post


Link to post
Share on other sites
Hey, thanks for the help guys. Turns out it was just a silly mistake and I didn't know how to get to the debug info that would help (I had some config settings that were trying to make a ps_2_0 shader).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this