mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Enough D3D11 to stumble to the first thin3d draw call. Buffers not implemented yet.
This commit is contained in:
parent
e5c20b47cd
commit
abc80ae770
9 changed files with 472 additions and 93 deletions
|
@ -10,6 +10,15 @@
|
||||||
#include "Windows/GPU/D3D11Context.h"
|
#include "Windows/GPU/D3D11Context.h"
|
||||||
#include "Windows/W32Util/Misc.h"
|
#include "Windows/W32Util/Misc.h"
|
||||||
#include "thin3d/thin3d.h"
|
#include "thin3d/thin3d.h"
|
||||||
|
#include "thin3d/d3d11_loader.h"
|
||||||
|
|
||||||
|
D3D11Context::D3D11Context() : draw_(nullptr), adapterId(-1), hDC(nullptr), hWnd_(nullptr), hD3D11(nullptr) {
|
||||||
|
LoadD3D11();
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11Context::~D3D11Context() {
|
||||||
|
UnloadD3D11();
|
||||||
|
}
|
||||||
|
|
||||||
void D3D11Context::SwapBuffers() {
|
void D3D11Context::SwapBuffers() {
|
||||||
swapChain_->Present(0, 0);
|
swapChain_->Present(0, 0);
|
||||||
|
@ -31,48 +40,41 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||||
hWnd_ = wnd;
|
hWnd_ = wnd;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
RECT rc;
|
|
||||||
GetClientRect(hWnd_, &rc);
|
|
||||||
UINT width = rc.right - rc.left;
|
|
||||||
UINT height = rc.bottom - rc.top;
|
|
||||||
|
|
||||||
UINT createDeviceFlags = 0;
|
UINT createDeviceFlags = 0;
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
D3D_DRIVER_TYPE driverTypes[] = {
|
static const D3D_DRIVER_TYPE driverTypes[] = {
|
||||||
D3D_DRIVER_TYPE_HARDWARE,
|
D3D_DRIVER_TYPE_HARDWARE,
|
||||||
D3D_DRIVER_TYPE_WARP,
|
D3D_DRIVER_TYPE_WARP,
|
||||||
D3D_DRIVER_TYPE_REFERENCE,
|
D3D_DRIVER_TYPE_REFERENCE,
|
||||||
};
|
};
|
||||||
UINT numDriverTypes = ARRAYSIZE(driverTypes);
|
UINT numDriverTypes = ARRAYSIZE(driverTypes);
|
||||||
|
|
||||||
const D3D_FEATURE_LEVEL featureLevels[] = {
|
static const D3D_FEATURE_LEVEL featureLevels[] = {
|
||||||
// D3D_FEATURE_LEVEL_11_1,
|
D3D_FEATURE_LEVEL_11_1,
|
||||||
D3D_FEATURE_LEVEL_11_0,
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
D3D_FEATURE_LEVEL_10_1,
|
D3D_FEATURE_LEVEL_10_1,
|
||||||
D3D_FEATURE_LEVEL_10_0,
|
D3D_FEATURE_LEVEL_10_0,
|
||||||
};
|
};
|
||||||
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
|
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
|
||||||
|
|
||||||
|
|
||||||
// Temporarily commenting out until we can dynamically load D3D11CreateDevice.
|
// Temporarily commenting out until we can dynamically load D3D11CreateDevice.
|
||||||
/*
|
|
||||||
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) {
|
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) {
|
||||||
driverType_ = driverTypes[driverTypeIndex];
|
driverType_ = driverTypes[driverTypeIndex];
|
||||||
hr = D3D11CreateDevice(nullptr, driverType_, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
|
hr = ptr_D3D11CreateDevice(nullptr, driverType_, nullptr, createDeviceFlags, (D3D_FEATURE_LEVEL *)featureLevels, numFeatureLevels,
|
||||||
D3D11_SDK_VERSION, &device_, &featureLevel_, &context_);
|
D3D11_SDK_VERSION, &device_, &featureLevel_, &context_);
|
||||||
|
|
||||||
if (hr == E_INVALIDARG) {
|
if (hr == E_INVALIDARG) {
|
||||||
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
|
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
|
||||||
hr = D3D11CreateDevice(nullptr, driverType_, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
|
hr = ptr_D3D11CreateDevice(nullptr, driverType_, nullptr, createDeviceFlags, (D3D_FEATURE_LEVEL *)&featureLevels[1], numFeatureLevels - 1,
|
||||||
D3D11_SDK_VERSION, &device_, &featureLevel_, &context_);
|
D3D11_SDK_VERSION, &device_, &featureLevel_, &context_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -94,58 +96,27 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Create swap chain
|
int width;
|
||||||
/*
|
int height;
|
||||||
IDXGIFactory2* dxgiFactory2 = nullptr;
|
GetRes(hWnd_, width, height);
|
||||||
hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
|
|
||||||
if (dxgiFactory2)
|
|
||||||
{
|
|
||||||
// DirectX 11.1 or later
|
|
||||||
hr = device_->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&device_1));
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
(void)context_->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&context_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 sd;
|
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
|
||||||
sd.Width = width;
|
|
||||||
sd.Height = height;
|
|
||||||
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
sd.SampleDesc.Count = 1;
|
|
||||||
sd.SampleDesc.Quality = 0;
|
|
||||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
sd.BufferCount = 1;
|
|
||||||
|
|
||||||
hr = dxgiFactory2->CreateSwapChainForHwnd(device_, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
hr = g_pSwapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain));
|
|
||||||
}
|
|
||||||
dxgiFactory2->Release();
|
|
||||||
} else {
|
|
||||||
*/
|
|
||||||
// DirectX 11.0 systems
|
// DirectX 11.0 systems
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
sd.BufferCount = 1;
|
sd.BufferCount = 1;
|
||||||
sd.BufferDesc.Width = width;
|
sd.BufferDesc.Width = width;
|
||||||
sd.BufferDesc.Height = height;
|
sd.BufferDesc.Height = height;
|
||||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
sd.OutputWindow = hWnd_;
|
sd.OutputWindow = hWnd_;
|
||||||
sd.SampleDesc.Count = 1;
|
sd.SampleDesc.Count = 1;
|
||||||
sd.SampleDesc.Quality = 0;
|
sd.SampleDesc.Quality = 0;
|
||||||
sd.Windowed = TRUE;
|
sd.Windowed = TRUE;
|
||||||
|
|
||||||
hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_);
|
hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_);
|
||||||
// }
|
|
||||||
|
|
||||||
// Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
|
|
||||||
dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER);
|
dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
dxgiFactory->Release();
|
dxgiFactory->Release();
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -163,8 +134,7 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Create depth stencil texture
|
// Create depth stencil texture
|
||||||
D3D11_TEXTURE2D_DESC descDepth;
|
D3D11_TEXTURE2D_DESC descDepth{};
|
||||||
ZeroMemory(&descDepth, sizeof(descDepth));
|
|
||||||
descDepth.Width = width;
|
descDepth.Width = width;
|
||||||
descDepth.Height = height;
|
descDepth.Height = height;
|
||||||
descDepth.MipLevels = 1;
|
descDepth.MipLevels = 1;
|
||||||
|
@ -181,8 +151,7 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Create the depth stencil view
|
// Create the depth stencil view
|
||||||
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
|
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV{};
|
||||||
ZeroMemory(&descDSV, sizeof(descDSV));
|
|
||||||
descDSV.Format = descDepth.Format;
|
descDSV.Format = descDepth.Format;
|
||||||
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||||
descDSV.Texture2D.MipSlice = 0;
|
descDSV.Texture2D.MipSlice = 0;
|
||||||
|
|
|
@ -27,9 +27,8 @@ class DrawContext;
|
||||||
|
|
||||||
class D3D11Context : public WindowsGraphicsContext {
|
class D3D11Context : public WindowsGraphicsContext {
|
||||||
public:
|
public:
|
||||||
D3D11Context() : draw_(nullptr), adapterId(-1), hDC(nullptr), hWnd_(nullptr), hD3D11(nullptr) {
|
D3D11Context();
|
||||||
}
|
~D3D11Context();
|
||||||
|
|
||||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override;
|
void SwapInterval(int interval) override;
|
||||||
|
|
|
@ -236,6 +236,7 @@
|
||||||
<ClInclude Include="gfx\gl_debug_log.h" />
|
<ClInclude Include="gfx\gl_debug_log.h" />
|
||||||
<ClInclude Include="gfx\gl_lost_manager.h" />
|
<ClInclude Include="gfx\gl_lost_manager.h" />
|
||||||
<ClInclude Include="gfx\texture_atlas.h" />
|
<ClInclude Include="gfx\texture_atlas.h" />
|
||||||
|
<ClInclude Include="thin3d\d3d11_loader.h" />
|
||||||
<ClInclude Include="util\text\wrap_text.h" />
|
<ClInclude Include="util\text\wrap_text.h" />
|
||||||
<ClInclude Include="gfx_es2\draw_buffer.h" />
|
<ClInclude Include="gfx_es2\draw_buffer.h" />
|
||||||
<ClInclude Include="gfx_es2\draw_text.h" />
|
<ClInclude Include="gfx_es2\draw_text.h" />
|
||||||
|
@ -689,6 +690,7 @@
|
||||||
<ClCompile Include="gfx\gl_debug_log.cpp" />
|
<ClCompile Include="gfx\gl_debug_log.cpp" />
|
||||||
<ClCompile Include="gfx\gl_lost_manager.cpp" />
|
<ClCompile Include="gfx\gl_lost_manager.cpp" />
|
||||||
<ClCompile Include="gfx\texture_atlas.cpp" />
|
<ClCompile Include="gfx\texture_atlas.cpp" />
|
||||||
|
<ClCompile Include="thin3d\d3d11_loader.cpp" />
|
||||||
<ClCompile Include="thin3d\thin3d_d3d11.cpp" />
|
<ClCompile Include="thin3d\thin3d_d3d11.cpp" />
|
||||||
<ClCompile Include="util\text\wrap_text.cpp" />
|
<ClCompile Include="util\text\wrap_text.cpp" />
|
||||||
<ClCompile Include="gfx_es2\draw_buffer.cpp" />
|
<ClCompile Include="gfx_es2\draw_buffer.cpp" />
|
||||||
|
|
|
@ -320,8 +320,8 @@
|
||||||
<ClInclude Include="gfx\GLStateCache.h">
|
<ClInclude Include="gfx\GLStateCache.h">
|
||||||
<Filter>gfx</Filter>
|
<Filter>gfx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="gfx\dx_state.h">
|
<ClInclude Include="thin3d\d3d11_loader.h">
|
||||||
<Filter>gfx</Filter>
|
<Filter>thin3d</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -772,8 +772,8 @@
|
||||||
<ClCompile Include="gfx\GLStateCache.cpp">
|
<ClCompile Include="gfx\GLStateCache.cpp">
|
||||||
<Filter>gfx</Filter>
|
<Filter>gfx</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="gfx\dx_state.cpp">
|
<ClCompile Include="thin3d\d3d11_loader.cpp">
|
||||||
<Filter>gfx</Filter>
|
<Filter>thin3d</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -847,4 +847,4 @@
|
||||||
<UniqueIdentifier>{06c6305a-a646-485b-85b9-645a24dd6553}</UniqueIdentifier>
|
<UniqueIdentifier>{06c6305a-a646-485b-85b9-645a24dd6553}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
47
ext/native/thin3d/d3d11_loader.cpp
Normal file
47
ext/native/thin3d/d3d11_loader.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#include "thin3d/d3d11_loader.h"
|
||||||
|
|
||||||
|
static HMODULE g_DXGIModule;
|
||||||
|
static HMODULE g_D3D11Module;
|
||||||
|
static HMODULE g_D3DCompileModule;
|
||||||
|
|
||||||
|
LPCREATEDXGIFACTORY ptr_CreateDXGIFactory;
|
||||||
|
LPD3D11CREATEDEVICE ptr_D3D11CreateDevice;
|
||||||
|
LPD3D11CREATEDEVICEANDSWAPCHAIN ptr_D3D11CreateDeviceAndSwapChain;
|
||||||
|
pD3DCompile ptr_D3DCompile;
|
||||||
|
|
||||||
|
bool LoadD3D11() {
|
||||||
|
if (g_D3D11Module) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
g_D3D11Module = LoadLibrary(L"d3d11.dll");
|
||||||
|
if (g_D3D11Module) {
|
||||||
|
ptr_D3D11CreateDevice = (LPD3D11CREATEDEVICE)GetProcAddress(g_D3D11Module, "D3D11CreateDevice");
|
||||||
|
ptr_D3D11CreateDeviceAndSwapChain = (LPD3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(g_D3D11Module, "D3D11CreateDeviceAndSwapChain");
|
||||||
|
}
|
||||||
|
if (!ptr_CreateDXGIFactory) {
|
||||||
|
g_DXGIModule = LoadLibrary(L"dxgi.dll");
|
||||||
|
if (g_DXGIModule) {
|
||||||
|
ptr_CreateDXGIFactory = (LPCREATEDXGIFACTORY)GetProcAddress(g_DXGIModule, "CreateDXGIFactory1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_D3DCompileModule = LoadLibrary(L"D3dcompiler_47.dll");
|
||||||
|
ptr_D3DCompile = (pD3DCompile)GetProcAddress(g_D3DCompileModule, "D3DCompile");
|
||||||
|
|
||||||
|
return g_DXGIModule != nullptr && g_D3D11Module != nullptr && g_D3DCompileModule != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnloadD3D11() {
|
||||||
|
if (g_DXGIModule) {
|
||||||
|
FreeLibrary(g_DXGIModule);
|
||||||
|
g_DXGIModule = nullptr;
|
||||||
|
}
|
||||||
|
if (g_D3D11Module) {
|
||||||
|
FreeLibrary(g_D3D11Module);
|
||||||
|
g_D3D11Module = nullptr;
|
||||||
|
}
|
||||||
|
if (g_D3DCompileModule) {
|
||||||
|
FreeLibrary(g_D3DCompileModule);
|
||||||
|
g_D3DCompileModule = nullptr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
21
ext/native/thin3d/d3d11_loader.h
Normal file
21
ext/native/thin3d/d3d11_loader.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Standard Windows includes
|
||||||
|
#include <windows.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <D3Dcompiler.h>
|
||||||
|
|
||||||
|
typedef HRESULT(WINAPI *LPCREATEDXGIFACTORY)(REFIID, void **);
|
||||||
|
typedef HRESULT(WINAPI *LPD3D11CREATEDEVICEANDSWAPCHAIN)(__in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext);
|
||||||
|
typedef HRESULT(WINAPI *LPD3D11CREATEDEVICE)(IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL *, UINT, UINT32, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
|
||||||
|
// typedef HRESULT(WINAPI *LPD3DCOMPILE)(LPCVOID pSrcData, SIZE_T SrcDataSize, LPCSTR pSourceName, const D3D_SHADER_MACRO pDefines, ID3DInclude *pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, UINT Flags1, UINT Flags2, ID3DBlob *ppCode, ID3DBlob *ppErrorMsgs);
|
||||||
|
|
||||||
|
extern LPCREATEDXGIFACTORY ptr_CreateDXGIFactory;
|
||||||
|
extern LPD3D11CREATEDEVICE ptr_D3D11CreateDevice;
|
||||||
|
extern LPD3D11CREATEDEVICEANDSWAPCHAIN ptr_D3D11CreateDeviceAndSwapChain;
|
||||||
|
extern pD3DCompile ptr_D3DCompile;
|
||||||
|
|
||||||
|
bool LoadD3D11();
|
||||||
|
bool UnloadD3D11();
|
|
@ -22,6 +22,8 @@ size_t DataFormatSizeInBytes(DataFormat fmt) {
|
||||||
|
|
||||||
case DataFormat::R8G8B8A8_UNORM:
|
case DataFormat::R8G8B8A8_UNORM:
|
||||||
case DataFormat::R8G8B8A8_UNORM_SRGB: return 4;
|
case DataFormat::R8G8B8A8_UNORM_SRGB: return 4;
|
||||||
|
case DataFormat::B8G8R8A8_UNORM:
|
||||||
|
case DataFormat::B8G8R8A8_UNORM_SRGB: return 4;
|
||||||
|
|
||||||
case DataFormat::R8G8B8A8_SNORM: return 4;
|
case DataFormat::R8G8B8A8_SNORM: return 4;
|
||||||
case DataFormat::R8G8B8A8_UINT: return 4;
|
case DataFormat::R8G8B8A8_UINT: return 4;
|
||||||
|
@ -79,6 +81,14 @@ static const std::vector<ShaderSource> fsTexCol = {
|
||||||
" return input.color * tex2D(Sampler0, input.uv);\n"
|
" return input.color * tex2D(Sampler0, input.uv);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
},
|
},
|
||||||
|
{ShaderLanguage::HLSL_D3D11,
|
||||||
|
"struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n"
|
||||||
|
"SamplerState samp : register(s0);\n"
|
||||||
|
"Texture2D<float4> tex : register(t0);\n"
|
||||||
|
"float4 main(PS_INPUT input) : SV_Target {\n"
|
||||||
|
" return input.color * tex.Sample(samp, input.uv);\n"
|
||||||
|
"}\n"
|
||||||
|
},
|
||||||
{ShaderLanguage::GLSL_VULKAN,
|
{ShaderLanguage::GLSL_VULKAN,
|
||||||
"#version 140\n"
|
"#version 140\n"
|
||||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||||
|
@ -105,6 +115,12 @@ static const std::vector<ShaderSource> fsCol = {
|
||||||
" return input.color;\n"
|
" return input.color;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
},
|
},
|
||||||
|
{ ShaderLanguage::HLSL_D3D11,
|
||||||
|
"struct PS_INPUT { float4 color : COLOR0; };\n"
|
||||||
|
"float4 main(PS_INPUT input) : SV_Target {\n"
|
||||||
|
" return input.color;\n"
|
||||||
|
"}\n"
|
||||||
|
},
|
||||||
{ ShaderLanguage::GLSL_VULKAN,
|
{ ShaderLanguage::GLSL_VULKAN,
|
||||||
"#version 140\n"
|
"#version 140\n"
|
||||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||||
|
@ -139,6 +155,17 @@ static const std::vector<ShaderSource> vsCol = {
|
||||||
" return output;\n"
|
" return output;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
},
|
},
|
||||||
|
{ ShaderLanguage::HLSL_D3D11,
|
||||||
|
"struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n"
|
||||||
|
"struct VS_OUTPUT { float4 Position : POSITION; float4 Color0 : COLOR0; };\n"
|
||||||
|
"float4x4 WorldViewProj : register(c0);\n"
|
||||||
|
"VS_OUTPUT main(VS_INPUT input) {\n"
|
||||||
|
" VS_OUTPUT output;\n"
|
||||||
|
" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n"
|
||||||
|
" output.Color0 = input.Color0;\n"
|
||||||
|
" return output;\n"
|
||||||
|
"}\n"
|
||||||
|
},
|
||||||
{ ShaderLanguage::GLSL_VULKAN,
|
{ ShaderLanguage::GLSL_VULKAN,
|
||||||
"#version 400\n"
|
"#version 400\n"
|
||||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||||
|
@ -188,6 +215,18 @@ static const std::vector<ShaderSource> vsTexCol = {
|
||||||
" return output;\n"
|
" return output;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
},
|
},
|
||||||
|
{ ShaderLanguage::HLSL_D3D11,
|
||||||
|
"struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n"
|
||||||
|
"struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n"
|
||||||
|
"float4x4 WorldViewProj : register(c0);\n"
|
||||||
|
"VS_OUTPUT main(VS_INPUT input) {\n"
|
||||||
|
" VS_OUTPUT output;\n"
|
||||||
|
" output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n"
|
||||||
|
" output.Texcoord0 = input.Texcoord0;\n"
|
||||||
|
" output.Color0 = input.Color0;\n"
|
||||||
|
" return output;\n"
|
||||||
|
"}\n"
|
||||||
|
},
|
||||||
{ ShaderLanguage::GLSL_VULKAN,
|
{ ShaderLanguage::GLSL_VULKAN,
|
||||||
"#version 400\n"
|
"#version 400\n"
|
||||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||||
|
@ -214,7 +253,7 @@ struct VsTexColUB {
|
||||||
float WorldViewProj[16];
|
float WorldViewProj[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources) {
|
static ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources) {
|
||||||
uint32_t supported = draw->GetSupportedShaderLanguages();
|
uint32_t supported = draw->GetSupportedShaderLanguages();
|
||||||
for (auto iter : sources) {
|
for (auto iter : sources) {
|
||||||
if ((uint32_t)iter.lang & supported) {
|
if ((uint32_t)iter.lang & supported) {
|
||||||
|
@ -234,10 +273,12 @@ void DrawContext::CreatePresets() {
|
||||||
|
|
||||||
DrawContext::~DrawContext() {
|
DrawContext::~DrawContext() {
|
||||||
for (int i = 0; i < VS_MAX_PRESET; i++) {
|
for (int i = 0; i < VS_MAX_PRESET; i++) {
|
||||||
vsPresets_[i]->Release();
|
if (vsPresets_[i])
|
||||||
|
vsPresets_[i]->Release();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < FS_MAX_PRESET; i++) {
|
for (int i = 0; i < FS_MAX_PRESET; i++) {
|
||||||
fsPresets_[i]->Release();
|
if (fsPresets_[i])
|
||||||
|
fsPresets_[i]->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,8 @@ enum class Primitive {
|
||||||
LINE_STRIP_ADJ,
|
LINE_STRIP_ADJ,
|
||||||
TRIANGLE_LIST_ADJ,
|
TRIANGLE_LIST_ADJ,
|
||||||
TRIANGLE_STRIP_ADJ,
|
TRIANGLE_STRIP_ADJ,
|
||||||
|
|
||||||
|
UNDEFINED,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum VertexShaderPreset : int {
|
enum VertexShaderPreset : int {
|
||||||
|
@ -182,6 +184,7 @@ enum class DataFormat : uint8_t {
|
||||||
R8G8B8A8_UNORM,
|
R8G8B8A8_UNORM,
|
||||||
R8G8B8A8_UNORM_SRGB,
|
R8G8B8A8_UNORM_SRGB,
|
||||||
B8G8R8A8_UNORM, // D3D style
|
B8G8R8A8_UNORM, // D3D style
|
||||||
|
B8G8R8A8_UNORM_SRGB, // D3D style
|
||||||
|
|
||||||
R8G8B8A8_SNORM,
|
R8G8B8A8_SNORM,
|
||||||
R8G8B8A8_UINT,
|
R8G8B8A8_UINT,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "thin3d/thin3d.h"
|
#include "thin3d/thin3d.h"
|
||||||
|
#include "thin3d/d3d11_loader.h"
|
||||||
|
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
|
@ -64,7 +65,10 @@ public:
|
||||||
void SetScissorRect(int left, int top, int width, int height) override;
|
void SetScissorRect(int left, int top, int width, int height) override;
|
||||||
void SetViewports(int count, Viewport *viewports) override;
|
void SetViewports(int count, Viewport *viewports) override;
|
||||||
void SetBlendFactor(float color[4]) override {
|
void SetBlendFactor(float color[4]) override {
|
||||||
memcpy(blendFactor_, color, sizeof(float) * 4);
|
if (memcmp(blendFactor_, color, sizeof(float) * 4)) {
|
||||||
|
memcpy(blendFactor_, color, sizeof(float) * 4);
|
||||||
|
blendFactorDirty_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(int vertexCount, int offset) override;
|
void Draw(int vertexCount, int offset) override;
|
||||||
|
@ -109,6 +113,10 @@ private:
|
||||||
D3D11DepthStencilState *curDepth_ = nullptr;
|
D3D11DepthStencilState *curDepth_ = nullptr;
|
||||||
D3D11RasterState *curRaster_ = nullptr;
|
D3D11RasterState *curRaster_ = nullptr;
|
||||||
ID3D11InputLayout *curInputLayout_ = nullptr;
|
ID3D11InputLayout *curInputLayout_ = nullptr;
|
||||||
|
ID3D11VertexShader *curVS_ = nullptr;
|
||||||
|
ID3D11PixelShader *curPS_ = nullptr;
|
||||||
|
ID3D11GeometryShader *curGS_ = nullptr;
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
|
|
||||||
// Dynamic state
|
// Dynamic state
|
||||||
float blendFactor_[4];
|
float blendFactor_[4];
|
||||||
|
@ -119,7 +127,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *context) : device_(device), context_(context) {
|
D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *context) : device_(device), context_(context) {
|
||||||
|
CreatePresets();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11DrawContext::~D3D11DrawContext() {
|
D3D11DrawContext::~D3D11DrawContext() {
|
||||||
|
@ -170,19 +178,45 @@ static const D3D11_STENCIL_OP stencilOpToD3D11[] = {
|
||||||
D3D11_STENCIL_OP_DECR,
|
D3D11_STENCIL_OP_DECR,
|
||||||
};
|
};
|
||||||
|
|
||||||
DXGI_FORMAT dataFormatToD3D11(DataFormat format) {
|
static DXGI_FORMAT dataFormatToD3D11(DataFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case DataFormat::R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
|
case DataFormat::R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
|
||||||
case DataFormat::R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
|
case DataFormat::R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
|
||||||
case DataFormat::R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT;
|
case DataFormat::R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT;
|
||||||
case DataFormat::R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
case DataFormat::R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
case DataFormat::R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
case DataFormat::R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
case DataFormat::R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||||
|
case DataFormat::B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
case DataFormat::B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||||
|
case DataFormat::R16_FLOAT: return DXGI_FORMAT_R16_FLOAT;
|
||||||
|
case DataFormat::R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
|
||||||
|
case DataFormat::R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||||
|
case DataFormat::D24_S8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
case DataFormat::D16: return DXGI_FORMAT_D16_UNORM;
|
||||||
|
case DataFormat::D32F: return DXGI_FORMAT_D32_FLOAT;
|
||||||
|
case DataFormat::D32F_S8: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||||
case DataFormat::ETC1:
|
case DataFormat::ETC1:
|
||||||
default:
|
default:
|
||||||
return DXGI_FORMAT_UNKNOWN;
|
return DXGI_FORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static D3D11_PRIMITIVE_TOPOLOGY primToD3D11[] = {
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,
|
||||||
|
// Tesselation shader only
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST, // ???
|
||||||
|
// These are for geometry shaders only.
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
|
||||||
|
};
|
||||||
|
|
||||||
inline void CopyStencilSide(D3D11_DEPTH_STENCILOP_DESC &side, const StencilSide &input) {
|
inline void CopyStencilSide(D3D11_DEPTH_STENCILOP_DESC &side, const StencilSide &input) {
|
||||||
side.StencilFunc = compareToD3D11[(int)input.compareOp];
|
side.StencilFunc = compareToD3D11[(int)input.compareOp];
|
||||||
side.StencilDepthFailOp = stencilOpToD3D11[(int)input.depthFailOp];
|
side.StencilDepthFailOp = stencilOpToD3D11[(int)input.depthFailOp];
|
||||||
|
@ -240,6 +274,7 @@ public:
|
||||||
bs->Release();
|
bs->Release();
|
||||||
}
|
}
|
||||||
ID3D11BlendState *bs;
|
ID3D11BlendState *bs;
|
||||||
|
float blendFactor[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
BlendState *D3D11DrawContext::CreateBlendState(const BlendStateDesc &desc) {
|
BlendState *D3D11DrawContext::CreateBlendState(const BlendStateDesc &desc) {
|
||||||
|
@ -382,31 +417,181 @@ public:
|
||||||
D3D11BlendState *blend;
|
D3D11BlendState *blend;
|
||||||
D3D11DepthStencilState *depth;
|
D3D11DepthStencilState *depth;
|
||||||
D3D11RasterState *raster;
|
D3D11RasterState *raster;
|
||||||
|
ID3D11VertexShader *vs;
|
||||||
|
ID3D11PixelShader *ps;
|
||||||
|
ID3D11GeometryShader *gs;
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||||
};
|
};
|
||||||
|
|
||||||
class D3D11Texture : public Texture {
|
class D3D11Texture : public Texture {
|
||||||
public:
|
public:
|
||||||
D3D11Texture() {}
|
D3D11Texture(const TextureDesc &desc) {
|
||||||
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) {}
|
width_ = desc.width;
|
||||||
|
height_ = desc.height;
|
||||||
|
depth_ = desc.depth;
|
||||||
|
}
|
||||||
|
~D3D11Texture() {
|
||||||
|
if (tex)
|
||||||
|
tex->Release();
|
||||||
|
if (view)
|
||||||
|
view->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) {
|
||||||
|
ELOG("SetImageData not supported, create a new texture instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11Texture2D *tex = nullptr;
|
||||||
|
ID3D11ShaderResourceView *view = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture *D3D11DrawContext::CreateTexture(const TextureDesc &desc) {
|
Texture *D3D11DrawContext::CreateTexture(const TextureDesc &desc) {
|
||||||
D3D11Texture *tex = new D3D11Texture();
|
D3D11Texture *tex = new D3D11Texture(desc);
|
||||||
|
|
||||||
// ....
|
if (!(GetDataFormatSupport(desc.format) & FMT_TEXTURE)) {
|
||||||
|
// D3D11 does not support this format as a texture format.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC descColor{};
|
||||||
|
descColor.Width = desc.width;
|
||||||
|
descColor.Height = desc.height;
|
||||||
|
descColor.MipLevels = desc.mipLevels;
|
||||||
|
descColor.ArraySize = 1;
|
||||||
|
descColor.Format = dataFormatToD3D11(desc.format);
|
||||||
|
descColor.SampleDesc.Count = 1;
|
||||||
|
descColor.SampleDesc.Quality = 0;
|
||||||
|
descColor.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
descColor.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
descColor.CPUAccessFlags = 0;
|
||||||
|
descColor.MiscFlags = 0;
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA initData[12]{};
|
||||||
|
if (desc.initData.size()) {
|
||||||
|
int w = desc.width;
|
||||||
|
int h = desc.height;
|
||||||
|
for (int i = 0; i < desc.initData.size(); i++) {
|
||||||
|
initData[i].pSysMem = desc.initData[0];
|
||||||
|
initData[i].SysMemPitch = (UINT)(w * DataFormatSizeInBytes(desc.format));
|
||||||
|
initData[i].SysMemSlicePitch = (UINT)(w * h * DataFormatSizeInBytes(desc.format));
|
||||||
|
w /= 2;
|
||||||
|
h /= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = device_->CreateTexture2D(&descColor, desc.initData.size() ? initData : nullptr, &tex->tex);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
delete tex;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
hr = device_->CreateShaderResourceView(tex->tex, nullptr, &tex->view);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
delete tex;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class D3D11ShaderModule : public ShaderModule {
|
class D3D11ShaderModule : public ShaderModule {
|
||||||
public:
|
public:
|
||||||
|
~D3D11ShaderModule() {
|
||||||
|
if (vs)
|
||||||
|
vs->Release();
|
||||||
|
if (ps)
|
||||||
|
ps->Release();
|
||||||
|
if (gs)
|
||||||
|
gs->Release();
|
||||||
|
}
|
||||||
|
ShaderStage GetStage() const override { return stage; }
|
||||||
|
|
||||||
std::vector<uint8_t> byteCode_;
|
std::vector<uint8_t> byteCode_;
|
||||||
|
ShaderStage stage;
|
||||||
|
|
||||||
|
ID3D11VertexShader *vs = nullptr;
|
||||||
|
ID3D11PixelShader *ps = nullptr;
|
||||||
|
ID3D11GeometryShader *gs = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) {
|
ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) {
|
||||||
// ...
|
switch (language) {
|
||||||
|
case ShaderLanguage::HLSL_D3D11:
|
||||||
|
case ShaderLanguage::HLSL_D3D11_BYTECODE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ELOG("Unsupported shader language");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string compiled;
|
||||||
|
std::string errors;
|
||||||
|
if (language == ShaderLanguage::HLSL_D3D11) {
|
||||||
|
const char *target = nullptr;
|
||||||
|
switch (stage) {
|
||||||
|
case ShaderStage::FRAGMENT: target = "ps_5_0"; break;
|
||||||
|
case ShaderStage::GEOMETRY: target = "gs_5_0"; break;
|
||||||
|
case ShaderStage::VERTEX: target = "vs_5_0"; break;
|
||||||
|
break;
|
||||||
|
case ShaderStage::COMPUTE:
|
||||||
|
case ShaderStage::CONTROL:
|
||||||
|
case ShaderStage::EVALUATION:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!target) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3DBlob *compiledCode = nullptr;
|
||||||
|
ID3DBlob *errorMsgs = nullptr;
|
||||||
|
HRESULT result = ptr_D3DCompile(data, dataSize, nullptr, nullptr, nullptr, "main", target, 0, 0, &compiledCode, &errorMsgs);
|
||||||
|
if (compiledCode) {
|
||||||
|
compiled = std::string((const char *)compiledCode->GetBufferPointer(), compiledCode->GetBufferSize());
|
||||||
|
compiledCode->Release();
|
||||||
|
}
|
||||||
|
if (errorMsgs) {
|
||||||
|
errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize());
|
||||||
|
ELOG("Failed compiling:\n%s\n%s", data, errors.c_str());
|
||||||
|
errorMsgs->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != S_OK) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK, we can now proceed
|
||||||
|
language = ShaderLanguage::HLSL_D3D11_BYTECODE;
|
||||||
|
data = (const uint8_t *)compiled.c_str();
|
||||||
|
dataSize = compiled.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language == ShaderLanguage::HLSL_D3D11_BYTECODE) {
|
||||||
|
// Easy!
|
||||||
|
D3D11ShaderModule *module = new D3D11ShaderModule();
|
||||||
|
module->stage = stage;
|
||||||
|
module->byteCode_ = std::vector<uint8_t>(data, data + dataSize);
|
||||||
|
HRESULT result = S_OK;
|
||||||
|
switch (stage) {
|
||||||
|
case ShaderStage::VERTEX:
|
||||||
|
result = device_->CreateVertexShader(data, dataSize, nullptr, &module->vs);
|
||||||
|
break;
|
||||||
|
case ShaderStage::FRAGMENT:
|
||||||
|
result = device_->CreatePixelShader(data, dataSize, nullptr, &module->ps);
|
||||||
|
break;
|
||||||
|
case ShaderStage::GEOMETRY:
|
||||||
|
result = device_->CreateGeometryShader(data, dataSize, nullptr, &module->gs);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ELOG("Unsupported shader stage");
|
||||||
|
result = S_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (result == S_OK) {
|
||||||
|
return module;
|
||||||
|
} else {
|
||||||
|
delete module;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,13 +605,25 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||||
dPipeline->depth->AddRef();
|
dPipeline->depth->AddRef();
|
||||||
dPipeline->input->AddRef();
|
dPipeline->input->AddRef();
|
||||||
dPipeline->raster->AddRef();
|
dPipeline->raster->AddRef();
|
||||||
|
dPipeline->topology = primToD3D11[(int)desc.prim];
|
||||||
|
|
||||||
std::vector<D3D11ShaderModule *> shaders;
|
std::vector<D3D11ShaderModule *> shaders;
|
||||||
D3D11ShaderModule *vshader = nullptr;
|
D3D11ShaderModule *vshader = nullptr;
|
||||||
for (auto iter : desc.shaders) {
|
for (auto iter : desc.shaders) {
|
||||||
shaders.push_back((D3D11ShaderModule *)iter);
|
D3D11ShaderModule *module = (D3D11ShaderModule *)iter;
|
||||||
if (iter->GetStage() == ShaderStage::VERTEX)
|
shaders.push_back(module);
|
||||||
vshader = (D3D11ShaderModule *)iter;
|
switch (module->GetStage()) {
|
||||||
|
case ShaderStage::VERTEX:
|
||||||
|
vshader = module;
|
||||||
|
dPipeline->vs = module->vs;
|
||||||
|
break;
|
||||||
|
case ShaderStage::FRAGMENT:
|
||||||
|
dPipeline->ps = module->ps;
|
||||||
|
break;
|
||||||
|
case ShaderStage::GEOMETRY:
|
||||||
|
dPipeline->gs = module->gs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vshader) {
|
if (!vshader) {
|
||||||
|
@ -438,12 +635,17 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||||
// Can finally create the input layout
|
// Can finally create the input layout
|
||||||
auto &inputDesc = dPipeline->input->desc;
|
auto &inputDesc = dPipeline->input->desc;
|
||||||
const std::vector<D3D11_INPUT_ELEMENT_DESC> &elements = dPipeline->input->elements;
|
const std::vector<D3D11_INPUT_ELEMENT_DESC> &elements = dPipeline->input->elements;
|
||||||
device_->CreateInputLayout(elements.data(), (UINT)elements.size(), vshader->byteCode_.data(), vshader->byteCode_.size(), &dPipeline->il);
|
HRESULT hr = device_->CreateInputLayout(elements.data(), (UINT)elements.size(), vshader->byteCode_.data(), vshader->byteCode_.size(), &dPipeline->il);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
Crash();
|
||||||
|
}
|
||||||
return dPipeline;
|
return dPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11DrawContext::BindPipeline(Pipeline *pipeline) {
|
void D3D11DrawContext::BindPipeline(Pipeline *pipeline) {
|
||||||
D3D11Pipeline *dPipeline = (D3D11Pipeline *)pipeline;
|
D3D11Pipeline *dPipeline = (D3D11Pipeline *)pipeline;
|
||||||
|
if (curPipeline_ == dPipeline)
|
||||||
|
return;
|
||||||
curPipeline_ = dPipeline;
|
curPipeline_ = dPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +668,22 @@ void D3D11DrawContext::ApplyCurrentState() {
|
||||||
context_->IASetInputLayout(curPipeline_->il);
|
context_->IASetInputLayout(curPipeline_->il);
|
||||||
curInputLayout_ = curPipeline_->il;
|
curInputLayout_ = curPipeline_->il;
|
||||||
}
|
}
|
||||||
|
if (curVS_ != curPipeline_->vs) {
|
||||||
|
context_->VSSetShader(curPipeline_->vs, nullptr, 0);
|
||||||
|
curVS_ = curPipeline_->vs;
|
||||||
|
}
|
||||||
|
if (curPS_ != curPipeline_->ps) {
|
||||||
|
context_->PSSetShader(curPipeline_->ps, nullptr, 0);
|
||||||
|
curPS_ = curPipeline_->ps;
|
||||||
|
}
|
||||||
|
if (curGS_ != curPipeline_->gs) {
|
||||||
|
context_->GSSetShader(curPipeline_->gs, nullptr, 0);
|
||||||
|
curGS_ = curPipeline_->gs;
|
||||||
|
}
|
||||||
|
if (curTopology_ != curPipeline_->topology) {
|
||||||
|
context_->IASetPrimitiveTopology(curPipeline_->topology);
|
||||||
|
curTopology_ = curPipeline_->topology;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class D3D11Buffer : public Buffer {
|
class D3D11Buffer : public Buffer {
|
||||||
|
@ -493,17 +711,19 @@ void D3D11DrawContext::BindIndexBuffer(Buffer *indexBuffer, int offset) {
|
||||||
|
|
||||||
void D3D11DrawContext::Draw(int vertexCount, int offset) {
|
void D3D11DrawContext::Draw(int vertexCount, int offset) {
|
||||||
ApplyCurrentState();
|
ApplyCurrentState();
|
||||||
|
context_->Draw(vertexCount, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11DrawContext::DrawIndexed(int vertexCount, int offset) {
|
void D3D11DrawContext::DrawIndexed(int indexCount, int offset) {
|
||||||
ApplyCurrentState();
|
ApplyCurrentState();
|
||||||
|
context_->DrawIndexed(indexCount, offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) {
|
void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) {
|
||||||
ApplyCurrentState();
|
ApplyCurrentState();
|
||||||
|
// TODO: Upload the data then draw..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
||||||
// TODO: Actually do proper checks
|
// TODO: Actually do proper checks
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
|
@ -539,20 +759,97 @@ uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
||||||
// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
|
// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
|
||||||
class D3D11Framebuffer : public Framebuffer {
|
class D3D11Framebuffer : public Framebuffer {
|
||||||
public:
|
public:
|
||||||
|
D3D11Framebuffer() {}
|
||||||
|
~D3D11Framebuffer() {
|
||||||
|
if (colorTex)
|
||||||
|
colorTex->Release();
|
||||||
|
if (colorView)
|
||||||
|
colorView->Release();
|
||||||
|
if (depthStencilTex)
|
||||||
|
depthStencilTex->Release();
|
||||||
|
if (depthStencilView)
|
||||||
|
depthStencilView->Release();
|
||||||
|
}
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
|
ID3D11Texture2D *colorTex = nullptr;
|
||||||
|
ID3D11RenderTargetView *colorView = nullptr;
|
||||||
|
ID3D11Texture2D *depthStencilTex = nullptr;
|
||||||
|
ID3D11DepthStencilView *depthStencilView = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||||
|
HRESULT hr;
|
||||||
D3D11Framebuffer *fb = new D3D11Framebuffer();
|
D3D11Framebuffer *fb = new D3D11Framebuffer();
|
||||||
fb->width = desc.width;
|
fb->width = desc.width;
|
||||||
fb->height = desc.height;
|
fb->height = desc.height;
|
||||||
|
|
||||||
|
if (desc.numColorAttachments) {
|
||||||
|
D3D11_TEXTURE2D_DESC descColor{};
|
||||||
|
descColor.Width = desc.width;
|
||||||
|
descColor.Height = desc.height;
|
||||||
|
descColor.MipLevels = 1;
|
||||||
|
descColor.ArraySize = 1;
|
||||||
|
descColor.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
descColor.SampleDesc.Count = 1;
|
||||||
|
descColor.SampleDesc.Quality = 0;
|
||||||
|
descColor.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
descColor.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||||
|
descColor.CPUAccessFlags = 0;
|
||||||
|
descColor.MiscFlags = 0;
|
||||||
|
hr = device_->CreateTexture2D(&descColor, nullptr, &fb->colorTex);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
delete fb;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
hr = device_->CreateRenderTargetView(fb->colorTex, nullptr, &fb->colorView);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
delete fb;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.z_stencil) {
|
||||||
|
D3D11_TEXTURE2D_DESC descDepth{};
|
||||||
|
descDepth.Width = desc.width;
|
||||||
|
descDepth.Height = desc.height;
|
||||||
|
descDepth.MipLevels = 1;
|
||||||
|
descDepth.ArraySize = 1;
|
||||||
|
descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
descDepth.SampleDesc.Count = 1;
|
||||||
|
descDepth.SampleDesc.Quality = 0;
|
||||||
|
descDepth.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||||
|
descDepth.CPUAccessFlags = 0;
|
||||||
|
descDepth.MiscFlags = 0;
|
||||||
|
hr = device_->CreateTexture2D(&descDepth, nullptr, &fb->depthStencilTex);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
delete fb;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV{};
|
||||||
|
descDSV.Format = descDepth.Format;
|
||||||
|
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||||
|
descDSV.Texture2D.MipSlice = 0;
|
||||||
|
hr = device_->CreateDepthStencilView(fb->depthStencilTex, &descDSV, &fb->depthStencilView);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
delete fb;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11DrawContext::BindTextures(int start, int count, Texture **textures) {
|
void D3D11DrawContext::BindTextures(int start, int count, Texture **textures) {
|
||||||
|
// Collect the resource views from the textures.
|
||||||
|
ID3D11ShaderResourceView *views[8];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
D3D11Texture *tex = (D3D11Texture *)textures[i];
|
||||||
|
views[i] = tex->view;
|
||||||
|
}
|
||||||
|
context_->PSSetShaderResources(start, count, views);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11DrawContext::BindSamplerStates(int start, int count, SamplerState **states) {
|
void D3D11DrawContext::BindSamplerStates(int start, int count, SamplerState **states) {
|
||||||
|
@ -582,7 +879,7 @@ void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context) {
|
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context) {
|
||||||
return nullptr; // new D3D11DrawContext(device, context);
|
return new D3D11DrawContext(device, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Draw
|
} // namespace Draw
|
Loading…
Add table
Reference in a new issue