1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[dxvk] Fixed vertex buffer binding issue

If an application binds vertex buffers before changing the input layout,
it might happen that the vertex buffers are not bound correctly to the
Vulkan command buffer. This issue is now resolved.
This commit is contained in:
Philip Rebohle 2018-01-08 20:23:21 +01:00
parent cb748c786a
commit c7e33e636e
2 changed files with 74 additions and 28 deletions

View File

@ -659,7 +659,7 @@ namespace dxvk {
pShaderBytecodeWithInputSignature), BytecodeLength);
DxbcModule dxbcModule(dxbcReader);
Rc<DxbcIsgn> inputSignature = dxbcModule.isgn();
const Rc<DxbcIsgn> inputSignature = dxbcModule.isgn();
std::vector<DxvkVertexAttribute> attributes;
std::vector<DxvkVertexBinding> 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) {

View File

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