From 3edb0ef11405bf908efcde821d206a28b91901b8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 14:12:39 +0200 Subject: [PATCH] [d3d11] Ensure that all required inputs are defined by input layout --- src/d3d11/d3d11_device.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f5fbc13e..3cdc0bf7 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -591,7 +591,10 @@ namespace dxvk { ID3D11InputLayout** ppInputLayout) { InitReturnPtr(ppInputLayout); - if (pInputElementDescs == nullptr) + // This check is somehow even correct, passing null with zero + // size will always fail but passing non-null with zero size + // works, provided the shader does not have any actual inputs + if (!pInputElementDescs) return E_INVALIDARG; try { @@ -603,6 +606,7 @@ namespace dxvk { uint32_t attrMask = 0; uint32_t bindMask = 0; + uint32_t locationMask = 0; uint32_t bindingsDefined = 0; std::array attrList = { }; @@ -669,9 +673,19 @@ namespace dxvk { if (entry) { attrMask |= 1u << i; bindMask |= 1u << binding.binding; + locationMask |= 1u << attrib.location; } } + // Ensure that all inputs used by the shader are defined + for (auto i = inputSignature->begin(); i != inputSignature->end(); i++) { + bool isBuiltIn = DxbcIsgn::compareSemanticNames(i->semanticName, "sv_instanceid") + || DxbcIsgn::compareSemanticNames(i->semanticName, "sv_vertexid"); + + if (!isBuiltIn && !(locationMask & (1u << i->registerId))) + return E_INVALIDARG; + } + // Compact the attribute and binding lists to filter // out attributes and bindings not used by the shader uint32_t attrCount = CompactSparseList(attrList.data(), attrMask);