Take the D3D11 feature level into account when creating shaders. May help #9369

This commit is contained in:
Henrik Rydgard 2017-03-05 12:26:46 +01:00
parent ce54c8f935
commit 116edcb77a
12 changed files with 53 additions and 36 deletions

View File

@ -37,8 +37,9 @@ static std::vector<uint8_t> CompileShaderToBytecode(const char *code, size_t cod
return std::vector<uint8_t>();
}
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, UINT flags) {
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "vs_5_0", flags);
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "vs_4_0_level_9_1" : "vs_4_0";
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, profile, flags);
if (byteCode.empty())
return nullptr;
@ -49,8 +50,9 @@ ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *co
return vs;
}
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, UINT flags) {
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "ps_5_0", flags);
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "ps_4_0_level_9_1" : "ps_4_0";
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, profile, flags);
if (byteCode.empty())
return nullptr;
@ -59,8 +61,10 @@ ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code
return ps;
}
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, UINT flags) {
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "cs_5_0", flags);
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
return nullptr;
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "cs_4_0", flags);
if (byteCode.empty())
return nullptr;
@ -69,7 +73,9 @@ ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *
return cs;
}
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, UINT flags) {
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
return nullptr;
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "gs_5_0", flags);
if (byteCode.empty())
return nullptr;
@ -79,7 +85,6 @@ ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char
return gs;
}
void StockObjectsD3D11::Create(ID3D11Device *device) {
D3D11_BLEND_DESC blend_desc{};
blend_desc.RenderTarget[0].BlendEnable = false;

View File

@ -64,10 +64,10 @@ private:
bool nextMapDiscard_ = false;
};
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, UINT flags = 0);
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, UINT flags = 0);
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, UINT flags = 0);
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, UINT flags = 0);
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
class StockObjectsD3D11 {
public:

View File

@ -54,11 +54,13 @@ static const D3D11_INPUT_ELEMENT_DESC g_DepalVertexElements[] = {
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, },
};
DepalShaderCacheD3D11::DepalShaderCacheD3D11(ID3D11Device *device, ID3D11DeviceContext *context)
: device_(device), context_(context) {
DepalShaderCacheD3D11::DepalShaderCacheD3D11(Draw::DrawContext *draw) {
std::string errorMessage;
std::vector<uint8_t> vsByteCode;
vertexShader_ = CreateVertexShaderD3D11(device, depalVShaderHLSL, strlen(depalVShaderHLSL), &vsByteCode);
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
featureLevel_ = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
vertexShader_ = CreateVertexShaderD3D11(device_, depalVShaderHLSL, strlen(depalVShaderHLSL), &vsByteCode, featureLevel_);
ASSERT_SUCCESS(device_->CreateInputLayout(g_DepalVertexElements, ARRAY_SIZE(g_DepalVertexElements), vsByteCode.data(), vsByteCode.size(), &inputLayout_));
}
@ -144,7 +146,7 @@ ID3D11PixelShader *DepalShaderCacheD3D11::GetDepalettizePixelShader(GEPaletteFor
GenerateDepalShader(buffer, pixelFormat, HLSL_D3D11);
ID3D11PixelShader *pshader = CreatePixelShaderD3D11(device_, buffer, strlen(buffer));
ID3D11PixelShader *pshader = CreatePixelShaderD3D11(device_, buffer, strlen(buffer), featureLevel_);
if (!pshader) {
ERROR_LOG(G3D, "Failed to compile depal pixel shader");

View File

@ -19,8 +19,10 @@
#include <vector>
#include <cstdint>
#include <d3d11.h>
#include "Common/CommonTypes.h"
#include "GPU/ge_constants.h"
#include "thin3d/thin3d.h"
class DepalShaderD3D11 {
public:
@ -43,7 +45,7 @@ public:
// Caches both shaders and palette textures.
class DepalShaderCacheD3D11 {
public:
DepalShaderCacheD3D11(ID3D11Device *device, ID3D11DeviceContext *context);
DepalShaderCacheD3D11(Draw::DrawContext *draw);
~DepalShaderCacheD3D11();
// This also uploads the palette and binds the correct texture.
@ -59,6 +61,7 @@ private:
ID3D11Device *device_;
ID3D11DeviceContext *context_;
D3D_FEATURE_LEVEL featureLevel_;
ID3D11VertexShader *vertexShader_ = nullptr;
ID3D11InputLayout *inputLayout_ = nullptr;

View File

@ -98,12 +98,13 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
: FramebufferManagerCommon(draw) {
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
featureLevel_ = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
std::vector<uint8_t> bytecode;
std::string errorMsg;
quadVertexShader_ = CreateVertexShaderD3D11(device_, vscode, strlen(vscode), &bytecode);
quadPixelShader_ = CreatePixelShaderD3D11(device_, pscode, strlen(pscode));
quadVertexShader_ = CreateVertexShaderD3D11(device_, vscode, strlen(vscode), &bytecode, featureLevel_);
quadPixelShader_ = CreatePixelShaderD3D11(device_, pscode, strlen(pscode), featureLevel_);
ASSERT_SUCCESS(device_->CreateInputLayout(g_QuadVertexElements, ARRAY_SIZE(g_QuadVertexElements), bytecode.data(), bytecode.size(), &quadInputLayout_));
// STRIP geometry
@ -271,11 +272,11 @@ void FramebufferManagerD3D11::CompilePostShader() {
UINT flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
std::vector<uint8_t> byteCode;
postVertexShader_ = CreateVertexShaderD3D11(device_, vsSource.data(), vsSource.size(), &byteCode, flags);
postVertexShader_ = CreateVertexShaderD3D11(device_, vsSource.data(), vsSource.size(), &byteCode, featureLevel_, flags);
if (!postVertexShader_) {
return;
}
postPixelShader_ = CreatePixelShaderD3D11(device_, psSource.data(), psSource.size(), flags);
postPixelShader_ = CreatePixelShaderD3D11(device_, psSource.data(), psSource.size(), featureLevel_, flags);
if (!postPixelShader_) {
postVertexShader_->Release();
return;

View File

@ -108,6 +108,7 @@ private:
ID3D11Device *device_;
ID3D11DeviceContext *context_;
D3D_FEATURE_LEVEL featureLevel_;
// Used by DrawPixels
ID3D11Texture2D *drawPixelsTex_ = nullptr;

View File

@ -415,18 +415,19 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
(ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT)) {
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
lastVsync_ = g_Config.bVSync ? 1 : 0;
stockD3D11.Create(device_);
shaderManagerD3D11_ = new ShaderManagerD3D11(device_, context_);
shaderManagerD3D11_ = new ShaderManagerD3D11(device_, context_, featureLevel);
framebufferManagerD3D11_ = new FramebufferManagerD3D11(draw);
framebufferManager_ = framebufferManagerD3D11_;
textureCacheD3D11_ = new TextureCacheD3D11(draw);
textureCache_ = textureCacheD3D11_;
drawEngineCommon_ = &drawEngine_;
shaderManager_ = shaderManagerD3D11_;
depalShaderCache_ = new DepalShaderCacheD3D11(device_, context_);
depalShaderCache_ = new DepalShaderCacheD3D11(draw);
drawEngine_.SetShaderManager(shaderManagerD3D11_);
drawEngine_.SetTextureCache(textureCacheD3D11_);
drawEngine_.SetFramebufferManager(framebufferManagerD3D11_);

View File

@ -38,11 +38,11 @@
#include "GPU/D3D11/VertexShaderGeneratorD3D11.h"
#include "GPU/D3D11/D3D11Util.h"
D3D11FragmentShader::D3D11FragmentShader(ID3D11Device *device, ShaderID id, const char *code, bool useHWTransform)
D3D11FragmentShader::D3D11FragmentShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, ShaderID id, const char *code, bool useHWTransform)
: device_(device), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(0) {
source_ = code;
module_ = CreatePixelShaderD3D11(device, code, strlen(code));
module_ = CreatePixelShaderD3D11(device, code, strlen(code), featureLevel);
if (!module_)
failed_ = true;
}
@ -63,11 +63,11 @@ std::string D3D11FragmentShader::GetShaderString(DebugShaderStringType type) con
}
}
D3D11VertexShader::D3D11VertexShader(ID3D11Device *device, ShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting)
D3D11VertexShader::D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, ShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting)
: device_(device), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(nullptr), usesLighting_(usesLighting) {
source_ = code;
module_ = CreateVertexShaderD3D11(device, code, strlen(code), &bytecode_);
module_ = CreateVertexShaderD3D11(device, code, strlen(code), &bytecode_, featureLevel);
if (!module_)
failed_ = true;
}
@ -88,8 +88,8 @@ std::string D3D11VertexShader::GetShaderString(DebugShaderStringType type) const
}
}
ShaderManagerD3D11::ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext *context)
: device_(device), context_(context), lastVShader_(nullptr), lastFShader_(nullptr) {
ShaderManagerD3D11::ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel)
: device_(device), context_(context), featureLevel_(featureLevel_), lastVShader_(nullptr), lastFShader_(nullptr) {
codeBuffer_ = new char[16384];
memset(&ub_base, 0, sizeof(ub_base));
memset(&ub_lights, 0, sizeof(ub_lights));
@ -201,7 +201,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
// Vertex shader not in cache. Let's compile it.
bool usesLighting;
GenerateVertexShaderD3D11(VSID, codeBuffer_, &usesLighting);
vs = new D3D11VertexShader(device_, VSID, codeBuffer_, vertType, useHWTransform, usesLighting);
vs = new D3D11VertexShader(device_, featureLevel_, VSID, codeBuffer_, vertType, useHWTransform, usesLighting);
vsCache_[VSID] = vs;
} else {
vs = vsIter->second;
@ -213,7 +213,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
if (fsIter == fsCache_.end()) {
// Fragment shader not in cache. Let's compile it.
GenerateFragmentShaderD3D11(FSID, codeBuffer_);
fs = new D3D11FragmentShader(device_, FSID, codeBuffer_, useHWTransform);
fs = new D3D11FragmentShader(device_, featureLevel_, FSID, codeBuffer_, useHWTransform);
fsCache_[FSID] = fs;
} else {
fs = fsIter->second;

View File

@ -35,7 +35,7 @@ class D3D11PushBuffer;
class D3D11FragmentShader {
public:
D3D11FragmentShader(ID3D11Device *device, ShaderID id, const char *code, bool useHWTransform);
D3D11FragmentShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, ShaderID id, const char *code, bool useHWTransform);
~D3D11FragmentShader();
const std::string &source() const { return source_; }
@ -58,7 +58,7 @@ protected:
class D3D11VertexShader {
public:
D3D11VertexShader(ID3D11Device *device, ShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting);
D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, ShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting);
~D3D11VertexShader();
const std::string &source() const { return source_; }
@ -92,7 +92,7 @@ class D3D11PushBuffer;
class ShaderManagerD3D11 : public ShaderManagerCommon {
public:
ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext *context);
ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel);
~ShaderManagerD3D11();
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform);
@ -126,6 +126,7 @@ private:
ID3D11Device *device_;
ID3D11DeviceContext *context_;
D3D_FEATURE_LEVEL featureLevel_;
typedef std::map<ShaderID, D3D11FragmentShader *> FSCache;
FSCache fsCache_;

View File

@ -169,12 +169,12 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZ
// TODO: Helper with logging?
if (!stencilUploadPS_) {
std::string errorMessage;
stencilUploadPS_ = CreatePixelShaderD3D11(device_, stencil_ps, strlen(stencil_ps));
stencilUploadPS_ = CreatePixelShaderD3D11(device_, stencil_ps, strlen(stencil_ps), featureLevel_);
}
if (!stencilUploadVS_) {
std::string errorMessage;
std::vector<uint8_t> byteCode;
stencilUploadVS_ = CreateVertexShaderD3D11(device_, stencil_vs, strlen(stencil_vs), &byteCode);
stencilUploadVS_ = CreateVertexShaderD3D11(device_, stencil_vs, strlen(stencil_vs), &byteCode, featureLevel_);
ASSERT_SUCCESS(device_->CreateInputLayout(g_QuadVertexElements, 2, byteCode.data(), byteCode.size(), &stencilUploadInputLayout_));
}
if (!stencilValueBuffer_) {

View File

@ -319,6 +319,7 @@ enum class NativeObject {
BACKBUFFER_DEPTH_VIEW,
BACKBUFFER_COLOR_TEX,
BACKBUFFER_DEPTH_TEX,
FEATURE_LEVEL,
};
enum FBColorDepth {

View File

@ -133,6 +133,8 @@ public:
return (uintptr_t)bbRenderTargetView_;
case NativeObject::BACKBUFFER_DEPTH_VIEW:
return (uintptr_t)bbDepthStencilView_;
case NativeObject::FEATURE_LEVEL:
return (uintptr_t)featureLevel_;
default:
return 0;
}