How do I solve E_INVALIDARG error on ID3D11Device::CreateVertexShader method?

CDev-8220 220 Reputation points
2023-10-09T17:36:32.0033333+00:00

I'm getting an E_INVALIDARG error when creating the vertex and pixel shaders.

I tried two methods, both of which failed.

There is no error when compiling the shaders, so I assume the files are okay.

Here are the shader files code:

// VERTEX SHADER FILE
////////////////////////////
//        GLOBALS         //
////////////////////////////
cbuffer MatrixBuffer
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};

////////////////////////////
//        TYPEDEFS        //
////////////////////////////
struct VertexInputType
{
    float4 position : POSITION;
    float4 color : COLOR;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

////////////////////////////
//      Vertex Shader     //
////////////////////////////
PixelInputType ColorVertexShader(VertexInputType input)
{
    PixelInputType output;
    
    // Change the position vector to be 4 units for proper matrix calculations.
    input.position.w = 1.0f;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);
    
    // Store the input color for the pixel shader to use.
    output.color = input.color;
    
    return output;
}


// PIXEL SHADER FILE
////////////////////////////
//        TYPEDEFS        //
////////////////////////////
struct PixelInputType
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

////////////////////////////
//      Pixel Shader      //
////////////////////////////
float4 ColorPixelShader(PixelInputType input) : SV_TARGET
{
    return input.color;
}

Here is the shader initialization code:

static ID3D10Blob* vsBlob = nullptr, * psBlob = nullptr;
static ID3D11VertexShader* cs_vertexShader;
static ID3D11PixelShader* cs_pixelShader;
static ID3D11InputLayout* cs_layout;
static ID3D11Buffer* cs_matrixBuffer;
static int numShaders = 0;

bool ColorShader_InitializeShader(
	ID3D11Device* device, 
	ID3D11DeviceContext* deviceContext, 
	HWND hwnd, 
	const wchar_t* Filename, 
	std::vector<char>& shaderByteCode
) {
	HRESULT hr = 0;
	ID3D10Blob* errorMessage = nullptr;
	D3D11_INPUT_ELEMENT_DESC polygonLayout[2]{};
	unsigned int numElements = 0;
	D3D11_BUFFER_DESC matrixBufferDesc{};

	ID3DBlob* pErrorBlob = nullptr;
	hr = D3DCompileFromFile(
		Filename,
		nullptr,
		nullptr,
		pEntryPoint[numShaders],
		pTarget[numShaders],
		iShaderFlags,
		0,
		&ppCodeBlob,
		&pErrorBlob
	);
	if (FAILED(hr)) {
		// If the shader failed to compile it should have writen something to the error message.
		if (errorMessage) {
			ColorShader_OutputErrorMessage(errorMessage, hwnd, Filename);
		}
		// If there was nothing in the error message then it simply could not find the shader file itself.
		else {
			MessageBox(hwnd, Filename, L"Missing Shader File", MB_OK);
		}

		return false;
	}

	// Create the vertex and pixel shader from the buffer.
	if (numShaders == 0) {
		if (FAILED(hr = device->CreateVertexShader(
			vsBlob->GetBufferPointer(), // &shaderByteCode[0], // 
			vsBlob->GetBufferSize(), // shaderByteCode.size(), // 
			NULL,
			&cs_vertexShader
		)))
		{
			return false;
		}
	}
	else {
		hr = device->CreatePixelShader(
			psBlob->GetBufferPointer(), // &shaderByteCode[0], // 
			psBlob->GetBufferSize(), // shaderByteCode.size(), // 
			NULL,
			&cs_pixelShader
		);
		if (FAILED(hr)) {
			return false;
		}
	}

	// Now setup the layout of the data that goes into the shader.
	// This setup needs to match the VertexType stucture in the ModelClass and in the shader.
	polygonLayout[0].SemanticName = "POSITION";
	polygonLayout[0].SemanticIndex = 0;
	polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	polygonLayout[0].InputSlot = 0;
	polygonLayout[0].AlignedByteOffset = 0;
	polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[0].InstanceDataStepRate = 0;

	polygonLayout[1].SemanticName = "COLOR";
	polygonLayout[1].SemanticIndex = 0;
	polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	polygonLayout[1].InputSlot = 0;
	polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[1].InstanceDataStepRate = 0;

	// Get a count of the elements in the layout.
	numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

	// Create the vertex input layout.
	hr = device->CreateInputLayout(
		polygonLayout, 
		numElements,
		vsBlob->GetBufferPointer(), // &shaderByteCode[0], // 
		vsBlob->GetBufferSize(), // shaderByteCode.size(), // 
		&cs_layout
	);
	if (FAILED(hr)) {
		return false;
	}

	// Setup the description of the dynamic matrix constant buffer that is in the vertex shader.
	matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
	matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
	matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	matrixBufferDesc.MiscFlags = 0;
	matrixBufferDesc.StructureByteStride = 0;

	// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
	hr = device->CreateBuffer(&matrixBufferDesc, NULL, &cs_matrixBuffer);
	if (FAILED(hr)) {
		return false;
	}

	return true;
}

HRESULT ColorShader_BuildShapesVertexLayout(
	ID3D11Device* device, std::vector<char>& shaderByteCode, ID3D11InputLayout*& inputLayout) {
	HRESULT hr = 0;
	unsigned int numElements = 0;
	
	assert(!inputLayout);
	assert(!shaderByteCode.empty());

	// Create the vertex input layout for land and screen quad
	D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
	{
		{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
		{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}
	};

	// Get a count of the elements in the layout.
	numElements = sizeof(vertexDesc) / sizeof(vertexDesc[0]);

	// Create the input layout
	//if (inputLayout != NULL) inputLayout->Release();
	hr = device->CreateInputLayout(
		vertexDesc, numElements, &shaderByteCode[0], shaderByteCode.size(), &inputLayout);

	return hr;
}

void ColorShader_ComputeShaderByteCode(
	const std::wstring& fileName, std::vector<char>& shaderByteCode, const int& index) {
	assert(!fileName.empty());

	// Clear vector content
	shaderByteCode.clear();

	// Open shader file, compile it and 
	std::ifstream fin;
	fin.open(fileName.c_str(), std::ios::binary);

	assert(fin.is_open());

	fin.seekg(0, std::ios_base::end);
	size_t size = static_cast<size_t> (fin.tellg());
	fin.seekg(0, std::ios_base::beg);
	shaderByteCode.resize(size);
	fin.read(&shaderByteCode[index], size);
	fin.close();
}

bool ColorShader_Initialize(
	ID3D11Device* device, ID3D11DeviceContext* deviceContext, HWND hwnd) {
	HRESULT hr = S_OK;
	bool result = false;

	ID3D10Blob* errorMessage = 0;
	string shaderfile = "", ext[2]{ "vs", "ps" };

	
#ifdef _DEBUG
	/* Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	Setting this flag improves the shader debugging experience, but still allows the
	shaders to be optimized and to run exactly the way they will run in the release
	configuration of this program. */
	iShaderFlags |= D3DCOMPILE_DEBUG;

	/* Disable optimizations to further improve shader debugging */
	iShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif

	for (int s = 0; s < 2; s++) {
		shaderfile = "color." + ext[s];
		sourceFileName = "C:\\shader\\" + shaderfile;

		shaderFile = sourceFileName;

		pcstrFileName = shaderFile.c_str();
		wstring ws(shaderFile.begin(), shaderFile.end());

		// Store shader byte code, used to create a shader.
		std::vector<char> shaderByteCode;
		ColorShader_ComputeShaderByteCode(ws, shaderByteCode, s);

		if (s == 0) {
			const wchar_t* vsFilename = L"C:\\shader\\color.vs";

			// Load Vertex Shader
			D3DReadFileToBlob(L"C:\\shader\\color.vs", &vsBlob);

			result = ColorShader_InitializeShader(
				pD3D11Device,
				pD3D11DeviceContext,
				hwnd,
				vsFilename,
				shaderByteCode
			);
			if (result) {
				numShaders += 1;
			}
			else {
				ColorShader_BuildShapesVertexLayout(pD3D11Device, shaderByteCode, cs_layout);

				hr = device->CreateVertexShader(
					&shaderByteCode[0], 
					shaderByteCode.size(), 
					nullptr,
					&cs_vertexShader
				);
				if (SUCCEEDED(hr)) {
					D3D11_INPUT_ELEMENT_DESC inputDescription[] =
					{
						{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
						{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
					};

					// Before cleaning up the data, create the input layout
					if (inputDescription) {
						if (cs_layout != NULL) cs_layout->Release();
						hr = device->CreateInputLayout(
							inputDescription,
							2, // Number of elments inside of Description
							&shaderByteCode[0], 
							shaderByteCode.size(), 
							&cs_layout
						);
					}

					// Clean up
					vsBlob->Release();
				}
			}
		}
		else {
			const wchar_t* psFilename = L"C:\\shader\\color.ps";

			// Load Pixel Shader
			D3DReadFileToBlob(L"C:\\shader\\color.ps", &psBlob);

			result = ColorShader_InitializeShader(
				pD3D11Device,
				pD3D11DeviceContext,
				hwnd,
				psFilename,
				shaderByteCode
			);
			if (!result) {
				hr = device->CreatePixelShader(
					psBlob->GetBufferPointer(), // &shaderByteCode[0], // 
					psBlob->GetBufferSize(), // shaderByteCode.size(), // 
					nullptr,
					&cs_pixelShader
				);

				// Clean up
				psBlob->Release();
			}
		}
	}

	return result;
}

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,449 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,562 questions
{count} votes