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:
parent
cb748c786a
commit
c7e33e636e
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user