mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 11:52:12 +01:00
[d3d11] Implemented input layout creation
This commit is contained in:
parent
f33acf7334
commit
1f89452014
@ -58,7 +58,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D11DeviceContext::ClearState() {
|
||||
// this->IASetInputLayout(nullptr);
|
||||
this->IASetInputLayout(nullptr);
|
||||
this->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED);
|
||||
// this->IASetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, nullptr, nullptr, nullptr);
|
||||
// this->IASetIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0);
|
||||
@ -424,7 +424,15 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D11DeviceContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) {
|
||||
Logger::err("D3D11DeviceContext::IASetInputLayout: Not implemented");
|
||||
auto inputLayout = static_cast<D3D11InputLayout*>(pInputLayout);
|
||||
|
||||
if (m_state.ia.inputLayout != inputLayout) {
|
||||
m_state.ia.inputLayout = inputLayout;
|
||||
|
||||
m_context->setInputLayout(inputLayout != nullptr
|
||||
? inputLayout->GetDXVKInputLayout()
|
||||
: nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -522,7 +530,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D11DeviceContext::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) {
|
||||
Logger::err("D3D11DeviceContext::IAGetInputLayout: Not implemented");
|
||||
*ppInputLayout = m_state.ia.inputLayout.ref();
|
||||
}
|
||||
|
||||
|
||||
@ -822,7 +830,7 @@ namespace dxvk {
|
||||
auto shader = static_cast<D3D11PixelShader*>(pPixelShader);
|
||||
|
||||
if (NumClassInstances != 0)
|
||||
Logger::err("D3D11DeviceContext::VSSetShader: Class instances not supported");
|
||||
Logger::err("D3D11DeviceContext::PSSetShader: Class instances not supported");
|
||||
|
||||
if (m_state.ps.shader != shader) {
|
||||
m_state.ps.shader = shader;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <array>
|
||||
|
||||
#include "d3d11_buffer.h"
|
||||
#include "d3d11_input_layout.h"
|
||||
#include "d3d11_shader.h"
|
||||
#include "d3d11_state.h"
|
||||
#include "d3d11_view.h"
|
||||
@ -61,6 +62,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
struct D3D11ContextStateIA {
|
||||
Com<D3D11InputLayout> inputLayout;
|
||||
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "d3d11_buffer.h"
|
||||
#include "d3d11_context.h"
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_input_layout.h"
|
||||
#include "d3d11_present.h"
|
||||
#include "d3d11_shader.h"
|
||||
#include "d3d11_texture.h"
|
||||
@ -261,8 +262,98 @@ namespace dxvk {
|
||||
const void* pShaderBytecodeWithInputSignature,
|
||||
SIZE_T BytecodeLength,
|
||||
ID3D11InputLayout** ppInputLayout) {
|
||||
Logger::err("D3D11Device::CreateInputLayout: Not implemented");
|
||||
return E_NOTIMPL;
|
||||
try {
|
||||
DxbcReader dxbcReader(reinterpret_cast<const char*>(
|
||||
pShaderBytecodeWithInputSignature), BytecodeLength);
|
||||
DxbcModule dxbcModule(dxbcReader);
|
||||
|
||||
Rc<DxbcIsgn> inputSignature = dxbcModule.isgn();
|
||||
|
||||
std::vector<VkVertexInputAttributeDescription> attributes;
|
||||
std::vector<VkVertexInputBindingDescription> bindings;
|
||||
|
||||
for (uint32_t i = 0; i < NumElements; i++) {
|
||||
const DxbcSgnEntry* entry = inputSignature->find(
|
||||
pInputElementDescs[i].SemanticName,
|
||||
pInputElementDescs[i].SemanticIndex);
|
||||
|
||||
if (entry == nullptr) {
|
||||
Logger::err(str::format(
|
||||
"D3D11Device::CreateInputLayout: No such semantic: ",
|
||||
pInputElementDescs[i].SemanticName,
|
||||
pInputElementDescs[i].SemanticIndex));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Create vertex input attribute description
|
||||
VkVertexInputAttributeDescription attrib;
|
||||
attrib.location = entry->registerId;
|
||||
attrib.binding = pInputElementDescs[i].InputSlot;
|
||||
attrib.format = m_dxgiAdapter->LookupFormat(
|
||||
pInputElementDescs[i].Format).actual;
|
||||
attrib.offset = pInputElementDescs[i].AlignedByteOffset;
|
||||
|
||||
if (attrib.offset == D3D11_APPEND_ALIGNED_ELEMENT) {
|
||||
Logger::err("D3D11Device::CreateInputLayout: D3D11_APPEND_ALIGNED_ELEMENT not supported yet");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
attributes.push_back(attrib);
|
||||
|
||||
// Create vertex input binding description.
|
||||
VkVertexInputBindingDescription binding;
|
||||
binding.binding = pInputElementDescs[i].InputSlot;
|
||||
binding.stride = 0;
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
if (pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA) {
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
|
||||
if (pInputElementDescs[i].InstanceDataStepRate != 1) {
|
||||
Logger::err(str::format(
|
||||
"D3D11Device::CreateInputLayout: Unsupported instance data step rate: ",
|
||||
pInputElementDescs[i].InstanceDataStepRate));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the binding was already defined. If so, the
|
||||
// parameters must be identical (namely, the input rate).
|
||||
bool bindingDefined = false;
|
||||
|
||||
for (const auto& existingBinding : bindings) {
|
||||
if (binding.binding == existingBinding.binding) {
|
||||
bindingDefined = true;
|
||||
|
||||
if (binding.inputRate != existingBinding.inputRate) {
|
||||
Logger::err(str::format(
|
||||
"D3D11Device::CreateInputLayout: Conflicting input rate for binding ",
|
||||
binding.binding));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bindingDefined)
|
||||
bindings.push_back(binding);
|
||||
}
|
||||
|
||||
// Create the actual input layout object
|
||||
// if the application requests it.
|
||||
if (ppInputLayout != nullptr) {
|
||||
*ppInputLayout = ref(
|
||||
new D3D11InputLayout(this,
|
||||
new DxvkInputLayout(
|
||||
attributes.size(),
|
||||
attributes.data(),
|
||||
bindings.size(),
|
||||
bindings.data())));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
} catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
33
src/d3d11/d3d11_input_layout.cpp
Normal file
33
src/d3d11/d3d11_input_layout.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_input_layout.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D11InputLayout::D3D11InputLayout(
|
||||
D3D11Device* pDevice,
|
||||
const Rc<DxvkInputLayout>& inputLayout)
|
||||
: m_device(pDevice), m_inputLayout(inputLayout) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D11InputLayout::~D3D11InputLayout() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D11InputLayout::QueryInterface(REFIID riid, void** ppvObject) {
|
||||
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
|
||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11InputLayout);
|
||||
|
||||
Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
void D3D11InputLayout::GetDevice(ID3D11Device** ppDevice) {
|
||||
*ppDevice = ref(m_device);
|
||||
}
|
||||
|
||||
}
|
37
src/d3d11/d3d11_input_layout.h
Normal file
37
src/d3d11/d3d11_input_layout.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "d3d11_device_child.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D11Device;
|
||||
|
||||
class D3D11InputLayout : public D3D11DeviceChild<ID3D11InputLayout> {
|
||||
|
||||
public:
|
||||
|
||||
D3D11InputLayout(
|
||||
D3D11Device* pDevice,
|
||||
const Rc<DxvkInputLayout>& inputLayout);
|
||||
|
||||
~D3D11InputLayout();
|
||||
|
||||
HRESULT QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) final;
|
||||
|
||||
void GetDevice(
|
||||
ID3D11Device **ppDevice) final;
|
||||
|
||||
Rc<DxvkInputLayout> GetDXVKInputLayout() const {
|
||||
return m_inputLayout;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
D3D11Device* const m_device;
|
||||
Rc<DxvkInputLayout> m_inputLayout;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ d3d11_src = [
|
||||
'd3d11_context.cpp',
|
||||
'd3d11_device.cpp',
|
||||
'd3d11_enums.cpp',
|
||||
'd3d11_input_layout.cpp',
|
||||
'd3d11_main.cpp',
|
||||
'd3d11_present.cpp',
|
||||
'd3d11_shader.cpp',
|
||||
|
@ -29,4 +29,17 @@ namespace dxvk {
|
||||
|
||||
}
|
||||
|
||||
|
||||
const DxbcSgnEntry* DxbcIsgn::find(
|
||||
const std::string& semanticName,
|
||||
uint32_t semanticIndex) const {
|
||||
for (auto e = this->begin(); e != this->end(); e++) {
|
||||
if (e->semanticName == semanticName
|
||||
&& e->semanticIndex == semanticIndex)
|
||||
return &(*e);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
@ -39,6 +39,10 @@ namespace dxvk {
|
||||
auto begin() const { return m_entries.cbegin(); }
|
||||
auto end () const { return m_entries.cend(); }
|
||||
|
||||
const DxbcSgnEntry* find(
|
||||
const std::string& semanticName,
|
||||
uint32_t semanticIndex) const;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<DxbcSgnEntry> m_entries;
|
||||
|
@ -35,6 +35,15 @@ namespace dxvk {
|
||||
return m_shexChunk->version();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Input and output signature chunks
|
||||
*
|
||||
* Parts of the D3D11 API need access to the
|
||||
* input or output signature of the shader.
|
||||
*/
|
||||
Rc<DxbcIsgn> isgn() const { return m_isgnChunk; }
|
||||
Rc<DxbcIsgn> osgn() const { return m_osgnChunk; }
|
||||
|
||||
/**
|
||||
* \brief Compiles DXBC shader to SPIR-V module
|
||||
* \returns The compiled DXVK shader object
|
||||
|
Loading…
x
Reference in New Issue
Block a user