mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-31 19:47:06 +01:00
commit
4dd17c7b28
15 files changed
+865
-374
No files matched your search
+11
-10
@@ -38,6 +38,13 @@
|
||||
|
||||
const int FB_WIDTH = 480;
|
||||
const int FB_HEIGHT = 272;
|
||||
|
||||
struct Vertex {
|
||||
float x, y, z;
|
||||
float u, v;
|
||||
uint32_t rgba;
|
||||
};
|
||||
|
||||
FormatBuffer fb;
|
||||
FormatBuffer depthbuf;
|
||||
u32 clut[4096];
|
||||
@@ -62,7 +69,7 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||
|
||||
InputLayoutDesc inputDesc = {
|
||||
{
|
||||
{ 24, false },
|
||||
{ sizeof(Vertex), false },
|
||||
},
|
||||
{
|
||||
{ 0, SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0 },
|
||||
@@ -73,7 +80,7 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||
|
||||
ShaderModule *vshader = draw_->GetVshaderPreset(VS_TEXTURE_COLOR_2D);
|
||||
|
||||
vdata = draw_->CreateBuffer(24 * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
|
||||
vdata = draw_->CreateBuffer(sizeof(Vertex) * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
|
||||
idata = draw_->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA);
|
||||
|
||||
InputLayout *inputLayout = draw_->CreateInputLayout(inputDesc);
|
||||
@@ -213,12 +220,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
|
||||
x2 -= 1.0f;
|
||||
y2 -= 1.0f;
|
||||
|
||||
struct Vertex {
|
||||
float x, y, z;
|
||||
float u, v;
|
||||
uint32_t rgba;
|
||||
};
|
||||
|
||||
if (hasImage) {
|
||||
float v0 = 1.0f;
|
||||
float v1 = 0.0f;
|
||||
@@ -235,10 +236,10 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
|
||||
{ x2, y2, 0, u1, v1, 0xFFFFFFFF }, // BR
|
||||
{ x2, y, 0, u1, v0, 0xFFFFFFFF }, // TR
|
||||
};
|
||||
vdata->SetData((const uint8_t *)verts, sizeof(verts));
|
||||
draw_->UpdateBuffer(vdata, (const uint8_t *)verts, 0, sizeof(verts), Draw::UPDATE_DISCARD);
|
||||
|
||||
int indexes[] = { 0, 1, 2, 0, 2, 3 };
|
||||
idata->SetData((const uint8_t *)indexes, sizeof(indexes));
|
||||
draw_->UpdateBuffer(idata, (const uint8_t *)indexes, 0, sizeof(indexes), Draw::UPDATE_DISCARD);
|
||||
|
||||
draw_->BindTexture(0, fbTex);
|
||||
|
||||
|
||||
+17
-140
@@ -10,16 +10,18 @@
|
||||
#include "Windows/GPU/D3D11Context.h"
|
||||
#include "Windows/W32Util/Misc.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "thin3d/d3d11_loader.h"
|
||||
|
||||
void D3D11Context::SwapBuffers() {
|
||||
swapChain_->Present(0, 0);
|
||||
D3D11Context::D3D11Context() : draw_(nullptr), adapterId(-1), hDC(nullptr), hWnd_(nullptr), hD3D11(nullptr) {
|
||||
LoadD3D11();
|
||||
}
|
||||
|
||||
static void GetRes(HWND hWnd, int &xres, int &yres) {
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
xres = rc.right - rc.left;
|
||||
yres = rc.bottom - rc.top;
|
||||
D3D11Context::~D3D11Context() {
|
||||
UnloadD3D11();
|
||||
}
|
||||
|
||||
void D3D11Context::SwapBuffers() {
|
||||
draw_->HandleEvent(Draw::Event::PRESENT_REQUESTED);
|
||||
}
|
||||
|
||||
void D3D11Context::SwapInterval(int interval) {
|
||||
@@ -31,25 +33,20 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||
hWnd_ = wnd;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hWnd_, &rc);
|
||||
UINT width = rc.right - rc.left;
|
||||
UINT height = rc.bottom - rc.top;
|
||||
|
||||
UINT createDeviceFlags = 0;
|
||||
#ifdef _DEBUG
|
||||
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
D3D_DRIVER_TYPE driverTypes[] = {
|
||||
static const D3D_DRIVER_TYPE driverTypes[] = {
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
D3D_DRIVER_TYPE_WARP,
|
||||
D3D_DRIVER_TYPE_REFERENCE,
|
||||
};
|
||||
UINT numDriverTypes = ARRAYSIZE(driverTypes);
|
||||
|
||||
const D3D_FEATURE_LEVEL featureLevels[] = {
|
||||
// D3D_FEATURE_LEVEL_11_1,
|
||||
static const D3D_FEATURE_LEVEL featureLevels[] = {
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
@@ -57,149 +54,28 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
|
||||
|
||||
// Temporarily commenting out until we can dynamically load D3D11CreateDevice.
|
||||
/*
|
||||
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; 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_);
|
||||
|
||||
if (hr == E_INVALIDARG) {
|
||||
// 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_);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
// Obtain DXGI factory from device (since we used nullptr for pAdapter above)
|
||||
IDXGIFactory1* dxgiFactory = nullptr;
|
||||
{
|
||||
IDXGIDevice* dxgiDevice = nullptr;
|
||||
hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
|
||||
if (SUCCEEDED(hr)) {
|
||||
IDXGIAdapter* adapter = nullptr;
|
||||
hr = dxgiDevice->GetAdapter(&adapter);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));
|
||||
adapter->Release();
|
||||
}
|
||||
dxgiDevice->Release();
|
||||
}
|
||||
}
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
// Create swap chain
|
||||
/*
|
||||
IDXGIFactory2* dxgiFactory2 = nullptr;
|
||||
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
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 1;
|
||||
sd.BufferDesc.Width = width;
|
||||
sd.BufferDesc.Height = height;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = hWnd_;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
|
||||
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->Release();
|
||||
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
// Create a render target view
|
||||
ID3D11Texture2D* pBackBuffer = nullptr;
|
||||
hr = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer));
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = device_->CreateRenderTargetView(pBackBuffer, nullptr, &renderTargetView_);
|
||||
pBackBuffer->Release();
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
// Create depth stencil texture
|
||||
D3D11_TEXTURE2D_DESC descDepth;
|
||||
ZeroMemory(&descDepth, sizeof(descDepth));
|
||||
descDepth.Width = width;
|
||||
descDepth.Height = 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, &depthStencilTex_);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
// Create the depth stencil view
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
|
||||
ZeroMemory(&descDSV, sizeof(descDSV));
|
||||
descDSV.Format = descDepth.Format;
|
||||
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||
descDSV.Texture2D.MipSlice = 0;
|
||||
hr = device_->CreateDepthStencilView(depthStencilTex_, &descDSV, &depthStencilView_);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
context_->OMSetRenderTargets(1, &renderTargetView_, depthStencilView_);
|
||||
|
||||
int xres, yres;
|
||||
GetRes(hWnd_, xres, yres);
|
||||
|
||||
draw_ = Draw::T3DCreateD3D11Context(device_, context_);
|
||||
draw_ = Draw::T3DCreateD3D11Context(device_, context_, hWnd_);
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D11Context::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER);
|
||||
// This should only be called from the emu thread.
|
||||
/*
|
||||
int xres, yres;
|
||||
@@ -218,6 +94,7 @@ void D3D11Context::Resize() {
|
||||
}
|
||||
}
|
||||
*/
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER);
|
||||
}
|
||||
|
||||
void D3D11Context::Shutdown() {
|
||||
|
||||
@@ -27,9 +27,8 @@ class DrawContext;
|
||||
|
||||
class D3D11Context : public WindowsGraphicsContext {
|
||||
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;
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
@@ -43,10 +42,6 @@ private:
|
||||
Draw::DrawContext *draw_;
|
||||
ID3D11Device *device_;
|
||||
ID3D11DeviceContext *context_;
|
||||
IDXGISwapChain *swapChain_ = nullptr;
|
||||
ID3D11RenderTargetView *renderTargetView_ = nullptr;
|
||||
ID3D11Texture2D *depthStencilTex_ = nullptr;
|
||||
ID3D11DepthStencilView *depthStencilView_ = nullptr;
|
||||
|
||||
D3D_DRIVER_TYPE driverType_;
|
||||
D3D_FEATURE_LEVEL featureLevel_ = D3D_FEATURE_LEVEL_11_0;
|
||||
|
||||
@@ -38,11 +38,11 @@ void DrawBuffer::Init(Draw::DrawContext *t3d, Draw::Pipeline *pipeline) {
|
||||
if (inited_)
|
||||
return;
|
||||
|
||||
t3d_ = t3d;
|
||||
draw_ = t3d;
|
||||
inited_ = true;
|
||||
|
||||
if (pipeline->RequiresBuffer()) {
|
||||
vbuf_ = t3d_->CreateBuffer(MAX_VERTS * sizeof(Vertex), BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
|
||||
vbuf_ = draw_->CreateBuffer(MAX_VERTS * sizeof(Vertex), BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
|
||||
} else {
|
||||
vbuf_ = nullptr;
|
||||
}
|
||||
@@ -91,14 +91,14 @@ void DrawBuffer::Flush(bool set_blend_state) {
|
||||
return;
|
||||
|
||||
pipeline_->SetMatrix4x4("WorldViewProj", drawMatrix_.getReadPtr());
|
||||
t3d_->BindPipeline(pipeline_);
|
||||
draw_->BindPipeline(pipeline_);
|
||||
if (vbuf_) {
|
||||
vbuf_->SubData((const uint8_t *)verts_, 0, sizeof(Vertex) * count_);
|
||||
t3d_->BindVertexBuffers(0, 1, &vbuf_, nullptr);
|
||||
draw_->UpdateBuffer(vbuf_, (const uint8_t *)verts_, 0, sizeof(Vertex) * count_, Draw::UPDATE_DISCARD);
|
||||
draw_->BindVertexBuffers(0, 1, &vbuf_, nullptr);
|
||||
int offset = 0;
|
||||
t3d_->Draw(count_, offset);
|
||||
draw_->Draw(count_, offset);
|
||||
} else {
|
||||
t3d_->DrawUP((const void *)verts_, count_);
|
||||
draw_->DrawUP((const void *)verts_, count_);
|
||||
}
|
||||
count_ = 0;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ private:
|
||||
|
||||
Matrix4x4 drawMatrix_;
|
||||
|
||||
Draw::DrawContext *t3d_;
|
||||
Draw::DrawContext *draw_;
|
||||
Draw::Buffer *vbuf_;
|
||||
Draw::Pipeline *pipeline_;
|
||||
|
||||
|
||||
@@ -236,6 +236,7 @@
|
||||
<ClInclude Include="gfx\gl_debug_log.h" />
|
||||
<ClInclude Include="gfx\gl_lost_manager.h" />
|
||||
<ClInclude Include="gfx\texture_atlas.h" />
|
||||
<ClInclude Include="thin3d\d3d11_loader.h" />
|
||||
<ClInclude Include="util\text\wrap_text.h" />
|
||||
<ClInclude Include="gfx_es2\draw_buffer.h" />
|
||||
<ClInclude Include="gfx_es2\draw_text.h" />
|
||||
@@ -689,6 +690,7 @@
|
||||
<ClCompile Include="gfx\gl_debug_log.cpp" />
|
||||
<ClCompile Include="gfx\gl_lost_manager.cpp" />
|
||||
<ClCompile Include="gfx\texture_atlas.cpp" />
|
||||
<ClCompile Include="thin3d\d3d11_loader.cpp" />
|
||||
<ClCompile Include="thin3d\thin3d_d3d11.cpp" />
|
||||
<ClCompile Include="util\text\wrap_text.cpp" />
|
||||
<ClCompile Include="gfx_es2\draw_buffer.cpp" />
|
||||
|
||||
@@ -320,8 +320,8 @@
|
||||
<ClInclude Include="gfx\GLStateCache.h">
|
||||
<Filter>gfx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gfx\dx_state.h">
|
||||
<Filter>gfx</Filter>
|
||||
<ClInclude Include="thin3d\d3d11_loader.h">
|
||||
<Filter>thin3d</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -772,8 +772,8 @@
|
||||
<ClCompile Include="gfx\GLStateCache.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gfx\dx_state.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
<ClCompile Include="thin3d\d3d11_loader.cpp">
|
||||
<Filter>thin3d</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -847,4 +847,4 @@
|
||||
<UniqueIdentifier>{06c6305a-a646-485b-85b9-645a24dd6553}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_SRGB: return 4;
|
||||
case DataFormat::B8G8R8A8_UNORM:
|
||||
case DataFormat::B8G8R8A8_UNORM_SRGB: return 4;
|
||||
|
||||
case DataFormat::R8G8B8A8_SNORM: 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"
|
||||
"}\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,
|
||||
"#version 140\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
@@ -105,6 +115,12 @@ static const std::vector<ShaderSource> fsCol = {
|
||||
" return input.color;\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,
|
||||
"#version 140\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
@@ -139,6 +155,17 @@ static const std::vector<ShaderSource> vsCol = {
|
||||
" return output;\n"
|
||||
"}\n"
|
||||
},
|
||||
{ ShaderLanguage::HLSL_D3D11,
|
||||
"struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n"
|
||||
"struct VS_OUTPUT { float4 Color0 : COLOR0; float4 Position : SV_Position; };\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,
|
||||
"#version 400\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
@@ -188,6 +215,18 @@ static const std::vector<ShaderSource> vsTexCol = {
|
||||
" return output;\n"
|
||||
"}\n"
|
||||
},
|
||||
{ ShaderLanguage::HLSL_D3D11,
|
||||
"struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; };\n"
|
||||
"struct VS_OUTPUT { float4 Color0 : COLOR0; float2 Texcoord0 : TEXCOORD0; float4 Position : SV_Position; };\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,
|
||||
"#version 400\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
@@ -214,7 +253,7 @@ struct VsTexColUB {
|
||||
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();
|
||||
for (auto iter : sources) {
|
||||
if ((uint32_t)iter.lang & supported) {
|
||||
@@ -234,10 +273,12 @@ void DrawContext::CreatePresets() {
|
||||
|
||||
DrawContext::~DrawContext() {
|
||||
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++) {
|
||||
fsPresets_[i]->Release();
|
||||
if (fsPresets_[i])
|
||||
fsPresets_[i]->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ class Matrix4x4;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
struct IDirect3DDevice9;
|
||||
struct IDirect3D9;
|
||||
struct IDirect3DDevice9Ex;
|
||||
@@ -113,6 +117,7 @@ enum BufferUsageFlag : int {
|
||||
VERTEXDATA = 1,
|
||||
INDEXDATA = 2,
|
||||
GENERIC = 4,
|
||||
UNIFORM = 8,
|
||||
|
||||
DYNAMIC = 16,
|
||||
};
|
||||
@@ -142,6 +147,8 @@ enum class Primitive {
|
||||
LINE_STRIP_ADJ,
|
||||
TRIANGLE_LIST_ADJ,
|
||||
TRIANGLE_STRIP_ADJ,
|
||||
|
||||
UNDEFINED,
|
||||
};
|
||||
|
||||
enum VertexShaderPreset : int {
|
||||
@@ -182,6 +189,7 @@ enum class DataFormat : uint8_t {
|
||||
R8G8B8A8_UNORM,
|
||||
R8G8B8A8_UNORM_SRGB,
|
||||
B8G8R8A8_UNORM, // D3D style
|
||||
B8G8R8A8_UNORM_SRGB, // D3D style
|
||||
|
||||
R8G8B8A8_SNORM,
|
||||
R8G8B8A8_UINT,
|
||||
@@ -329,10 +337,15 @@ enum FBBlitFilter {
|
||||
FB_BLIT_LINEAR = 1,
|
||||
};
|
||||
|
||||
enum UpdateBufferFlags {
|
||||
UPDATE_DISCARD = 1,
|
||||
};
|
||||
|
||||
enum class Event {
|
||||
// These happen on D3D resize
|
||||
LOST_BACKBUFFER,
|
||||
GOT_BACKBUFFER,
|
||||
PRESENT_REQUESTED,
|
||||
};
|
||||
|
||||
struct FramebufferDesc {
|
||||
@@ -384,8 +397,6 @@ public:
|
||||
|
||||
class Buffer : public RefCountedObject {
|
||||
public:
|
||||
virtual void SetData(const uint8_t *data, size_t size) = 0;
|
||||
virtual void SubData(const uint8_t *data, size_t offset, size_t size) = 0;
|
||||
};
|
||||
|
||||
class Texture : public RefCountedObject {
|
||||
@@ -564,6 +575,9 @@ public:
|
||||
virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) = 0;
|
||||
virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0;
|
||||
|
||||
// Copies data from the CPU over into the buffer, at a specific offset. This does not change the size of the buffer and cannot write outside it.
|
||||
virtual void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) = 0;
|
||||
|
||||
virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) = 0;
|
||||
virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) = 0;
|
||||
|
||||
@@ -633,7 +647,7 @@ DrawContext *T3DCreateGLContext();
|
||||
|
||||
#ifdef _WIN32
|
||||
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx);
|
||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context);
|
||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, HWND hWnd);
|
||||
#endif
|
||||
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *context);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "thin3d/d3d11_loader.h"
|
||||
#include "math/dataconv.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d3dcompiler.h>
|
||||
@@ -18,7 +20,7 @@ class D3D11RasterState;
|
||||
|
||||
class D3D11DrawContext : public DrawContext {
|
||||
public:
|
||||
D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext);
|
||||
D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext, HWND hWnd);
|
||||
~D3D11DrawContext();
|
||||
|
||||
const DeviceCaps &GetDeviceCaps() const override {
|
||||
@@ -40,6 +42,8 @@ public:
|
||||
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
@@ -64,7 +68,10 @@ public:
|
||||
void SetScissorRect(int left, int top, int width, int height) override;
|
||||
void SetViewports(int count, Viewport *viewports) 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;
|
||||
@@ -95,13 +102,27 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void HandleEvent(Event ev) override {}
|
||||
void HandleEvent(Event ev) override {
|
||||
switch (ev) {
|
||||
case Event::PRESENT_REQUESTED:
|
||||
swapChain_->Present(0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ApplyCurrentState();
|
||||
|
||||
HWND hWnd_;
|
||||
ID3D11Device *device_;
|
||||
ID3D11DeviceContext *context_;
|
||||
IDXGISwapChain *swapChain_ = nullptr;
|
||||
|
||||
ID3D11RenderTargetView *bbRenderTargetView_ = nullptr;
|
||||
// Strictly speaking we don't need a depth buffer for the backbuffer.
|
||||
ID3D11Texture2D *bbDepthStencilTex_ = nullptr;
|
||||
ID3D11DepthStencilView *bbDepthStencilView_ = nullptr;
|
||||
|
||||
D3D11Pipeline *curPipeline_;
|
||||
DeviceCaps caps_;
|
||||
|
||||
@@ -109,6 +130,15 @@ private:
|
||||
D3D11DepthStencilState *curDepth_ = nullptr;
|
||||
D3D11RasterState *curRaster_ = nullptr;
|
||||
ID3D11InputLayout *curInputLayout_ = nullptr;
|
||||
ID3D11VertexShader *curVS_ = nullptr;
|
||||
ID3D11PixelShader *curPS_ = nullptr;
|
||||
ID3D11GeometryShader *curGS_ = nullptr;
|
||||
D3D11_PRIMITIVE_TOPOLOGY curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
|
||||
ID3D11Buffer *nextVertexBuffers_[4]{};
|
||||
int nextVertexBufferOffsets_[4]{};
|
||||
ID3D11Buffer *nextIndexBuffer_ = nullptr;
|
||||
int nextIndexBufferOffset_ = 0;
|
||||
|
||||
// Dynamic state
|
||||
float blendFactor_[4];
|
||||
@@ -117,9 +147,91 @@ private:
|
||||
bool stencilRefDirty_;
|
||||
};
|
||||
|
||||
static void GetRes(HWND hWnd, int &xres, int &yres) {
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
xres = rc.right - rc.left;
|
||||
yres = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *context) : device_(device), context_(context) {
|
||||
D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *context, HWND hWnd) : device_(device), context_(context), hWnd_(hWnd) {
|
||||
HRESULT hr;
|
||||
// Obtain DXGI factory from device (since we used nullptr for pAdapter above)
|
||||
IDXGIFactory1* dxgiFactory = nullptr;
|
||||
IDXGIDevice* dxgiDevice = nullptr;
|
||||
IDXGIAdapter* adapter = nullptr;
|
||||
hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = dxgiDevice->GetAdapter(&adapter);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));
|
||||
adapter->Release();
|
||||
}
|
||||
dxgiDevice->Release();
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
GetRes(hWnd_, width, height);
|
||||
|
||||
// DirectX 11.0 systems
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 1;
|
||||
sd.BufferDesc.Width = width;
|
||||
sd.BufferDesc.Height = height;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = hWnd_;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
|
||||
hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_);
|
||||
dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER);
|
||||
dxgiFactory->Release();
|
||||
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
|
||||
// Create a render target view
|
||||
ID3D11Texture2D* pBackBuffer = nullptr;
|
||||
hr = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer));
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
|
||||
hr = device_->CreateRenderTargetView(pBackBuffer, nullptr, &bbRenderTargetView_);
|
||||
pBackBuffer->Release();
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
|
||||
// Create depth stencil texture
|
||||
D3D11_TEXTURE2D_DESC descDepth{};
|
||||
descDepth.Width = width;
|
||||
descDepth.Height = 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, &bbDepthStencilTex_);
|
||||
|
||||
// Create the depth stencil view
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV{};
|
||||
descDSV.Format = descDepth.Format;
|
||||
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||
descDSV.Texture2D.MipSlice = 0;
|
||||
hr = device_->CreateDepthStencilView(bbDepthStencilTex_, &descDSV, &bbDepthStencilView_);
|
||||
|
||||
context_->OMSetRenderTargets(1, &bbRenderTargetView_, bbDepthStencilView_);
|
||||
|
||||
CreatePresets();
|
||||
}
|
||||
|
||||
D3D11DrawContext::~D3D11DrawContext() {
|
||||
@@ -132,7 +244,7 @@ void D3D11DrawContext::SetViewports(int count, Viewport *viewports) {
|
||||
}
|
||||
|
||||
void D3D11DrawContext::SetScissorRect(int left, int top, int width, int height) {
|
||||
D3D11_RECT rc;
|
||||
D3D11_RECT rc{};
|
||||
rc.left = left;
|
||||
rc.top = top;
|
||||
rc.right = left + width;
|
||||
@@ -170,19 +282,45 @@ static const D3D11_STENCIL_OP stencilOpToD3D11[] = {
|
||||
D3D11_STENCIL_OP_DECR,
|
||||
};
|
||||
|
||||
DXGI_FORMAT dataFormatToD3D11(DataFormat format) {
|
||||
static DXGI_FORMAT dataFormatToD3D11(DataFormat format) {
|
||||
switch (format) {
|
||||
case DataFormat::R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
|
||||
case DataFormat::R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
|
||||
case DataFormat::R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT;
|
||||
case DataFormat::R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
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:
|
||||
default:
|
||||
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) {
|
||||
side.StencilFunc = compareToD3D11[(int)input.compareOp];
|
||||
side.StencilDepthFailOp = stencilOpToD3D11[(int)input.depthFailOp];
|
||||
@@ -240,6 +378,7 @@ public:
|
||||
bs->Release();
|
||||
}
|
||||
ID3D11BlendState *bs;
|
||||
float blendFactor[4];
|
||||
};
|
||||
|
||||
BlendState *D3D11DrawContext::CreateBlendState(const BlendStateDesc &desc) {
|
||||
@@ -382,31 +521,181 @@ public:
|
||||
D3D11BlendState *blend;
|
||||
D3D11DepthStencilState *depth;
|
||||
D3D11RasterState *raster;
|
||||
ID3D11VertexShader *vs;
|
||||
ID3D11PixelShader *ps;
|
||||
ID3D11GeometryShader *gs;
|
||||
D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||
};
|
||||
|
||||
class D3D11Texture : public Texture {
|
||||
public:
|
||||
D3D11Texture() {}
|
||||
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) {}
|
||||
D3D11Texture(const TextureDesc &desc) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
class D3D11ShaderModule : public ShaderModule {
|
||||
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_;
|
||||
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) {
|
||||
// ...
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -420,13 +709,25 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
dPipeline->depth->AddRef();
|
||||
dPipeline->input->AddRef();
|
||||
dPipeline->raster->AddRef();
|
||||
dPipeline->topology = primToD3D11[(int)desc.prim];
|
||||
|
||||
std::vector<D3D11ShaderModule *> shaders;
|
||||
D3D11ShaderModule *vshader = nullptr;
|
||||
for (auto iter : desc.shaders) {
|
||||
shaders.push_back((D3D11ShaderModule *)iter);
|
||||
if (iter->GetStage() == ShaderStage::VERTEX)
|
||||
vshader = (D3D11ShaderModule *)iter;
|
||||
D3D11ShaderModule *module = (D3D11ShaderModule *)iter;
|
||||
shaders.push_back(module);
|
||||
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) {
|
||||
@@ -438,15 +739,21 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
// Can finally create the input layout
|
||||
auto &inputDesc = dPipeline->input->desc;
|
||||
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;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindPipeline(Pipeline *pipeline) {
|
||||
D3D11Pipeline *dPipeline = (D3D11Pipeline *)pipeline;
|
||||
if (curPipeline_ == dPipeline)
|
||||
return;
|
||||
curPipeline_ = dPipeline;
|
||||
}
|
||||
|
||||
// Gonna need dirtyflags soon..
|
||||
void D3D11DrawContext::ApplyCurrentState() {
|
||||
if (curBlend_ != curPipeline_->blend || blendFactorDirty_) {
|
||||
context_->OMSetBlendState(curPipeline_->blend->bs, blendFactor_, 0);
|
||||
@@ -466,44 +773,119 @@ void D3D11DrawContext::ApplyCurrentState() {
|
||||
context_->IASetInputLayout(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;
|
||||
}
|
||||
|
||||
int numVBs = (int)curPipeline_->input->strides.size();
|
||||
context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
|
||||
if (nextIndexBuffer_) {
|
||||
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R32_UINT, nextIndexBufferOffset_);
|
||||
}
|
||||
}
|
||||
|
||||
class D3D11Buffer : public Buffer {
|
||||
public:
|
||||
ID3D11Buffer *buf;
|
||||
|
||||
virtual void SetData(const uint8_t *data, size_t size) override {
|
||||
|
||||
}
|
||||
virtual void SubData(const uint8_t *data, size_t offset, size_t size) override {
|
||||
|
||||
~D3D11Buffer() {
|
||||
if (buf)
|
||||
buf->Release();
|
||||
if (srView)
|
||||
srView->Release();
|
||||
}
|
||||
ID3D11Buffer *buf = nullptr;
|
||||
ID3D11ShaderResourceView *srView = nullptr;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
Buffer *D3D11DrawContext::CreateBuffer(size_t size, uint32_t usageFlags) {
|
||||
D3D11Buffer *b = new D3D11Buffer();
|
||||
D3D11_BUFFER_DESC desc{};
|
||||
desc.ByteWidth = (UINT)size;
|
||||
desc.BindFlags = 0;
|
||||
if (usageFlags & VERTEXDATA)
|
||||
desc.BindFlags |= D3D11_BIND_VERTEX_BUFFER;
|
||||
if (usageFlags & INDEXDATA)
|
||||
desc.BindFlags |= D3D11_BIND_INDEX_BUFFER;
|
||||
if (usageFlags & UNIFORM)
|
||||
desc.BindFlags |= D3D11_BIND_CONSTANT_BUFFER;
|
||||
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
|
||||
b->size = size;
|
||||
HRESULT hr = device_->CreateBuffer(&desc, nullptr, &b->buf);
|
||||
if (FAILED(hr)) {
|
||||
delete b;
|
||||
return nullptr;
|
||||
}
|
||||
if (usageFlags & UNIFORM) {
|
||||
// D3D11_SHADER_RESOURCE_VIEW_DESC resDesc{};
|
||||
// device_->CreateShaderResourceView(b->buf, &resDesc, &b->srView);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) {
|
||||
void D3D11DrawContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) {
|
||||
D3D11Buffer *buf = (D3D11Buffer *)buffer;
|
||||
if ((flags & UPDATE_DISCARD) || (offset == 0 && size == buf->size)) {
|
||||
// Can just discard the old contents. This is only allowed for DYNAMIC buffers.
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
context_->Map(buf->buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
memcpy(map.pData, data, size);
|
||||
context_->Unmap(buf->buf, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_BOX box{};
|
||||
box.left = (UINT)offset;
|
||||
box.right = (UINT)(offset + size);
|
||||
context_->UpdateSubresource(buf->buf, 0, &box, data, 0, 0);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) {
|
||||
// Lazy application
|
||||
for (int i = 0; i < count; i++) {
|
||||
D3D11Buffer *buf = (D3D11Buffer *)buffers[i];
|
||||
nextVertexBuffers_[start + i] = buf->buf;
|
||||
nextVertexBufferOffsets_[start + i] = offsets ? offsets[i] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindIndexBuffer(Buffer *indexBuffer, int offset) {
|
||||
D3D11Buffer *buf = (D3D11Buffer *)indexBuffer;
|
||||
// Lazy application
|
||||
nextIndexBuffer_ = buf->buf;
|
||||
nextIndexBufferOffset_ = offset;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::Draw(int vertexCount, int offset) {
|
||||
ApplyCurrentState();
|
||||
context_->Draw(vertexCount, offset);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::DrawIndexed(int vertexCount, int offset) {
|
||||
void D3D11DrawContext::DrawIndexed(int indexCount, int offset) {
|
||||
ApplyCurrentState();
|
||||
context_->DrawIndexed(indexCount, offset, 0);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
ApplyCurrentState();
|
||||
// TODO: Upload the data then draw..
|
||||
}
|
||||
|
||||
|
||||
uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
||||
// TODO: Actually do proper checks
|
||||
switch (fmt) {
|
||||
@@ -539,41 +921,172 @@ uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
||||
// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
|
||||
class D3D11Framebuffer : public Framebuffer {
|
||||
public:
|
||||
D3D11Framebuffer() {}
|
||||
~D3D11Framebuffer() {
|
||||
if (colorTex)
|
||||
colorTex->Release();
|
||||
if (colorRTView)
|
||||
colorRTView->Release();
|
||||
if (colorSRView)
|
||||
colorSRView->Release();
|
||||
if (depthStencilTex)
|
||||
depthStencilTex->Release();
|
||||
if (depthStencilRTView)
|
||||
depthStencilRTView->Release();
|
||||
}
|
||||
int width;
|
||||
int height;
|
||||
|
||||
ID3D11Texture2D *colorTex = nullptr;
|
||||
ID3D11RenderTargetView *colorRTView = nullptr;
|
||||
ID3D11ShaderResourceView *colorSRView = nullptr;
|
||||
|
||||
ID3D11Texture2D *depthStencilTex = nullptr;
|
||||
ID3D11DepthStencilView *depthStencilRTView = nullptr;
|
||||
};
|
||||
|
||||
Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
HRESULT hr;
|
||||
D3D11Framebuffer *fb = new D3D11Framebuffer();
|
||||
fb->width = desc.width;
|
||||
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 | D3D11_BIND_SHADER_RESOURCE;
|
||||
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->colorRTView);
|
||||
if (FAILED(hr)) {
|
||||
delete fb;
|
||||
return nullptr;
|
||||
}
|
||||
hr = device_->CreateShaderResourceView(fb->colorTex, nullptr, &fb->colorSRView);
|
||||
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->depthStencilRTView);
|
||||
if (FAILED(hr)) {
|
||||
delete fb;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
ID3D11SamplerState *samplers[8];
|
||||
for (int i = 0; i < count; i++) {
|
||||
D3D11SamplerState *samp = (D3D11SamplerState *)states[i];
|
||||
samplers[i] = samp->ss;
|
||||
}
|
||||
context_->PSSetSamplers(start, count, samplers);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) {
|
||||
|
||||
if (mask & ClearFlag::COLOR) {
|
||||
float colorRGBA[4];
|
||||
Uint8x1ToFloat4(colorRGBA, colorval);
|
||||
context_->ClearRenderTargetView(bbRenderTargetView_, colorRGBA);
|
||||
}
|
||||
if (mask & (ClearFlag::DEPTH | ClearFlag::STENCIL)) {
|
||||
UINT clearFlag = 0;
|
||||
if (mask & ClearFlag::DEPTH)
|
||||
clearFlag |= D3D11_CLEAR_DEPTH;
|
||||
if (mask & ClearFlag::STENCIL)
|
||||
clearFlag |= D3D11_CLEAR_STENCIL;
|
||||
context_->ClearDepthStencilView(bbDepthStencilView_, clearFlag, depthVal, stencilVal);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11DrawContext::CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {}
|
||||
bool D3D11DrawContext::BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { return true; }
|
||||
void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y, int z, Framebuffer *dstfb, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {
|
||||
D3D11Framebuffer *src = (D3D11Framebuffer *)srcfb;
|
||||
D3D11Framebuffer *dst = (D3D11Framebuffer *)dstfb;
|
||||
|
||||
// CopySubResource ?
|
||||
}
|
||||
|
||||
bool D3D11DrawContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) {
|
||||
D3D11Framebuffer *src = (D3D11Framebuffer *)srcfb;
|
||||
D3D11Framebuffer *dst = (D3D11Framebuffer *)dstfb;
|
||||
|
||||
// Unfortunately D3D11 has no equivalent to this, gotta render a quad.
|
||||
return true;
|
||||
}
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {}
|
||||
// color must be 0, for now.
|
||||
void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {}
|
||||
void D3D11DrawContext::BindFramebufferForRead(Framebuffer *fbo) {}
|
||||
void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {
|
||||
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
|
||||
context_->OMSetRenderTargets(1, &fb->colorRTView, fb->depthStencilRTView);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindBackbufferAsRenderTarget() {}
|
||||
uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) { return 0; }
|
||||
// color must be 0, for now.
|
||||
void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {
|
||||
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
|
||||
context_->PSSetShaderResources(binding, 1, &fb->colorSRView);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindFramebufferForRead(Framebuffer *fbo) {
|
||||
// This is meaningless in D3D11
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindBackbufferAsRenderTarget() {
|
||||
context_->OMSetRenderTargets(1, &bbRenderTargetView_, bbDepthStencilView_);
|
||||
}
|
||||
|
||||
uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) {
|
||||
// D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
|
||||
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
|
||||
@@ -581,8 +1094,8 @@ void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h
|
||||
*h = fb->height;
|
||||
}
|
||||
|
||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context) {
|
||||
return nullptr; // new D3D11DrawContext(device, context);
|
||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, HWND hWnd) {
|
||||
return new D3D11DrawContext(device, context, hWnd);
|
||||
}
|
||||
|
||||
} // namespace Draw
|
||||
@@ -142,6 +142,8 @@ static int FormatToD3DDeclType(DataFormat type) {
|
||||
}
|
||||
}
|
||||
|
||||
class D3D9Buffer;
|
||||
|
||||
class D3D9DepthStencilState : public DepthStencilState {
|
||||
public:
|
||||
BOOL depthTestEnabled;
|
||||
@@ -219,77 +221,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Simulate a simple buffer type like the other backends have, use the usage flags to create the right internal type.
|
||||
class D3D9Buffer : public Buffer {
|
||||
public:
|
||||
D3D9Buffer(LPDIRECT3DDEVICE9 device, size_t size, uint32_t flags) : vbuffer_(nullptr), ibuffer_(nullptr), maxSize_(size) {
|
||||
if (flags & BufferUsageFlag::INDEXDATA) {
|
||||
DWORD usage = D3DUSAGE_DYNAMIC;
|
||||
device->CreateIndexBuffer((UINT)size, usage, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &ibuffer_, NULL);
|
||||
}
|
||||
else {
|
||||
DWORD usage = D3DUSAGE_DYNAMIC;
|
||||
device->CreateVertexBuffer((UINT)size, usage, 0, D3DPOOL_DEFAULT, &vbuffer_, NULL);
|
||||
}
|
||||
}
|
||||
virtual ~D3D9Buffer() override {
|
||||
if (ibuffer_) {
|
||||
ibuffer_->Release();
|
||||
}
|
||||
if (vbuffer_) {
|
||||
vbuffer_->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(const uint8_t *data, size_t size) override {
|
||||
if (!size)
|
||||
return;
|
||||
if (size > maxSize_) {
|
||||
ELOG("Can't SetData with bigger size than buffer was created with on D3D");
|
||||
return;
|
||||
}
|
||||
if (vbuffer_) {
|
||||
void *ptr;
|
||||
vbuffer_->Lock(0, (UINT)size, &ptr, D3DLOCK_DISCARD);
|
||||
memcpy(ptr, data, size);
|
||||
vbuffer_->Unlock();
|
||||
} else if (ibuffer_) {
|
||||
void *ptr;
|
||||
ibuffer_->Lock(0, (UINT)size, &ptr, D3DLOCK_DISCARD);
|
||||
memcpy(ptr, data, size);
|
||||
ibuffer_->Unlock();
|
||||
}
|
||||
}
|
||||
void SubData(const uint8_t *data, size_t offset, size_t size) override {
|
||||
if (!size)
|
||||
return;
|
||||
if (offset + size > maxSize_) {
|
||||
ELOG("Can't SubData with bigger size than buffer was created with on D3D");
|
||||
return;
|
||||
}
|
||||
if (vbuffer_) {
|
||||
void *ptr;
|
||||
HRESULT res = vbuffer_->Lock((UINT)offset, (UINT)size, &ptr, D3DLOCK_DISCARD);
|
||||
if (!FAILED(res)) {
|
||||
memcpy(ptr, data, size);
|
||||
vbuffer_->Unlock();
|
||||
}
|
||||
} else if (ibuffer_) {
|
||||
void *ptr;
|
||||
HRESULT res = ibuffer_->Lock((UINT)offset, (UINT)size, &ptr, D3DLOCK_DISCARD);
|
||||
if (!FAILED(res)) {
|
||||
memcpy(ptr, data, size);
|
||||
ibuffer_->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
LPDIRECT3DVERTEXBUFFER9 vbuffer_;
|
||||
LPDIRECT3DINDEXBUFFER9 ibuffer_;
|
||||
size_t maxSize_;
|
||||
};
|
||||
|
||||
class D3D9InputLayout : public InputLayout {
|
||||
public:
|
||||
D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc);
|
||||
@@ -550,6 +481,9 @@ public:
|
||||
Texture *CreateTexture(const TextureDesc &desc) override;
|
||||
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override {}
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
@@ -847,10 +781,61 @@ D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc
|
||||
delete[] elements;
|
||||
}
|
||||
|
||||
// Simulate a simple buffer type like the other backends have, use the usage flags to create the right internal type.
|
||||
class D3D9Buffer : public Buffer {
|
||||
public:
|
||||
D3D9Buffer(LPDIRECT3DDEVICE9 device, size_t size, uint32_t flags) : vbuffer_(nullptr), ibuffer_(nullptr), maxSize_(size) {
|
||||
if (flags & BufferUsageFlag::INDEXDATA) {
|
||||
DWORD usage = D3DUSAGE_DYNAMIC;
|
||||
device->CreateIndexBuffer((UINT)size, usage, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &ibuffer_, NULL);
|
||||
} else {
|
||||
DWORD usage = D3DUSAGE_DYNAMIC;
|
||||
device->CreateVertexBuffer((UINT)size, usage, 0, D3DPOOL_DEFAULT, &vbuffer_, NULL);
|
||||
}
|
||||
}
|
||||
virtual ~D3D9Buffer() override {
|
||||
if (ibuffer_) {
|
||||
ibuffer_->Release();
|
||||
}
|
||||
if (vbuffer_) {
|
||||
vbuffer_->Release();
|
||||
}
|
||||
}
|
||||
|
||||
LPDIRECT3DVERTEXBUFFER9 vbuffer_;
|
||||
LPDIRECT3DINDEXBUFFER9 ibuffer_;
|
||||
size_t maxSize_;
|
||||
};
|
||||
|
||||
Buffer *D3D9Context::CreateBuffer(size_t size, uint32_t usageFlags) {
|
||||
return new D3D9Buffer(device_, size, usageFlags);
|
||||
}
|
||||
|
||||
void D3D9Context::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) {
|
||||
D3D9Buffer *buf = (D3D9Buffer *)buffer;
|
||||
if (!size)
|
||||
return;
|
||||
if (offset + size > buf->maxSize_) {
|
||||
ELOG("Can't SubData with bigger size than buffer was created with");
|
||||
return;
|
||||
}
|
||||
if (buf->vbuffer_) {
|
||||
void *ptr;
|
||||
HRESULT res = buf->vbuffer_->Lock((UINT)offset, (UINT)size, &ptr, (flags & UPDATE_DISCARD) ? D3DLOCK_DISCARD : 0);
|
||||
if (!FAILED(res)) {
|
||||
memcpy(ptr, data, size);
|
||||
buf->vbuffer_->Unlock();
|
||||
}
|
||||
} else if (buf->ibuffer_) {
|
||||
void *ptr;
|
||||
HRESULT res = buf->ibuffer_->Lock((UINT)offset, (UINT)size, &ptr, (flags & UPDATE_DISCARD) ? D3DLOCK_DISCARD : 0);
|
||||
if (!FAILED(res)) {
|
||||
memcpy(ptr, data, size);
|
||||
buf->ibuffer_->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D3D9Pipeline::Apply(LPDIRECT3DDEVICE9 device) {
|
||||
vshader->Apply(device);
|
||||
pshader->Apply(device);
|
||||
|
||||
@@ -153,6 +153,8 @@ static const unsigned short primToGL[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
class OpenGLBuffer;
|
||||
|
||||
static const char *glsl_fragment_prelude =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision mediump float;\n"
|
||||
@@ -270,62 +272,6 @@ public:
|
||||
GLenum frontFace;
|
||||
};
|
||||
|
||||
class OpenGLBuffer : public Buffer, GfxResourceHolder {
|
||||
public:
|
||||
OpenGLBuffer(size_t size, uint32_t flags) {
|
||||
glGenBuffers(1, &buffer_);
|
||||
target_ = (flags & BufferUsageFlag::INDEXDATA) ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER;
|
||||
usage_ = 0;
|
||||
if (flags & BufferUsageFlag::DYNAMIC)
|
||||
usage_ = GL_STREAM_DRAW;
|
||||
else
|
||||
usage_ = GL_STATIC_DRAW;
|
||||
knownSize_ = 0;
|
||||
register_gl_resource_holder(this);
|
||||
}
|
||||
~OpenGLBuffer() override {
|
||||
unregister_gl_resource_holder(this);
|
||||
glDeleteBuffers(1, &buffer_);
|
||||
}
|
||||
|
||||
void SetData(const uint8_t *data, size_t size) override {
|
||||
Bind(0);
|
||||
glBufferData(target_, size, data, usage_);
|
||||
knownSize_ = size;
|
||||
}
|
||||
|
||||
void SubData(const uint8_t *data, size_t offset, size_t size) override {
|
||||
Bind(0);
|
||||
if (size + offset > knownSize_) {
|
||||
// Allocate the buffer.
|
||||
glBufferData(target_, size + offset, NULL, usage_);
|
||||
knownSize_ = size + offset;
|
||||
}
|
||||
glBufferSubData(target_, offset, size, data);
|
||||
}
|
||||
void Bind(int offset) {
|
||||
// TODO: Can't support offset using ES 2.0
|
||||
glBindBuffer(target_, buffer_);
|
||||
}
|
||||
|
||||
void GLLost() override {
|
||||
buffer_ = 0;
|
||||
}
|
||||
|
||||
void GLRestore() override {
|
||||
ILOG("Recreating vertex buffer after gl_restore");
|
||||
knownSize_ = 0; // Will cause a new glBufferData call. Should genBuffers again though?
|
||||
glGenBuffers(1, &buffer_);
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint buffer_;
|
||||
GLuint target_;
|
||||
GLuint usage_;
|
||||
|
||||
size_t knownSize_;
|
||||
};
|
||||
|
||||
GLuint ShaderStageToOpenGL(ShaderStage stage) {
|
||||
switch (stage) {
|
||||
case ShaderStage::VERTEX: return GL_VERTEX_SHADER;
|
||||
@@ -524,6 +470,8 @@ public:
|
||||
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
@@ -939,10 +887,63 @@ RasterState *OpenGLContext::CreateRasterState(const RasterStateDesc &desc) {
|
||||
return rs;
|
||||
}
|
||||
|
||||
class OpenGLBuffer : public Buffer, GfxResourceHolder {
|
||||
public:
|
||||
OpenGLBuffer(size_t size, uint32_t flags) {
|
||||
glGenBuffers(1, &buffer_);
|
||||
target_ = (flags & BufferUsageFlag::INDEXDATA) ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER;
|
||||
usage_ = 0;
|
||||
if (flags & BufferUsageFlag::DYNAMIC)
|
||||
usage_ = GL_STREAM_DRAW;
|
||||
else
|
||||
usage_ = GL_STATIC_DRAW;
|
||||
totalSize_ = size;
|
||||
glBindBuffer(target_, buffer_);
|
||||
glBufferData(target_, size, NULL, usage_);
|
||||
register_gl_resource_holder(this);
|
||||
}
|
||||
~OpenGLBuffer() override {
|
||||
unregister_gl_resource_holder(this);
|
||||
glDeleteBuffers(1, &buffer_);
|
||||
}
|
||||
|
||||
void Bind(int offset) {
|
||||
// TODO: Can't support offset using ES 2.0
|
||||
glBindBuffer(target_, buffer_);
|
||||
}
|
||||
|
||||
void GLLost() override {
|
||||
buffer_ = 0;
|
||||
}
|
||||
|
||||
void GLRestore() override {
|
||||
ILOG("Recreating vertex buffer after gl_restore");
|
||||
totalSize_ = 0; // Will cause a new glBufferData call. Should genBuffers again though?
|
||||
glGenBuffers(1, &buffer_);
|
||||
}
|
||||
|
||||
GLuint buffer_;
|
||||
GLuint target_;
|
||||
GLuint usage_;
|
||||
|
||||
size_t totalSize_;
|
||||
};
|
||||
|
||||
Buffer *OpenGLContext::CreateBuffer(size_t size, uint32_t usageFlags) {
|
||||
return new OpenGLBuffer(size, usageFlags);
|
||||
}
|
||||
|
||||
void OpenGLContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) {
|
||||
OpenGLBuffer *buf = (OpenGLBuffer *)buffer;
|
||||
|
||||
buf->Bind(0);
|
||||
if (size + offset > buf->totalSize_) {
|
||||
Crash();
|
||||
}
|
||||
// if (flags & UPDATE_DISCARD) we could try to orphan the buffer using glBufferData.
|
||||
glBufferSubData(buf->target_, offset, size, data);
|
||||
}
|
||||
|
||||
Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
if (!desc.shaders.size()) {
|
||||
ELOG("Pipeline requires at least one shader");
|
||||
|
||||
@@ -176,38 +176,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Very simplistic buffer that will simply copy its contents into our "pushbuffer" when it's time to draw,
|
||||
// to avoid synchronization issues.
|
||||
class VKBuffer : public Buffer {
|
||||
public:
|
||||
VKBuffer(size_t size, uint32_t flags) : dataSize_(size) {
|
||||
data_ = new uint8_t[size];
|
||||
}
|
||||
~VKBuffer() override {
|
||||
delete[] data_;
|
||||
}
|
||||
|
||||
void SetData(const uint8_t *data, size_t size) override {
|
||||
delete[] data_;
|
||||
dataSize_ = size;
|
||||
data_ = new uint8_t[size];
|
||||
if (data) {
|
||||
memcpy(data_, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
void SubData(const uint8_t *data, size_t offset, size_t size) override {
|
||||
memcpy(data_, data_ + offset, size);
|
||||
}
|
||||
|
||||
size_t GetSize() const { return dataSize_; }
|
||||
const uint8_t *GetData() const { return data_; }
|
||||
|
||||
private:
|
||||
uint8_t *data_;
|
||||
size_t dataSize_;
|
||||
};
|
||||
|
||||
VkShaderStageFlagBits StageToVulkan(ShaderStage stage) {
|
||||
switch (stage) {
|
||||
case ShaderStage::VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
|
||||
@@ -329,6 +297,7 @@ private:
|
||||
};
|
||||
|
||||
class VKTexture;
|
||||
class VKBuffer;
|
||||
class VKSamplerState;
|
||||
|
||||
struct DescriptorSetKey {
|
||||
@@ -369,6 +338,8 @@ public:
|
||||
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
@@ -1057,10 +1028,33 @@ BlendState *VKContext::CreateBlendState(const BlendStateDesc &desc) {
|
||||
return bs;
|
||||
}
|
||||
|
||||
// Very simplistic buffer that will simply copy its contents into our "pushbuffer" when it's time to draw,
|
||||
// to avoid synchronization issues.
|
||||
class VKBuffer : public Buffer {
|
||||
public:
|
||||
VKBuffer(size_t size, uint32_t flags) : dataSize_(size) {
|
||||
data_ = new uint8_t[size];
|
||||
}
|
||||
~VKBuffer() override {
|
||||
delete[] data_;
|
||||
}
|
||||
|
||||
size_t GetSize() const { return dataSize_; }
|
||||
const uint8_t *GetData() const { return data_; }
|
||||
|
||||
uint8_t *data_;
|
||||
size_t dataSize_;
|
||||
};
|
||||
|
||||
Buffer *VKContext::CreateBuffer(size_t size, uint32_t usageFlags) {
|
||||
return new VKBuffer(size, usageFlags);
|
||||
}
|
||||
|
||||
void VKContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) {
|
||||
VKBuffer *buf = (VKBuffer *)buffer;
|
||||
memcpy(buf->data_ + offset, data, size);
|
||||
}
|
||||
|
||||
void VKContext::BindTextures(int start, int count, Texture **textures) {
|
||||
for (int i = start; i < start + count; i++) {
|
||||
boundTextures_[i] = static_cast<VKTexture *>(textures[i]);
|
||||
|
||||
Reference in new issue
Block a user