1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[dxvk] Refactored input layout state

This commit is contained in:
Philip Rebohle 2017-12-08 00:44:58 +01:00
parent 385c92db5a
commit 84605a1310
11 changed files with 114 additions and 98 deletions

View File

@ -463,9 +463,10 @@ namespace dxvk {
if (m_state.ia.inputLayout != inputLayout) { if (m_state.ia.inputLayout != inputLayout) {
m_state.ia.inputLayout = inputLayout; m_state.ia.inputLayout = inputLayout;
m_context->setInputLayout(inputLayout != nullptr if (inputLayout != nullptr)
? inputLayout->GetDXVKInputLayout() inputLayout->BindToContext(m_context);
: nullptr); else
m_context->setInputLayout(0, nullptr, 0, nullptr);
} }
} }

View File

@ -342,8 +342,8 @@ namespace dxvk {
Rc<DxbcIsgn> inputSignature = dxbcModule.isgn(); Rc<DxbcIsgn> inputSignature = dxbcModule.isgn();
std::vector<VkVertexInputAttributeDescription> attributes; std::vector<DxvkVertexAttribute> attributes;
std::vector<VkVertexInputBindingDescription> bindings; std::vector<DxvkVertexBinding> bindings;
for (uint32_t i = 0; i < NumElements; i++) { for (uint32_t i = 0; i < NumElements; i++) {
const DxbcSgnEntry* entry = inputSignature->find( const DxbcSgnEntry* entry = inputSignature->find(
@ -359,7 +359,7 @@ namespace dxvk {
} }
// Create vertex input attribute description // Create vertex input attribute description
VkVertexInputAttributeDescription attrib; DxvkVertexAttribute attrib;
attrib.location = entry->registerId; attrib.location = entry->registerId;
attrib.binding = pInputElementDescs[i].InputSlot; attrib.binding = pInputElementDescs[i].InputSlot;
attrib.format = m_dxgiAdapter->LookupFormat( attrib.format = m_dxgiAdapter->LookupFormat(
@ -376,9 +376,8 @@ namespace dxvk {
// Create vertex input binding description. The // Create vertex input binding description. The
// stride is dynamic state in D3D11 and will be // stride is dynamic state in D3D11 and will be
// set by D3D11DeviceContext::IASetVertexBuffers. // set by D3D11DeviceContext::IASetVertexBuffers.
VkVertexInputBindingDescription binding; DxvkVertexBinding binding;
binding.binding = pInputElementDescs[i].InputSlot; binding.binding = pInputElementDescs[i].InputSlot;
binding.stride = 0;
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
if (pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA) { if (pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA) {
@ -417,11 +416,10 @@ namespace dxvk {
if (ppInputLayout != nullptr) { if (ppInputLayout != nullptr) {
*ppInputLayout = ref( *ppInputLayout = ref(
new D3D11InputLayout(this, new D3D11InputLayout(this,
new DxvkInputLayout(
attributes.size(), attributes.size(),
attributes.data(), attributes.data(),
bindings.size(), bindings.size(),
bindings.data()))); bindings.data()));
} }
return S_OK; return S_OK;

View File

@ -5,9 +5,19 @@ namespace dxvk {
D3D11InputLayout::D3D11InputLayout( D3D11InputLayout::D3D11InputLayout(
D3D11Device* pDevice, D3D11Device* pDevice,
const Rc<DxvkInputLayout>& inputLayout) uint32_t numAttributes,
: m_device(pDevice), m_inputLayout(inputLayout) { const DxvkVertexAttribute* pAttributes,
uint32_t numBindings,
const DxvkVertexBinding* pBindings)
: m_device(pDevice) {
m_attributes.resize(numAttributes);
m_bindings.resize(numBindings);
for (uint32_t i = 0; i < numAttributes; i++)
m_attributes.at(i) = pAttributes[i];
for (uint32_t i = 0; i < numBindings; i++)
m_bindings.at(i) = pBindings[i];
} }
@ -30,4 +40,13 @@ namespace dxvk {
*ppDevice = ref(m_device); *ppDevice = ref(m_device);
} }
void D3D11InputLayout::BindToContext(const Rc<DxvkContext>& ctx) {
ctx->setInputLayout(
m_attributes.size(),
m_attributes.data(),
m_bindings.size(),
m_bindings.data());
}
} }

View File

@ -12,7 +12,10 @@ namespace dxvk {
D3D11InputLayout( D3D11InputLayout(
D3D11Device* pDevice, D3D11Device* pDevice,
const Rc<DxvkInputLayout>& inputLayout); uint32_t numAttributes,
const DxvkVertexAttribute* pAttributes,
uint32_t numBindings,
const DxvkVertexBinding* pBindings);
~D3D11InputLayout(); ~D3D11InputLayout();
@ -23,14 +26,15 @@ namespace dxvk {
void GetDevice( void GetDevice(
ID3D11Device **ppDevice) final; ID3D11Device **ppDevice) final;
Rc<DxvkInputLayout> GetDXVKInputLayout() const { void BindToContext(
return m_inputLayout; const Rc<DxvkContext>& ctx);
}
private: private:
D3D11Device* const m_device; D3D11Device* const m_device;
Rc<DxvkInputLayout> m_inputLayout;
std::vector<DxvkVertexAttribute> m_attributes;
std::vector<DxvkVertexBinding> m_bindings;
}; };

View File

@ -61,8 +61,7 @@ namespace dxvk {
m_context->setInputAssemblyState(iaState); m_context->setInputAssemblyState(iaState);
m_context->setInputLayout( m_context->setInputLayout(
new DxvkInputLayout( 0, nullptr, 0, nullptr);
0, nullptr, 0, nullptr));
DxvkRasterizerState rsState; DxvkRasterizerState rsState;
rsState.enableDepthClamp = VK_FALSE; rsState.enableDepthClamp = VK_FALSE;

View File

@ -41,30 +41,4 @@ namespace dxvk {
m_info.blendConstants[i] = 0.0f; m_info.blendConstants[i] = 0.0f;
} }
DxvkInputLayout::DxvkInputLayout(
uint32_t attributeCount,
const VkVertexInputAttributeDescription* attributeInfo,
uint32_t bindingCount,
const VkVertexInputBindingDescription* bindingInfo) {
// Copy vertex attribute info to a persistent array
m_attributes.resize(attributeCount);
for (uint32_t i = 0; i < attributeCount; i++)
m_attributes.at(i) = attributeInfo[i];
// Copy vertex binding info to a persistent array
m_bindings.resize(bindingCount);
for (uint32_t i = 0; i < bindingCount; i++)
m_bindings.at(i) = bindingInfo[i];
// Create info structure referencing those arrays
m_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
m_info.pNext = nullptr;
m_info.flags = 0;
m_info.vertexBindingDescriptionCount = m_bindings.size();
m_info.pVertexBindingDescriptions = m_bindings.data();
m_info.vertexAttributeDescriptionCount = m_attributes.size();
m_info.pVertexAttributeDescriptions = m_attributes.data();
}
} }

View File

@ -103,47 +103,48 @@ namespace dxvk {
}; };
/**
* \brief Vertex attribute description
*
* Stores information about a
* single vertex attribute.
*/
struct DxvkVertexAttribute {
uint32_t location;
uint32_t binding;
VkFormat format;
uint32_t offset;
};
/**
* \brief Vertex binding description
*
* Stores information about a
* single vertex binding slot.
*/
struct DxvkVertexBinding {
uint32_t binding;
VkVertexInputRate inputRate;
};
/** /**
* \brief Input layout * \brief Input layout
* *
* Stores the attributes and vertex buffer binding * Stores the description of all active
* descriptions that the vertex shader will take * vertex attributes and vertex bindings.
* its input values from.
*/ */
class DxvkInputLayout : public RcObject { struct DxvkInputLayout {
uint32_t numAttributes;
public: uint32_t numBindings;
DxvkInputLayout(
uint32_t attributeCount,
const VkVertexInputAttributeDescription* attributeInfo,
uint32_t bindingCount,
const VkVertexInputBindingDescription* bindingInfo);
uint32_t vertexAttributeCount() const {
return m_attributes.size();
}
uint32_t vertexBindingCount() const {
return m_bindings.size();
}
const VkPipelineVertexInputStateCreateInfo& info() const {
return m_info;
}
private:
std::vector<VkVertexInputAttributeDescription> m_attributes;
std::vector<VkVertexInputBindingDescription> m_bindings;
VkPipelineVertexInputStateCreateInfo m_info;
std::array<DxvkVertexAttribute, DxvkLimits::MaxNumVertexAttributes> attributes;
std::array<DxvkVertexBinding, DxvkLimits::MaxNumVertexBindings> bindings;
}; };
struct DxvkConstantStateObjects { struct DxvkConstantStateObjects {
Rc<DxvkInputLayout> inputLayout;
Rc<DxvkBlendState> blendState; Rc<DxvkBlendState> blendState;
}; };

View File

@ -389,11 +389,20 @@ namespace dxvk {
void DxvkContext::setInputLayout( void DxvkContext::setInputLayout(
const Rc<DxvkInputLayout>& state) { uint32_t attributeCount,
if (m_state.co.inputLayout != state) { const DxvkVertexAttribute* attributes,
m_state.co.inputLayout = state; uint32_t bindingCount,
const DxvkVertexBinding* bindings) {
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
}
m_state.il.numAttributes = attributeCount;
m_state.il.numBindings = bindingCount;
for (uint32_t i = 0; i < attributeCount; i++)
m_state.il.attributes.at(i) = attributes[i];
for (uint32_t i = 0; i < bindingCount; i++)
m_state.il.bindings.at(i) = bindings[i];
} }
@ -501,15 +510,19 @@ namespace dxvk {
gpState.iaPrimitiveTopology = m_state.ia.primitiveTopology; gpState.iaPrimitiveTopology = m_state.ia.primitiveTopology;
gpState.iaPrimitiveRestart = m_state.ia.primitiveRestart; gpState.iaPrimitiveRestart = m_state.ia.primitiveRestart;
const auto& il = m_state.co.inputLayout->info(); gpState.ilAttributeCount = m_state.il.numAttributes;
gpState.ilAttributeCount = il.vertexAttributeDescriptionCount; gpState.ilBindingCount = m_state.il.numBindings;
gpState.ilBindingCount = il.vertexBindingDescriptionCount;
for (uint32_t i = 0; i < gpState.ilAttributeCount; i++) for (uint32_t i = 0; i < m_state.il.numAttributes; i++) {
gpState.ilAttributes[i] = il.pVertexAttributeDescriptions[i]; gpState.ilAttributes[i].location = m_state.il.attributes[i].location;
gpState.ilAttributes[i].binding = m_state.il.attributes[i].binding;
gpState.ilAttributes[i].format = m_state.il.attributes[i].format;
gpState.ilAttributes[i].offset = m_state.il.attributes[i].offset;
}
for (uint32_t i = 0; i < gpState.ilBindingCount; i++) { for (uint32_t i = 0; i < m_state.il.numBindings; i++) {
gpState.ilBindings[i] = il.pVertexBindingDescriptions[i]; gpState.ilBindings[i].binding = m_state.il.bindings[i].binding;
gpState.ilBindings[i].inputRate = m_state.il.bindings[i].inputRate;
gpState.ilBindings[i].stride = m_state.vi.vertexStrides.at(i); gpState.ilBindings[i].stride = m_state.vi.vertexStrides.at(i);
} }

View File

@ -270,11 +270,18 @@ namespace dxvk {
const DxvkInputAssemblyState& state); const DxvkInputAssemblyState& state);
/** /**
* \brief Sets input layout state * \brief Sets input layout
* \param [in] state New state object *
* \param [in] attributeCount Number of vertex attributes
* \param [in] attributes The vertex attributes
* \param [in] bindingCount Number of buffer bindings
* \param [in] bindings Vertex buffer bindigs
*/ */
void setInputLayout( void setInputLayout(
const Rc<DxvkInputLayout>& state); uint32_t attributeCount,
const DxvkVertexAttribute* attributes,
uint32_t bindingCount,
const DxvkVertexBinding* bindings);
/** /**
* \brief Sets rasterizer state * \brief Sets rasterizer state

View File

@ -90,6 +90,7 @@ namespace dxvk {
*/ */
struct DxvkContextState { struct DxvkContextState {
DxvkInputAssemblyState ia; DxvkInputAssemblyState ia;
DxvkInputLayout il;
DxvkRasterizerState rs; DxvkRasterizerState rs;
DxvkMultisampleState ms; DxvkMultisampleState ms;
DxvkDepthStencilState ds; DxvkDepthStencilState ds;

View File

@ -87,8 +87,7 @@ public:
iaState.primitiveRestart = VK_FALSE; iaState.primitiveRestart = VK_FALSE;
m_dxvkContext->setInputAssemblyState(iaState); m_dxvkContext->setInputAssemblyState(iaState);
m_dxvkContext->setInputLayout( m_dxvkContext->setInputLayout(0, nullptr, 0, nullptr);
new DxvkInputLayout(0, nullptr, 0, nullptr));
DxvkRasterizerState rsState; DxvkRasterizerState rsState;
rsState.enableDepthClamp = VK_FALSE; rsState.enableDepthClamp = VK_FALSE;