Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DX12 CreateRootSignature fails when game is run via Reshape #69

Open
GlassBeaver opened this issue Nov 12, 2024 · 3 comments
Open

DX12 CreateRootSignature fails when game is run via Reshape #69

GlassBeaver opened this issue Nov 12, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@GlassBeaver
Copy link

My DX12 game fails to run due to E_INVALIDARG being thrown by CreateRootSignature() when it's run via Reshape. Without Reshape, the function succeeds. E_INVALIDARG indicates that the blob that pBlobWithRootSignature points to is invalid, however I'm not getting any errors from D3D12SerializeVersionedRootSignature().

I'm using Agility SDK 614, Windows 11 23H2 (OS Build 22631.4317).

Here's how the root signature is created:

{
	// root constants
	D3D12_ROOT_PARAMETER1 rpRootConstants{};
	rpRootConstants.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
	rpRootConstants.Constants.ShaderRegister = 0;
	rpRootConstants.Constants.RegisterSpace = 0;
	rpRootConstants.Constants.Num32BitValues = scast<u32>(GE::DivideAndRoundUp(GE::Max_CE(
		sizeof(CCullInstancesRootConstants),
		sizeof(CComputeLODsRootConstants),
		sizeof(CIndirectSetupRootConstants),
		sizeof(CShadowCullingRootConstants),
		sizeof(CPrefixSumiAbsBonesRootConstants),
		sizeof(CPrepareInstancesRootConstants),
		sizeof(CPrepareAnimInstancesRootConstants)
	), sizeof(u32)));
	rpRootConstants.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;

	// CBV 1
	D3D12_ROOT_PARAMETER1 rpCBV1{};
	rpCBV1.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
	rpCBV1.Descriptor.ShaderRegister = 1;
	rpCBV1.Descriptor.RegisterSpace = 0;
	rpCBV1.Descriptor.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE;
	rpCBV1.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;

	D3D12_ROOT_PARAMETER1 rootParameters[]{
		rpRootConstants,
		rpCBV1,
		CRenderer::CreateSRVRootParam(0), // 2
		CRenderer::CreateSRVRootParam(1), // 3
		CRenderer::CreateSRVRootParam(2), // 4
		CRenderer::CreateSRVRootParam(3), // 5
		CRenderer::CreateSRVRootParam(4), // 6
		CRenderer::CreateSRVRootParam(5), // 7
		CRenderer::CreateSRVRootParam(6), // 8
		CRenderer::CreateUAVRootParam(0), // 9
		CRenderer::CreateUAVRootParam(1), // 10
		CRenderer::CreateUAVRootParam(2), // 11
		CRenderer::CreateUAVRootParam(3), // 12
		CRenderer::CreateUAVRootParam(4), // 13
		CRenderer::CreateUAVRootParam(5), // 14
		CRenderer::CreateUAVRootParam(6) // 15
	};

	D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSigDesc{};
	rootSigDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
	rootSigDesc.Desc_1_1 = {};
	rootSigDesc.Desc_1_1.NumParameters = _countof(rootParameters);
	rootSigDesc.Desc_1_1.pParameters = rootParameters;
	rootSigDesc.Desc_1_1.NumStaticSamplers = 0;
	rootSigDesc.Desc_1_1.pStaticSamplers = nullptr;
	rootSigDesc.Desc_1_1.Flags =
		D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
		D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED;

	COMPTR<ID3DBlob> signature;
	COMPTR<ID3DBlob> error;
	verifySuccess(D3D12SerializeVersionedRootSignature(&rootSigDesc, &signature, &error));
	check(!error);
	if (error)
	{
		GE::logw("error is: {}", scast<void*>(error.Get()));
		const char* errorMessage = scast<const char*>(error->GetBufferPointer());
		GE::loge("D3D12SerializeVersionedRootSignature error: ", errorMessage);
	}

	const HRESULT res = Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&GRenderer.IndirectRootSignature));

	if (FAILED(res))
	{
		GE::loge("Root signature creation failed: {}", res);
		LogFailedHRESULT(res, false);

		ID3D12InfoQueue* infoQueue = nullptr;
		if (SUCCEEDED(Device->QueryInterface(IID_PPV_ARGS(&infoQueue))))
		{
			const u64 messageCount = infoQueue->GetNumStoredMessages();
			for (u64 i = 0; i < messageCount; i++)
			{
				SIZE_T messageLength = 0;
				infoQueue->GetMessage(i, nullptr, &messageLength);
				D3D12_MESSAGE* message = (D3D12_MESSAGE*)malloc(messageLength);
				infoQueue->GetMessage(i, message, &messageLength);
				OutputDebugStringA(message->pDescription);
				string s = message->pDescription;
				GE::loge("{}", s);
				free(message);
			}
			infoQueue->Release();
		}
		system("pause");
		return;
	}

	GRenderer.IndirectRootSignature->SetName(L"IndirectRootSignature");
	GRenderer.IndirectRootSignature->SetPrivateData(CCommandList::RootSigLastRPGUID, sizeof(rootSigDesc.Desc_1_1.NumParameters), &rootSigDesc.Desc_1_1.NumParameters);
}

D3D12_ROOT_PARAMETER1 CRenderer::CreateSRVRootParam(const u32 ShaderRegister)
{
	D3D12_ROOT_PARAMETER1 rpSRV{};
	rpSRV.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
	rpSRV.Descriptor.ShaderRegister = ShaderRegister;
	rpSRV.Descriptor.RegisterSpace = 0;
	rpSRV.Descriptor.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE;
	rpSRV.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
	return rpSRV;
}

D3D12_ROOT_PARAMETER1 CRenderer::CreateUAVRootParam(const u32 ShaderRegister)
{
	D3D12_ROOT_PARAMETER1 rpUAV{};
	rpUAV.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
	rpUAV.Descriptor.ShaderRegister = ShaderRegister;
	rpUAV.Descriptor.RegisterSpace = 0;
	rpUAV.Descriptor.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE;
	rpUAV.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
	return rpUAV;
}
@miguel-petersen miguel-petersen self-assigned this Nov 25, 2024
@miguel-petersen miguel-petersen added the bug Something isn't working label Nov 25, 2024
@miguel-petersen
Copy link
Collaborator

Hi!

Apologies for the delay, was out for a small period of time.

I'm suspecting it may have something to do with how I handle root constants on my end, will investigate.

@GlassBeaver
Copy link
Author

I suspect it's due to Reshape requiring a certain amount of root constants for itself. IIRC my tests indicated that it will consume around 7 32-bit DWORDS' worth, so if one has a shader that needs more than 57 DWORDs, the root signature will end up being too large which is probably the cause of the error. But this is just a hunch and I'm not sure if it was 7 DWORDs, 8 or some other amount.

@miguel-petersen
Copy link
Collaborator

Yeah that's what's happening. I want to get rid of all injected root constants, because it's very easy to run into limits like that.

I basically have some internal programs that unfortunately add "global" root constants, but they really dont need to be. There's a larger refactor needed to decouple that stuff out. I'll use this ticket to keep track of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants