D3D12: No output on screen when using shader compiled with DXC

Started by
1 comment, last by adam7 2 years, 7 months ago

Hi, I'm learning D3D12 for the first time after coming from D3D11 and I'm following a tutorial series which demonstrates compiling shaders and creating a pipeline like this:

ComPtr<ID3DBlob> vertexShaderBlob;
ThrowIfFailed(D3DReadFileToBlob(L"C:/Users/Adam/source/repos/Starfire DirectX 12/Starfire DirectX 12/assets/shaders/base.vsh.cso", &vertexShaderBlob));

ComPtr<ID3DBlob> pixelShaderBlob;

ThrowIfFailed(D3DReadFileToBlob(L"C:/Users/Adam/source/repos/Starfire DirectX 12/Starfire DirectX 12/assets/shaders/base.psh.cso", &pixelShaderBlob));


pipelineStateStream.pRootSignature = m_RootSignature.Get();
pipelineStateStream.InputLayout = { inputLayout, _countof(inputLayout) };
pipelineStateStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
pipelineStateStream.VS = CD3DX12_SHADER_BYTECODE((ID3DBlob*)vertexShaderBlob.Get());
pipelineStateStream.PS = CD3DX12_SHADER_BYTECODE((ID3DBlob*)pixelShaderBlob.Get());
pipelineStateStream.DSVFormat = DXGI_FORMAT_D32_FLOAT;
pipelineStateStream.RTVFormats = rtvFormats;
    

D3D12_PIPELINE_STATE_STREAM_DESC pipelineStateStreamDesc = {
sizeof(PipelineStateStream), &pipelineStateStream
};

ThrowIfFailed(device->CreatePipelineState(&pipelineStateStreamDesc, IID_PPV_ARGS(&m_PipelineState)));

This works and outputs a cube to the screen. However I want to use DXC instead so that I can dynamically compile shaders while running my program, so I compile my shaders and create a pipeline like this:

ComPtr<IDxcBlob> vertexShaderBlob;
vertexShaderBlob = CompileShader2(L"C:/Users/Adam/source/repos/Starfire DirectX 12/Starfire DirectX 12/assets/shaders/base.vsh.hlsl", L"main", L"vs_6_0", &vertexShaderBlob, NULL);

ComPtr<IDxcBlob> pixelShaderBlob;
pixelShaderBlob = CompileShader2(L"C:/Users/Adam/source/repos/Starfire DirectX 12/Starfire DirectX 12/assets/shaders/base.psh.hlsl", L"main", L"ps_6_0", &pixelShaderBlob, NULL);

DXGI_SAMPLE_DESC sampDesc = {
1, 0
};
D3D12_DEPTH_STENCIL_DESC depthDesc = {TRUE, D3D12_DEPTH_WRITE_MASK_ALL, D3D12_COMPARISON_FUNC_LESS };

D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.pRootSignature = m_RootSignature.Get();
psoDesc.InputLayout = { inputLayout, _countof(inputLayout) };
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
psoDesc.VS.BytecodeLength = vertexShaderBlob.Get()->GetBufferSize();
psoDesc.VS.pShaderBytecode = vertexShaderBlob.Get()->GetBufferPointer();
psoDesc.PS.BytecodeLength = pixelShaderBlob.Get()->GetBufferSize();
psoDesc.PS.pShaderBytecode = pixelShaderBlob.Get()->GetBufferPointer();
psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
psoDesc.NumRenderTargets = 1;
psoDesc.SampleDesc = sampDesc;
psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
psoDesc.RTVFormats[1] = DXGI_FORMAT_UNKNOWN;
psoDesc.RTVFormats[2] = DXGI_FORMAT_UNKNOWN;
psoDesc.RTVFormats[3] = DXGI_FORMAT_UNKNOWN;
psoDesc.RTVFormats[4] = DXGI_FORMAT_UNKNOWN;
psoDesc.RTVFormats[5] = DXGI_FORMAT_UNKNOWN;
psoDesc.RTVFormats[6] = DXGI_FORMAT_UNKNOWN;
psoDesc.RTVFormats[7] = DXGI_FORMAT_UNKNOWN;
psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
psoDesc.DepthStencilState = depthDesc;


ThrowIfFailed(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PipelineState)));

Now this doesn't work as the cube is no longer drawn. The shader compiler doesn't seem to give any errors and there are no errors given by D3D12 in the debug output and the program runs fine. I have compared both versions in RenderDoc and there is not much different between them apart from the fact that the shader bytecode is different both in contents and length… I don't know if this difference is due to the compiler being different or if I did something wrong. Here is my DXC compile function:

Microsoft::WRL::ComPtr<IDxcBlob> CompileShader2(_In_ LPCWSTR srcFile, _In_ LPCWSTR entryPoint, _In_ LPCWSTR profile, _Outptr_ IDxcBlob** blob, D3D_SHADER_MACRO defines[]) {
	HRESULT hr;

	Microsoft::WRL::ComPtr<IDxcLibrary> library;
	hr = DxcCreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&library));
	if(FAILED(hr)) SF_LOG_ERROR("SHADER COMPILE: Compile failed: DxcCreateInstance library \n", 0);

	Microsoft::WRL::ComPtr<IDxcCompiler> compiler;
	hr = DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler));
	if (FAILED(hr)) SF_LOG_ERROR("SHADER COMPILE: Compile failed: DxcCreateInstance compiler \n", 0);

	uint32_t codePage = CP_UTF8;
	Microsoft::WRL::ComPtr<IDxcBlobEncoding> sourceBlob;
	hr = library->CreateBlobFromFile(srcFile, &codePage, &sourceBlob);
	if (FAILED(hr)) SF_LOG_ERROR("SHADER COMPILE: Compile failed: CreateBlobFromFile \n", 0);

	Microsoft::WRL::ComPtr<IDxcOperationResult> result;
	hr = compiler->Compile(
		sourceBlob.Get(), // pSource
		srcFile, // pSourceName
		entryPoint, // pEntryPoint
		profile, // pTargetProfile
		NULL, 0, // pArguments, argCount
		NULL, 0, // pDefines, defineCount
		NULL, // pIncludeHandler
		&result); // ppResult
	if (SUCCEEDED(hr))
		result->GetStatus(&hr);
	if (FAILED(hr))
	{
		if (result)
		{
			Microsoft::WRL::ComPtr<IDxcBlobEncoding> errorsBlob;
			hr = result->GetErrorBuffer(&errorsBlob);
			if (SUCCEEDED(hr) && errorsBlob)
			{
				SF_LOG_ERROR("SHADER COMPILE: Compile failed: %s \n", errorsBlob->GetBufferPointer());
			}
		}

	}


	Microsoft::WRL::ComPtr<IDxcBlob> code;
	result->GetResult(&code);
	
	return code;

}

Where am I going wrong? Thanks

Advertisement

Turns out I forgot to set the SampleMask in the pipeline desc to 0xffffffff now everything works fine.

This topic is closed to new replies.

Advertisement