GPU-Reshape icon indicating copy to clipboard operation
GPU-Reshape copied to clipboard

DX12 CreateRootSignature fails when game is run via Reshape

Open GlassBeaver opened this issue 1 year ago • 3 comments

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;
}

GlassBeaver avatar Nov 12 '24 08:11 GlassBeaver

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.

miguel-petersen avatar Nov 25 '24 22:11 miguel-petersen

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.

GlassBeaver avatar Nov 26 '24 00:11 GlassBeaver

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.

miguel-petersen avatar Nov 26 '24 20:11 miguel-petersen