[d3d11] Implemented basic shader creation methods

This commit is contained in:
Philip Rebohle 2017-12-06 18:54:01 +01:00
parent 46909f82fc
commit dece62c70a
10 changed files with 261 additions and 12 deletions

View File

@ -59,7 +59,7 @@ namespace dxvk {
void D3D11DeviceContext::ClearState() {
// this->IASetInputLayout(nullptr);
// this->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED);
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);
@ -429,7 +429,77 @@ namespace dxvk {
void D3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) {
Logger::err("D3D11DeviceContext::IASetPrimitiveTopology: Not implemented");
if (m_state.ia.primitiveTopology != Topology) {
m_state.ia.primitiveTopology = Topology;
Rc<DxvkInputAssemblyState> iaState;
switch (Topology) {
case D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED:
break;
case D3D11_PRIMITIVE_TOPOLOGY_POINTLIST:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
VK_FALSE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_LINELIST:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
VK_FALSE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
VK_TRUE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
VK_FALSE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
VK_TRUE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
VK_FALSE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
VK_TRUE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
VK_FALSE);
break;
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ:
iaState = new DxvkInputAssemblyState(
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
VK_TRUE);
break;
default:
Logger::err(str::format(
"D3D11DeviceContext::IASetPrimitiveTopology: Unknown primitive topology: ",
Topology));
}
m_context->setInputAssemblyState(iaState);
}
}
@ -457,7 +527,7 @@ namespace dxvk {
void D3D11DeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) {
Logger::err("D3D11DeviceContext::IAGetPrimitiveTopology: Not implemented");
*pTopology = m_state.ia.primitiveTopology;
}

View File

@ -553,6 +553,8 @@ namespace dxvk {
void ApplyViewportState();
void SetupIAStateObjects();
};
}

View File

@ -61,7 +61,7 @@ namespace dxvk {
struct D3D11ContextStateIA {
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
};

View File

@ -4,6 +4,7 @@
#include "d3d11_context.h"
#include "d3d11_device.h"
#include "d3d11_present.h"
#include "d3d11_shader.h"
#include "d3d11_texture.h"
#include "d3d11_view.h"
@ -270,8 +271,18 @@ namespace dxvk {
SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage,
ID3D11VertexShader** ppVertexShader) {
Logger::err("D3D11Device::CreateVertexShader: Not implemented");
return E_NOTIMPL;
D3D11ShaderModule module;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage)))
return E_INVALIDARG;
if (ppVertexShader != nullptr) {
*ppVertexShader = ref(new D3D11VertexShader(
this, std::move(module)));
}
return S_OK;
}
@ -305,8 +316,18 @@ namespace dxvk {
SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage,
ID3D11PixelShader** ppPixelShader) {
Logger::err("D3D11Device::CreatePixelShader: Not implemented");
return E_NOTIMPL;
D3D11ShaderModule module;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage)))
return E_INVALIDARG;
if (ppPixelShader != nullptr) {
*ppPixelShader = ref(new D3D11PixelShader(
this, std::move(module)));
}
return S_OK;
}
@ -605,4 +626,25 @@ namespace dxvk {
return enabled;
}
HRESULT D3D11Device::CreateShaderModule(
D3D11ShaderModule* pShaderModule,
const void* pShaderBytecode,
size_t BytecodeLength,
ID3D11ClassLinkage* pClassLinkage) {
if (pClassLinkage != nullptr) {
Logger::err("D3D11Device::CreateShaderModule: Class linkage not supported");
return E_INVALIDARG;
}
try {
*pShaderModule = D3D11ShaderModule(
pShaderBytecode, BytecodeLength);
return S_OK;
} catch (const DxvkError& e) {
Logger::err(e.message());
return E_INVALIDARG;
}
}
}

View File

@ -13,6 +13,7 @@ namespace dxvk {
class DxgiAdapter;
class D3D11DeviceContext;
class D3D11PresentDevice;
class D3D11ShaderModule;
class D3D11Device : public ComObject<ID3D11Device> {
@ -245,6 +246,12 @@ namespace dxvk {
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
HRESULT CreateShaderModule(
D3D11ShaderModule* pShaderModule,
const void* pShaderBytecode,
size_t BytecodeLength,
ID3D11ClassLinkage* pClassLinkage);
};
}

View File

@ -1,8 +1,83 @@
#include "d3d11_device.h"
#include "d3d11_shader.h"
namespace dxvk {
static std::string GetEnvVar(LPCWSTR name) {
DWORD len = ::GetEnvironmentVariableW(name, nullptr, 0);
std::wstring result;
while (len > result.size()) {
result.resize(len);
len = ::GetEnvironmentVariableW(
name, result.data(), result.size());
}
result.resize(len);
return str::fromws(result);
}
D3D11ShaderModule:: D3D11ShaderModule() { }
D3D11ShaderModule::~D3D11ShaderModule() { }
D3D11ShaderModule::D3D11ShaderModule(
const void* pShaderBytecode,
size_t BytecodeLength) {
DxbcReader reader(
reinterpret_cast<const char*>(pShaderBytecode),
BytecodeLength);
DxbcModule module(reader);
m_code = module.compile();
// TODO pre-process shader bindings
// If requested by the user, dump both the raw DXBC
// shader and the compiled SPIR-V module to a file.
const std::string dumpPath = GetEnvVar(L"DXVK_SHADER_DUMP_PATH");
if (dumpPath.size() != 0) {
const std::string baseName = str::format(dumpPath, "/",
ConstructFileName(ComputeShaderHash(pShaderBytecode, BytecodeLength),
module.version().type()));
reader.store(std::ofstream(str::format(baseName, ".dxbc"),
std::ios_base::binary | std::ios_base::trunc));
m_code.store(std::ofstream(str::format(baseName, ".spv"),
std::ios_base::binary | std::ios_base::trunc));
}
}
Sha1Hash D3D11ShaderModule::ComputeShaderHash(
const void* pShaderBytecode,
size_t BytecodeLength) const {
return Sha1Hash::compute(
reinterpret_cast<const uint8_t*>(pShaderBytecode),
BytecodeLength);
}
std::string D3D11ShaderModule::ConstructFileName(
const Sha1Hash& hash,
const DxbcProgramType& type) const {
std::string typeStr;
switch (type) {
case DxbcProgramType::PixelShader: typeStr = "PS_"; break;
case DxbcProgramType::VertexShader: typeStr = "VS_"; break;
case DxbcProgramType::GeometryShader: typeStr = "GS_"; break;
case DxbcProgramType::HullShader: typeStr = "HS_"; break;
case DxbcProgramType::DomainShader: typeStr = "DS_"; break;
case DxbcProgramType::ComputeShader: typeStr = "CS_"; break;
}
return str::format(typeStr, hash.toString());
}
}

View File

@ -1,7 +1,10 @@
#pragma once
#include <dxbc_module.h>
#include <dxvk_device.h>
#include "../util/sha1/sha1_util.h"
#include "d3d11_device_child.h"
#include "d3d11_interfaces.h"
@ -9,6 +12,36 @@ namespace dxvk {
class D3D11Device;
/**
* \brief Shader module
*
*
*/
class D3D11ShaderModule {
public:
D3D11ShaderModule();
D3D11ShaderModule(
const void* pShaderBytecode,
size_t BytecodeLength);
~D3D11ShaderModule();
private:
SpirvCodeBuffer m_code;
Sha1Hash ComputeShaderHash(
const void* pShaderBytecode,
size_t BytecodeLength) const;
std::string ConstructFileName(
const Sha1Hash& hash,
const DxbcProgramType& type) const;
};
/**
* \brief Common shader interface
@ -22,8 +55,8 @@ namespace dxvk {
public:
D3D11Shader(D3D11Device* device)
: m_device(device) { }
D3D11Shader(D3D11Device* device, D3D11ShaderModule&& module)
: m_device(device), m_module(std::move(module)) { }
~D3D11Shader() { }
@ -40,9 +73,14 @@ namespace dxvk {
*ppDevice = m_device.ref();
}
const D3D11ShaderModule& GetShaderModule() const {
return m_module;
}
private:
Com<D3D11Device> m_device;
Com<D3D11Device> m_device;
D3D11ShaderModule m_module;
};

View File

@ -27,6 +27,14 @@ namespace dxvk {
DxbcModule(DxbcReader& reader);
~DxbcModule();
/**
* \brief Shader type and version
* \returns Shader type and version
*/
DxbcProgramVersion version() const {
return m_shexChunk->version();
}
/**
* \brief Compiles DXBC shader to SPIR-V module
* \returns The compiled DXVK shader object

View File

@ -50,4 +50,9 @@ namespace dxvk {
return DxbcReader(m_data, size, m_pos);
}
void DxbcReader::store(std::ostream&& stream) const {
stream.write(m_data, m_size);
}
}

View File

@ -55,6 +55,8 @@ namespace dxvk {
return m_pos >= m_size;
}
void store(std::ostream&& stream) const;
private:
DxbcReader(const char* data, size_t size, size_t pos)