diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index d135345a..ca33273d 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -659,7 +659,7 @@ namespace dxvk { pShaderBytecodeWithInputSignature), BytecodeLength); DxbcModule dxbcModule(dxbcReader); - Rc inputSignature = dxbcModule.isgn(); + const Rc inputSignature = dxbcModule.isgn(); std::vector attributes; std::vector bindings; @@ -707,7 +707,7 @@ namespace dxvk { // Create vertex input binding description. The // stride is dynamic state in D3D11 and will be - // set by STDMETHODCALLTYPE D3D11DeviceContext::IASetVertexBuffers. + // set by D3D11DeviceContext::IASetVertexBuffers. DxvkVertexBinding binding; binding.binding = pInputElementDescs[i].InputSlot; binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; @@ -716,8 +716,8 @@ namespace dxvk { binding.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE; if (pInputElementDescs[i].InstanceDataStepRate != 1) { - Logger::err(str::format( - "D3D11Device::CreateInputLayout: Unsupported instance data step rate: ", + Logger::warn(str::format( + "D3D11Device: Unsupported instance data step rate: ", pInputElementDescs[i].InstanceDataStepRate)); } } @@ -732,7 +732,7 @@ namespace dxvk { if (binding.inputRate != existingBinding.inputRate) { Logger::err(str::format( - "D3D11Device::CreateInputLayout: Conflicting input rate for binding ", + "D3D11Device: Conflicting input rate for binding ", binding.binding)); return E_INVALIDARG; } @@ -743,6 +743,23 @@ namespace dxvk { bindings.push_back(binding); } + // Check if there are any semantics defined in the + // shader that are not included in the current input + // layout. + for (auto i = inputSignature->begin(); i != inputSignature->end(); i++) { + bool found = i->systemValue != DxbcSystemValue::None; + + for (uint32_t j = 0; j < attributes.size() && !found; j++) + found = attributes.at(j).location == i->registerId; + + if (!found) { + Logger::warn(str::format( + "D3D11Device: Vertex input '", + i->semanticName, i->semanticIndex, + "' not defined by input layout")); + } + } + // Create the actual input layout object // if the application requests it. if (ppInputLayout != nullptr) { diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index f89d685f..c644e961 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -805,7 +805,10 @@ namespace dxvk { const DxvkVertexAttribute* attributes, uint32_t bindingCount, const DxvkVertexBinding* bindings) { - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + m_flags.set( + DxvkContextFlag::GpDirtyPipelineState, + DxvkContextFlag::GpDirtyIndexBuffer, + DxvkContextFlag::GpDirtyVertexBuffers); m_state.il.numAttributes = attributeCount; m_state.il.numBindings = bindingCount; @@ -1033,36 +1036,58 @@ namespace dxvk { switch (binding.type) { case VK_DESCRIPTOR_TYPE_SAMPLER: - m_descriptors[i].image.sampler = res.sampler->handle(); - m_descriptors[i].image.imageView = VK_NULL_HANDLE; - m_descriptors[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - m_cmd->trackResource(res.sampler); - break; + if (res.sampler != nullptr) { + m_descriptors[i].image.sampler = res.sampler->handle(); + m_descriptors[i].image.imageView = VK_NULL_HANDLE; + m_descriptors[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + m_cmd->trackResource(res.sampler); + } else { + Logger::err("DxvkContext: Unbound sampler descriptor"); + m_descriptors[i].image.sampler = VK_NULL_HANDLE; + m_descriptors[i].image.imageView = VK_NULL_HANDLE; + m_descriptors[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - m_descriptors[i].image.sampler = VK_NULL_HANDLE; - m_descriptors[i].image.imageView = res.imageView->handle(); - m_descriptors[i].image.imageLayout = res.imageView->imageInfo().layout; - - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - break; + if (res.imageView != nullptr) { + m_descriptors[i].image.sampler = VK_NULL_HANDLE; + m_descriptors[i].image.imageView = res.imageView->handle(); + m_descriptors[i].image.imageLayout = res.imageView->imageInfo().layout; + + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); + } else { + Logger::err("DxvkContext: Unbound image descriptor"); + m_descriptors[i].image.sampler = VK_NULL_HANDLE; + m_descriptors[i].image.imageView = VK_NULL_HANDLE; + m_descriptors[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - m_descriptors[i].texelBuffer = res.bufferView->handle(); - - m_cmd->trackResource(res.bufferView); - m_cmd->trackResource(res.bufferView->buffer()->resource()); - break; + if (res.bufferView != nullptr) { + m_descriptors[i].texelBuffer = res.bufferView->handle(); + + m_cmd->trackResource(res.bufferView); + m_cmd->trackResource(res.bufferView->buffer()->resource()); + } else { + Logger::err("DxvkContext: Unbound texel buffer"); + m_descriptors[i].texelBuffer = VK_NULL_HANDLE; + } break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - m_descriptors[i].buffer = res.bufferSlice.descriptorInfo(); - m_cmd->trackResource(res.bufferSlice.resource()); - break; + if (res.bufferSlice.handle() != VK_NULL_HANDLE) { + m_descriptors[i].buffer = res.bufferSlice.descriptorInfo(); + m_cmd->trackResource(res.bufferSlice.resource()); + } else { + Logger::err("DxvkContext: Unbound buffer"); + m_descriptors[i].buffer.buffer = VK_NULL_HANDLE; + m_descriptors[i].buffer.offset = 0; + m_descriptors[i].buffer.range = 0; + } break; default: Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.type)); @@ -1135,8 +1160,12 @@ namespace dxvk { const VkDeviceSize offset = vbo.offset(); if (handle != VK_NULL_HANDLE) { - m_cmd->cmdBindVertexBuffers(i, 1, &handle, &offset); + m_cmd->cmdBindVertexBuffers( + m_state.il.bindings[i].binding, + 1, &handle, &offset); m_cmd->trackResource(vbo.resource()); + } else { + Logger::err(str::format("DxvkContext: Unbound vertex buffer: ", i)); } } }