From a3343926291a9ed6b2b54d9defedee484a7ec60b Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 22 Oct 2017 15:32:40 +0300 Subject: [PATCH] Experimental DXGI/Direct3D 11 renderer. --- cfgfile.cpp | 11 +- od-win32/direct3d.cpp | 67 +- od-win32/direct3d.h | 51 +- od-win32/direct3d11.cpp | 1211 +++++++++++++++++ od-win32/win32.cpp | 17 +- od-win32/win32gfx.cpp | 2 + od-win32/win32gui.cpp | 10 +- od-win32/winuae_msvc15/winuae_msvc.vcxproj | 27 +- .../winuae_msvc15/winuae_msvc.vcxproj.filters | 3 + 9 files changed, 1322 insertions(+), 77 deletions(-) create mode 100644 od-win32/direct3d11.cpp diff --git a/cfgfile.cpp b/cfgfile.cpp index bcfa5363..6148a803 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -200,7 +200,7 @@ static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 }; static const TCHAR *vsyncmodes[] = { _T("adaptive"), _T("false"), _T("true"), _T("autoswitch"), 0 }; static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 }; -static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), 0 }; +static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), 0 }; static const TCHAR *dongles[] = { _T("none"), @@ -3336,7 +3336,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (s) { *s++ = 0; if (!_tcscmp (value, _T("D3D"))) { - p->gfx_api = 1; + if (!p->gfx_api) + p->gfx_api = 1; if (_tcscmp (option, _T("gfx_filter_pre")) == 0 || _tcscmp (option, _T("gfx_filter_pre_rtg")) == 0) { for (int i = 0; i < MAX_FILTERSHADERS; i++) { if (gf->gfx_filtershader[i][0] == 0) { @@ -3363,7 +3364,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (s) { *s++ = 0; if (!_tcscmp (value, _T("D3D"))) { - p->gfx_api = 1; + if (!p->gfx_api) + p->gfx_api = 1; _tcscpy (gf->gfx_filtershader[2 * MAX_FILTERSHADERS], s); for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) { if (!_tcsicmp (gf->gfx_filtershader[i], s)) { @@ -3380,7 +3382,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) gf->gfx_filtermask[i][0] = 0; } } else if (!_tcscmp (value, _T("direct3d"))) { - p->gfx_api = 1; // forwards compatibiity + if (!p->gfx_api) + p->gfx_api = 1; // forwards compatibiity } else { int i = 0; while(uaefilters[i].name) { diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 35aaa3bc..fdc199b2 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -556,7 +556,7 @@ static int psEffect_ParseParameters (struct d3dstruct *d3d, LPD3DXEFFECTCOMPILER static int psEffect_hasPreProcess (struct shaderdata *s) { return s->m_PreprocessTechnique1EffectHandle != 0; } static int psEffect_hasPreProcess2 (struct shaderdata *s) { return s->m_PreprocessTechnique2EffectHandle != 0; } -int D3D_goodenough (void) +int xD3D_goodenough (void) { static int d3d_good; LPDIRECT3D9 d3dx; @@ -591,7 +591,7 @@ int D3D_goodenough (void) return d3d_good > 0 ? d3d_good : 0; } -int D3D_canshaders (void) +int xD3D_canshaders (void) { static int d3d_yesno = 0; HMODULE h; @@ -2229,7 +2229,7 @@ static void D3D_free2 (struct d3dstruct *d3d) currprefs.leds_on_screen &= ~STATUSLINE_TARGET; } -void D3D_free (bool immediate) +void xD3D_free (bool immediate) { struct d3dstruct *d3d = &d3ddata[0]; if (!fakemodewaitms || immediate) { @@ -2242,7 +2242,7 @@ void D3D_free (bool immediate) #define VBLANKDEBUG 0 -bool D3D_getvblankpos (int *vpos) +static bool xD3D_getvblankpos (int *vpos) { struct d3dstruct *d3d = &d3ddata[0]; HRESULT hr; @@ -2277,7 +2277,7 @@ bool D3D_getvblankpos (int *vpos) return true; } -void D3D_vblank_reset (double freq) +static void xD3D_vblank_reset (double freq) { struct d3dstruct *d3d = &d3ddata[0]; if (!isd3d (d3d)) @@ -2719,7 +2719,7 @@ static void *D3D_init_start (void *p) return NULL; } -const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) +static const TCHAR *xD3D_init (HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) { struct d3dstruct *d3d = &d3ddata[0]; @@ -2745,7 +2745,7 @@ static bool alloctextures (struct d3dstruct *d3d) return true; } -bool D3D_alloctexture (int w, int h) +static bool xD3D_alloctexture (int w, int h) { struct d3dstruct *d3d = &d3ddata[0]; @@ -2890,14 +2890,14 @@ static void D3D_showframe2 (struct d3dstruct *d3d, bool dowait) } } -void D3D_restore (void) +static void xD3D_restore (void) { struct d3dstruct *d3d = &d3ddata[0]; d3d->renderdisabled = false; } -void D3D_clear (void) +static void xD3D_clear (void) { struct d3dstruct *d3d = &d3ddata[0]; int i; @@ -3288,7 +3288,7 @@ static void D3D_render2 (struct d3dstruct *d3d) write_log (_T("%s: EndScene() %s\n"), D3DHEAD, D3D_ErrorString (hr)); } -void D3D_setcursor (int x, int y, int width, int height, bool visible, bool noscale) +static void xD3D_setcursor (int x, int y, int width, int height, bool visible, bool noscale) { struct d3dstruct *d3d = &d3ddata[0]; @@ -3305,7 +3305,7 @@ void D3D_setcursor (int x, int y, int width, int height, bool visible, bool nosc d3d->cursor_v = visible; } -void D3D_unlocktexture (void) +static void xD3D_unlocktexture (void) { struct d3dstruct *d3d = &d3ddata[0]; HRESULT hr; @@ -3322,7 +3322,7 @@ void D3D_unlocktexture (void) d3d->fulllocked = 0; } -void D3D_flushtexture (int miny, int maxy) +static void xD3D_flushtexture (int miny, int maxy) { struct d3dstruct *d3d = &d3ddata[0]; @@ -3344,7 +3344,7 @@ void D3D_flushtexture (int miny, int maxy) } } -uae_u8 *D3D_locktexture (int *pitch, int *height, bool fullupdate) +static uae_u8 *xD3D_locktexture (int *pitch, int *height, bool fullupdate) { struct d3dstruct *d3d = &d3ddata[0]; D3DLOCKED_RECT lock; @@ -3407,7 +3407,7 @@ static void flushgpu (struct d3dstruct *d3d, bool wait) } } -bool D3D_renderframe (bool immediate) +static bool xD3D_renderframe (bool immediate) { struct d3dstruct *d3d = &d3ddata[0]; static int vsync2_cnt; @@ -3446,7 +3446,7 @@ bool D3D_renderframe (bool immediate) return true; } -void D3D_showframe (void) +static void xD3D_showframe (void) { struct d3dstruct *d3d = &d3ddata[0]; @@ -3469,7 +3469,7 @@ void D3D_showframe (void) } } -void D3D_showframe_special (int mode) +static void xD3D_showframe_special (int mode) { struct d3dstruct *d3d = &d3ddata[0]; @@ -3485,7 +3485,7 @@ void D3D_showframe_special (int mode) flushgpu (d3d,true); } -void D3D_refresh (void) +static void xD3D_refresh (void) { struct d3dstruct *d3d = &d3ddata[0]; @@ -3538,7 +3538,7 @@ void D3D_getpixelformat (int depth, int *rb, int *gb, int *bb, int *rs, int *gs, } } -double D3D_getrefreshrate (void) +static double xD3D_getrefreshrate (void) { struct d3dstruct *d3d = &d3ddata[0]; HRESULT hr; @@ -3553,7 +3553,7 @@ double D3D_getrefreshrate (void) return dmode.RefreshRate; } -void D3D_guimode (bool guion) +static void xD3D_guimode (bool guion) { struct d3dstruct *d3d = &d3ddata[0]; HRESULT hr; @@ -3595,7 +3595,7 @@ LPDIRECT3DSURFACE9 D3D_capture(int *w, int *h, int *bits) return d3d->screenshotsurface; } -HDC D3D_getDC (HDC hdc) +static HDC xD3D_getDC (HDC hdc) { struct d3dstruct *d3d = &d3ddata[0]; static LPDIRECT3DSURFACE9 bb; @@ -3624,7 +3624,7 @@ HDC D3D_getDC (HDC hdc) return 0; } -int D3D_isenabled (void) +static int xD3D_isenabled(void) { struct d3dstruct *d3d = &d3ddata[0]; return d3d->d3d_enabled; @@ -3636,4 +3636,29 @@ LPDIRECT3DTEXTURE9 D3D_getcursorsurface(void) return d3d->cursorsurfaced3d; } +void d3d9_select(void) +{ + D3D_free = xD3D_free; + D3D_init = xD3D_init; + D3D_alloctexture = xD3D_alloctexture; + D3D_refresh = xD3D_refresh; + D3D_renderframe = xD3D_renderframe; + D3D_showframe = xD3D_showframe; + D3D_showframe_special = xD3D_showframe_special; + D3D_locktexture = xD3D_locktexture; + D3D_unlocktexture = xD3D_unlocktexture; + D3D_flushtexture = xD3D_flushtexture; + D3D_guimode = xD3D_guimode; + D3D_getDC = xD3D_getDC; + D3D_isenabled = xD3D_isenabled; + D3D_clear = xD3D_clear; + D3D_canshaders = xD3D_canshaders; + D3D_goodenough = xD3D_goodenough; + D3D_setcursor = xD3D_setcursor; + D3D_getvblankpos = xD3D_getvblankpos; + D3D_getrefreshrate = xD3D_getrefreshrate; + D3D_vblank_reset = xD3D_vblank_reset; + D3D_restore = xD3D_restore; +} + #endif diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index f4995776..cb8a4620 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -1,27 +1,34 @@ -extern void D3D_free (bool immediate); -extern const TCHAR *D3D_init (HWND ahwnd, int w_w, int h_h, int depth, int *freq, int mmult); -extern bool D3D_alloctexture (int, int); -extern void D3D_getpixelformat (int depth,int *rb, int *bb, int *gb, int *rs, int *bs, int *gs, int *ab, int *ar, int *a); -extern void D3D_refresh (void); -extern bool D3D_renderframe (bool); -extern void D3D_showframe (void); -extern void D3D_showframe_special (int); -extern uae_u8 *D3D_locktexture(int*, int*, bool); -extern void D3D_unlocktexture(void); -extern void D3D_flushtexture (int miny, int maxy); -extern void D3D_guimode (bool); -extern HDC D3D_getDC(HDC hdc); -extern int D3D_isenabled (void); -extern void D3D_clear (void); -extern int D3D_canshaders (void); -extern int D3D_goodenough (void); -extern void D3D_setcursor (int x, int y, int width, int height, bool visible, bool noscale); -extern bool D3D_getvblankpos (int *vpos); -extern double D3D_getrefreshrate (void); -extern void D3D_vblank_reset (double freq); -extern void D3D_restore (void); + +extern void(*D3D_free)(bool immediate); +extern const TCHAR* (*D3D_init)(HWND ahwnd, int w_w, int h_h, int depth, int *freq, int mmult); +extern bool(*D3D_alloctexture)(int, int); +extern void(*D3D_refresh)(void); +extern bool(*D3D_renderframe)(bool); +extern void(*D3D_showframe)(void); +extern void(*D3D_showframe_special)(int); +extern uae_u8* (*D3D_locktexture)(int*, int*, bool); +extern void(*D3D_unlocktexture)(void); +extern void(*D3D_flushtexture)(int miny, int maxy); +extern void(*D3D_guimode)(bool); +extern HDC(*D3D_getDC)(HDC hdc); +extern int(*D3D_isenabled)(void); +extern void(*D3D_clear)(void); +extern int(*D3D_canshaders)(void); +extern int(*D3D_goodenough)(void); +extern void(*D3D_setcursor)(int x, int y, int width, int height, bool visible, bool noscale); +extern bool(*D3D_getvblankpos)(int *vpos); +extern double(*D3D_getrefreshrate)(void); +extern void(*D3D_vblank_reset)(double freq); +extern void(*D3D_restore)(void); + extern LPDIRECT3DSURFACE9 D3D_capture(int*,int*,int*); extern LPDIRECT3DTEXTURE9 D3D_getcursorsurface(void); +void D3D_getpixelformat(int depth, int *rb, int *gb, int *bb, int *rs, int *gs, int *bs, int *ab, int *as, int *a); + +void d3d9_select(void); +void d3d11_select(void); +void d3d_select(struct uae_prefs *p); + #define CURSORMAXWIDTH 64 #define CURSORMAXHEIGHT 64 diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp new file mode 100644 index 00000000..c8ce638a --- /dev/null +++ b/od-win32/direct3d11.cpp @@ -0,0 +1,1211 @@ + +#include +#include "resource.h" + +#include +#include +#include +#include + +#include +using Microsoft::WRL::ComPtr; + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "xwin.h" +#include "dxwrap.h" +#include "win32.h" +#include "win32gfx.h" +#include "direct3d.h" +#include "uae.h" +#include "custom.h" + +void (*D3D_free)(bool immediate); +const TCHAR* (*D3D_init)(HWND ahwnd, int w_w, int h_h, int depth, int *freq, int mmult); +bool (*D3D_alloctexture)(int, int); +void(*D3D_refresh)(void); +bool(*D3D_renderframe)(bool); +void(*D3D_showframe)(void); +void(*D3D_showframe_special)(int); +uae_u8* (*D3D_locktexture)(int*, int*, bool); +void (*D3D_unlocktexture)(void); +void (*D3D_flushtexture)(int miny, int maxy); +void (*D3D_guimode)(bool); +HDC (*D3D_getDC)(HDC hdc); +int (*D3D_isenabled)(void); +void (*D3D_clear)(void); +int (*D3D_canshaders)(void); +int (*D3D_goodenough)(void); +void (*D3D_setcursor)(int x, int y, int width, int height, bool visible, bool noscale); +bool (*D3D_getvblankpos)(int *vpos); +double (*D3D_getrefreshrate)(void); +void (*D3D_vblank_reset)(double freq); +void(*D3D_restore)(void); + +static HANDLE hd3d11, hdxgi, hd3dcompiler; + +static const float SCREEN_DEPTH = 1000.0f; +static const float SCREEN_NEAR = 0.1f; + +struct d3d11struct +{ + IDXGISwapChain1* m_swapChain; + ID3D11Device* m_device; + ID3D11DeviceContext* m_deviceContext; + ID3D11RenderTargetView* m_renderTargetView; + ID3D11RasterizerState* m_rasterState; + D3DXMATRIX m_projectionMatrix; + D3DXMATRIX m_worldMatrix; + D3DXMATRIX m_orthoMatrix; + ID3D11Buffer *m_vertexBuffer, *m_indexBuffer; + ID3D11Buffer* m_matrixBuffer; + int m_screenWidth, m_screenHeight; + int m_bitmapWidth, m_bitmapHeight; + int m_vertexCount, m_indexCount; + float m_positionX, m_positionY, m_positionZ; + float m_rotationX, m_rotationY, m_rotationZ; + D3DXMATRIX m_viewMatrix; + ID3D11ShaderResourceView *texture; + ID3D11Texture2D *texture2d; + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11SamplerState* m_sampleState; + ID3D11InputLayout* m_layout; + int texturelocked; + DXGI_FORMAT format; + bool m_tearingSupport; +}; + +struct VertexType +{ + D3DXVECTOR3 position; + D3DXVECTOR2 texture; +}; + +struct MatrixBufferType +{ + D3DXMATRIX world; + D3DXMATRIX view; + D3DXMATRIX projection; +}; + +static struct d3d11struct d3d11data[1]; + +typedef HRESULT (WINAPI* CREATEDXGIFACTORY1)(REFIID riid, void **ppFactory); +typedef HRESULT (WINAPI* D3DCOMPILEFROMFILE)(LPCWSTR pFileName, + CONST D3D_SHADER_MACRO* pDefines, + ID3DInclude* pInclude, + LPCSTR pEntrypoint, + LPCSTR pTarget, + UINT Flags1, + UINT Flags2, + ID3DBlob** ppCode, + ID3DBlob** ppErrorMsgs); + +static PFN_D3D11_CREATE_DEVICE pD3D11CreateDevice; +static CREATEDXGIFACTORY1 pCreateDXGIFactory1; +static D3DCOMPILEFROMFILE pD3DCompileFromFile; + +static void FreeTexture(void) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + if (d3d->texture) + d3d->texture->Release(); + d3d->texture = NULL; + + if (d3d->texture2d) + d3d->texture2d->Release(); + d3d->texture2d = NULL; +} + +static bool CreateTexture(void) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + D3D11_TEXTURE2D_DESC desc; + + FreeTexture(); + + memset(&desc, 0, sizeof desc); + desc.Width = d3d->m_bitmapWidth; + desc.Height = d3d->m_bitmapHeight; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = d3d->format; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + HRESULT hr = d3d->m_device->CreateTexture2D(&desc, NULL, &d3d->texture2d); + if (FAILED(hr)) { + write_log(_T("CreateTexture2D failed: %08x\n"), hr); + return false; + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + srvDesc.Format = d3d->format; + + hr = d3d->m_device->CreateShaderResourceView(d3d->texture2d, &srvDesc, &d3d->texture); + if (FAILED(hr)) { + write_log(_T("CreateShaderResourceView failed: %08x\n"), hr); + return false; + } + + return true; +} + +static void OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, TCHAR* shaderFilename) +{ + char* compileErrors; + unsigned long bufferSize; + + if (errorMessage) { + // Get a pointer to the error message text buffer. + compileErrors = (char*)(errorMessage->GetBufferPointer()); + + // Get the length of the message. + bufferSize = errorMessage->GetBufferSize(); + + write_log(_T("D3D11 Shader error: %s"), compileErrors); + + // Release the error message. + errorMessage->Release(); + } else { + + write_log(_T("D3D11 Shader error: %08x"), GetLastError()); + + } +} + +static bool TextureShaderClass_InitializeShader(ID3D11Device* device, HWND hwnd) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + HRESULT result; + ID3D10Blob* errorMessage; + ID3D10Blob* vertexShaderBuffer; + ID3D10Blob* pixelShaderBuffer; + D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; + unsigned int numElements; + D3D11_BUFFER_DESC matrixBufferDesc; + D3D11_SAMPLER_DESC samplerDesc; + bool plugin_path; + TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH]; + + plugin_path = get_plugin_path(tmp, sizeof tmp / sizeof(TCHAR), _T("filtershaders\\direct3d11")); + if (!plugin_path) + return false; + + // Initialize the pointers this function will use to null. + errorMessage = 0; + vertexShaderBuffer = 0; + pixelShaderBuffer = 0; + + // Compile the vertex shader code. + _tcscpy(tmp2, tmp); + _tcscat(tmp2, _T("_winuae.vs")); + //result = D3DX11CompileFromFile(vsFilename, NULL, NULL, "TextureVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &vertexShaderBuffer, &errorMessage, NULL); + result = pD3DCompileFromFile(tmp2, NULL, NULL, "TextureVertexShader", "vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, &vertexShaderBuffer, &errorMessage); + if (FAILED(result)) + { + OutputShaderErrorMessage(errorMessage, hwnd, tmp2); + return false; + } + + // Compile the pixel shader code. + _tcscpy(tmp2, tmp); + _tcscat(tmp2, _T("_winuae.ps")); + //result = D3DX11CompileFromFile(psFilename, NULL, NULL, "TexturePixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &pixelShaderBuffer, &errorMessage, NULL); + result = pD3DCompileFromFile(tmp2, NULL, NULL, "TexturePixelShader", "ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, &pixelShaderBuffer, &errorMessage); + if (FAILED(result)) + { + OutputShaderErrorMessage(errorMessage, hwnd, tmp2); + return false; + } + + // Create the vertex shader from the buffer. + result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &d3d->m_vertexShader); + if (FAILED(result)) + { + return false; + } + + // Create the pixel shader from the buffer. + result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &d3d->m_pixelShader); + if (FAILED(result)) + { + return false; + } + + // Create the vertex input layout description. + // This setup needs to match the VertexType stucture in the ModelClass and in the shader. + polygonLayout[0].SemanticName = "POSITION"; + polygonLayout[0].SemanticIndex = 0; + polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; + polygonLayout[0].InputSlot = 0; + polygonLayout[0].AlignedByteOffset = 0; + polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[0].InstanceDataStepRate = 0; + + polygonLayout[1].SemanticName = "TEXCOORD"; + polygonLayout[1].SemanticIndex = 0; + polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT; + polygonLayout[1].InputSlot = 0; + polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[1].InstanceDataStepRate = 0; + + // Get a count of the elements in the layout. + numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); + + // Create the vertex input layout. + result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &d3d->m_layout); + if (FAILED(result)) + { + return false; + } + + // Release the vertex shader buffer and pixel shader buffer since they are no longer needed. + vertexShaderBuffer->Release(); + vertexShaderBuffer = 0; + + pixelShaderBuffer->Release(); + pixelShaderBuffer = 0; + + // Setup the description of the dynamic matrix constant buffer that is in the vertex shader. + matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType); + matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + matrixBufferDesc.MiscFlags = 0; + matrixBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&matrixBufferDesc, NULL, &d3d->m_matrixBuffer); + if (FAILED(result)) + { + return false; + } + + // Create a texture sampler state description. + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + samplerDesc.BorderColor[0] = 0; + samplerDesc.BorderColor[1] = 0; + samplerDesc.BorderColor[2] = 0; + samplerDesc.BorderColor[3] = 0; + samplerDesc.MinLOD = 0; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + + // Create the texture sampler state. + result = device->CreateSamplerState(&samplerDesc, &d3d->m_sampleState); + if (FAILED(result)) + { + return false; + } + + return true; +} + +static bool InitializeBuffers(ID3D11Device* device) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + VertexType* vertices; + unsigned long* indices; + D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; + D3D11_SUBRESOURCE_DATA vertexData, indexData; + HRESULT result; + int i; + + + // Set the number of vertices in the vertex array. + d3d->m_vertexCount = 6; + + // Set the number of indices in the index array. + d3d->m_indexCount = d3d->m_vertexCount; + + // Create the vertex array. + vertices = new VertexType[d3d->m_vertexCount]; + if (!vertices) + { + return false; + } + + // Create the index array. + indices = new unsigned long[d3d->m_indexCount]; + if (!indices) + { + return false; + } + + // Initialize vertex array to zeros at first. + memset(vertices, 0, (sizeof(VertexType) * d3d->m_vertexCount)); + + // Load the index array with data. + for (i = 0; i < d3d->m_indexCount; i++) + { + indices[i] = i; + } + + // Set up the description of the static vertex buffer. + vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + vertexBufferDesc.ByteWidth = sizeof(VertexType) * d3d->m_vertexCount; + vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vertexBufferDesc.MiscFlags = 0; + vertexBufferDesc.StructureByteStride = 0; + + // Give the subresource structure a pointer to the vertex data. + vertexData.pSysMem = vertices; + vertexData.SysMemPitch = 0; + vertexData.SysMemSlicePitch = 0; + + // Now create the vertex buffer. + result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &d3d->m_vertexBuffer); + if (FAILED(result)) + { + return false; + } + + // Set up the description of the static index buffer. + indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; + indexBufferDesc.ByteWidth = sizeof(unsigned long) * d3d->m_indexCount; + indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + indexBufferDesc.CPUAccessFlags = 0; + indexBufferDesc.MiscFlags = 0; + indexBufferDesc.StructureByteStride = 0; + + // Give the subresource structure a pointer to the index data. + indexData.pSysMem = indices; + indexData.SysMemPitch = 0; + indexData.SysMemSlicePitch = 0; + + // Create the index buffer. + result = device->CreateBuffer(&indexBufferDesc, &indexData, &d3d->m_indexBuffer); + if (FAILED(result)) + { + return false; + } + + // Release the arrays now that the vertex and index buffers have been created and loaded. + delete[] vertices; + vertices = 0; + + delete[] indices; + indices = 0; + + return true; +} + + +static bool UpdateBuffers(ID3D11DeviceContext* deviceContext, int positionX, int positionY) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + float left, right, top, bottom; + VertexType* vertices; + D3D11_MAPPED_SUBRESOURCE mappedResource; + VertexType* verticesPtr; + HRESULT result; + + positionX = (d3d->m_screenWidth - d3d->m_bitmapWidth) / 2; + positionY = (d3d->m_screenHeight - d3d->m_bitmapHeight) / 2; + + + // Calculate the screen coordinates of the left side of the bitmap. + left = (float)((d3d->m_screenWidth / 2) * -1) + (float)positionX; + + // Calculate the screen coordinates of the right side of the bitmap. + right = left + (float)d3d->m_bitmapWidth; + + // Calculate the screen coordinates of the top of the bitmap. + top = (float)(d3d->m_screenHeight / 2) - (float)positionY; + + // Calculate the screen coordinates of the bottom of the bitmap. + bottom = top - (float)d3d->m_bitmapHeight; + + // Create the vertex array. + vertices = new VertexType[d3d->m_vertexCount]; + if (!vertices) + { + return false; + } + + // Load the vertex array with data. + // First triangle. + vertices[0].position = D3DXVECTOR3(left, top, 0.0f); // Top left. + vertices[0].texture = D3DXVECTOR2(0.0f, 0.0f); + + vertices[1].position = D3DXVECTOR3(right, bottom, 0.0f); // Bottom right. + vertices[1].texture = D3DXVECTOR2(1.0f, 1.0f); + + vertices[2].position = D3DXVECTOR3(left, bottom, 0.0f); // Bottom left. + vertices[2].texture = D3DXVECTOR2(0.0f, 1.0f); + + // Second triangle. + vertices[3].position = D3DXVECTOR3(left, top, 0.0f); // Top left. + vertices[3].texture = D3DXVECTOR2(0.0f, 0.0f); + + vertices[4].position = D3DXVECTOR3(right, top, 0.0f); // Top right. + vertices[4].texture = D3DXVECTOR2(1.0f, 0.0f); + + vertices[5].position = D3DXVECTOR3(right, bottom, 0.0f); // Bottom right. + vertices[5].texture = D3DXVECTOR2(1.0f, 1.0f); + + // Lock the vertex buffer so it can be written to. + result = deviceContext->Map(d3d->m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the vertex buffer. + verticesPtr = (VertexType*)mappedResource.pData; + + // Copy the data into the vertex buffer. + memcpy(verticesPtr, (void*)vertices, (sizeof(VertexType) * d3d->m_vertexCount)); + + // Unlock the vertex buffer. + deviceContext->Unmap(d3d->m_vertexBuffer, 0); + + // Release the vertex array as it is no longer needed. + delete[] vertices; + vertices = 0; + + return true; +} + +static const bool xxD3D11_init(HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) +{ + struct d3d11struct *d3d = &d3d11data[0]; + struct apmode *apm = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + + HRESULT result; + ComPtr factory2; + ComPtr factory4; + ComPtr factory5; + IDXGIAdapter1* adapter; + IDXGIOutput* adapterOutput; + unsigned int numModes, i; + DXGI_MODE_DESC1* displayModeList; + DXGI_ADAPTER_DESC adapterDesc; + DXGI_SWAP_CHAIN_DESC1 swapChainDesc; + DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsSwapChainDesc; + ID3D11Texture2D* backBufferPtr; + D3D11_RASTERIZER_DESC rasterDesc; + D3D11_VIEWPORT viewport; + float fieldOfView, screenAspect; + + write_log(_T("D3D11 init start\n")); + + if (!hd3d11) + hd3d11 = LoadLibrary(_T("D3D11.dll")); + if (!hdxgi) + hdxgi = LoadLibrary(_T("Dxgi.dll")); + if (!hd3dcompiler) + hd3dcompiler = LoadLibrary(_T("D3DCompiler_47.dll")); + + pD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(GetModuleHandle(_T("D3D11.dll")), "D3D11CreateDevice"); + pCreateDXGIFactory1 = (CREATEDXGIFACTORY1)GetProcAddress(GetModuleHandle(_T("Dxgi.dll")), "CreateDXGIFactory1"); + pD3DCompileFromFile = (D3DCOMPILEFROMFILE)GetProcAddress(GetModuleHandle(_T("D3DCompiler_47.dll")), "D3DCompileFromFile"); + + d3d->m_bitmapWidth = w_w; + d3d->m_bitmapHeight = w_h; + d3d->m_screenWidth = w_w; + d3d->m_screenHeight = w_h; + d3d->format = DXGI_FORMAT_B8G8R8A8_UNORM; + + struct MultiDisplay *md = getdisplay(&currprefs); + + // Create a DirectX graphics interface factory. + result = pCreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&factory4); + if (FAILED(result)) + { + write_log(_T("D3D11 CreateDXGIFactory4 %08x\n"), result); + result = pCreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&factory2); + if (FAILED(result)) { + write_log(_T("D3D11 CreateDXGIFactory2 %08x\n"), result); + return false; + } + factory2 = factory4; + } else { + BOOL allowTearing = FALSE; + result = factory4.As(&factory5); + factory2 = factory5; + if (!d3d->m_tearingSupport) { + result = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)); + d3d->m_tearingSupport = SUCCEEDED(result) && allowTearing; + write_log(_T("CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING) = %08x %d"), result, allowTearing); + } + } + + // Use the factory to create an adapter for the primary graphics interface (video card). + result = factory2->EnumAdapters1(0, &adapter); + if (FAILED(result)) + { + return false; + } + + + // Enumerate the primary adapter output (monitor). + result = adapter->EnumOutputs(0, &adapterOutput); + if (FAILED(result)) + { + return false; + } + + ComPtr adapterOutput1; + result = adapterOutput->QueryInterface(__uuidof(IDXGIOutput1), &adapterOutput1); + if (FAILED(result)) { + write_log(_T("QueryInterface IDXGIOutput1 %08x\n"), result); + } + + + // Get the number of modes that fit the display format for the adapter output (monitor). + result = adapterOutput1->GetDisplayModeList1(d3d->format, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); + if (FAILED(result)) + { + return false; + } + + // Create a list to hold all the possible display modes for this monitor/video card combination. + displayModeList = new DXGI_MODE_DESC1[numModes]; + if (!displayModeList) + { + return false; + } + + // Now fill the display mode list structures. + result = adapterOutput1->GetDisplayModeList1(d3d->format, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); + if (FAILED(result)) + { + return false; + } + + ZeroMemory(&fsSwapChainDesc, sizeof(fsSwapChainDesc)); + + // Now go through all the display modes and find the one that matches the screen width and height. + // When a match is found store the numerator and denominator of the refresh rate for that monitor. + for (i = 0; i < numModes; i++) + { + DXGI_MODE_DESC1 *m = &displayModeList[i]; + if (m->Format != d3d->format) + continue; + if (m->Width == md->rect.right - md->rect.left && m->Height == md->rect.bottom - md->rect.top) { + fsSwapChainDesc.RefreshRate.Denominator = m->RefreshRate.Denominator; + fsSwapChainDesc.RefreshRate.Numerator = m->RefreshRate.Numerator; + fsSwapChainDesc.ScanlineOrdering = m->ScanlineOrdering; + fsSwapChainDesc.Scaling = m->Scaling; + if (apm->gfx_interlaced && !(m->ScanlineOrdering & DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST)) + continue; + } + } + + // Get the adapter (video card) description. + result = adapter->GetDesc(&adapterDesc); + if (FAILED(result)) + { + return false; + } + + // Release the display mode list. + delete[] displayModeList; + displayModeList = 0; + + // Release the adapter output. + adapterOutput->Release(); + adapterOutput = 0; + + // Release the adapter. + adapter->Release(); + adapter = 0; + + static const D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 }; + result = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT, levels, 2, D3D11_SDK_VERSION, &d3d->m_device, NULL, &d3d->m_deviceContext); + if (FAILED(result)) { + write_log(_T("D3D11CreateDevice failed %08x\n"), result); + return false; + } + + ComPtr dxgiDevice; + result = d3d->m_device->QueryInterface(__uuidof(IDXGIDevice1), &dxgiDevice); + if (FAILED(result)) { + write_log(_T("QueryInterface IDXGIDevice1 %08x\n"), result); + } + result = dxgiDevice->SetMaximumFrameLatency(1); + + // Initialize the swap chain description. + ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); + + // Set the width and height of the back buffer. + swapChainDesc.Width = w_w; + swapChainDesc.Height = w_h; + + // Set regular 32-bit surface for the back buffer. + swapChainDesc.Format = d3d->format; + + // Turn multisampling off. + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + + // Set the usage of the back buffer. + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + + swapChainDesc.BufferCount = 2; + + swapChainDesc.Scaling = DXGI_SCALING_NONE; + + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + + // It is recommended to always use the tearing flag when it is supported. + swapChainDesc.Flags = d3d->m_tearingSupport ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; + + fsSwapChainDesc.Windowed = isfullscreen() <= 0; + + // Create the swap chain, Direct3D device, and Direct3D device context. + result = factory2->CreateSwapChainForHwnd(d3d->m_device, ahwnd, &swapChainDesc, isfullscreen() > 0 ? &fsSwapChainDesc : NULL, NULL, &d3d->m_swapChain); + + // Set the feature level to DirectX 11. + // featureLevel = D3D_FEATURE_LEVEL_11_0; + // result = pD3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &d3d->m_swapChain, + // &d3d->m_device, NULL, &d3d->m_deviceContext); + if (FAILED(result)) + { + return false; + } + + // Get the pointer to the back buffer. + result = d3d->m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); + if (FAILED(result)) + { + return false; + } + + // Create the render target view with the back buffer pointer. + result = d3d->m_device->CreateRenderTargetView(backBufferPtr, NULL, &d3d->m_renderTargetView); + if (FAILED(result)) + { + return false; + } + + // Release pointer to the back buffer as we no longer need it. + backBufferPtr->Release(); + backBufferPtr = 0; + + + // Setup the raster description which will determine how and what polygons will be drawn. + rasterDesc.AntialiasedLineEnable = false; + rasterDesc.CullMode = D3D11_CULL_BACK; + rasterDesc.DepthBias = 0; + rasterDesc.DepthBiasClamp = 0.0f; + rasterDesc.DepthClipEnable = false; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.FrontCounterClockwise = false; + rasterDesc.MultisampleEnable = false; + rasterDesc.ScissorEnable = false; + rasterDesc.SlopeScaledDepthBias = 0.0f; + + // Create the rasterizer state from the description we just filled out. + result = d3d->m_device->CreateRasterizerState(&rasterDesc, &d3d->m_rasterState); + if (FAILED(result)) + { + return false; + } + + // Now set the rasterizer state. + d3d->m_deviceContext->RSSetState(d3d->m_rasterState); + + // Setup the viewport for rendering. + viewport.Width = (float)w_w; + viewport.Height = (float)w_h; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + + // Create the viewport. + d3d->m_deviceContext->RSSetViewports(1, &viewport); + + // Setup the projection matrix. + fieldOfView = (float)D3DX_PI / 4.0f; + screenAspect = (float)w_w / (float)w_h; + + // Create the projection matrix for 3D rendering. + D3DXMatrixPerspectiveFovLH(&d3d->m_projectionMatrix, fieldOfView, screenAspect, SCREEN_NEAR, SCREEN_DEPTH); + + // Initialize the world matrix to the identity matrix. + D3DXMatrixIdentity(&d3d->m_worldMatrix); + + // Create an orthographic projection matrix for 2D rendering. + D3DXMatrixOrthoLH(&d3d->m_orthoMatrix, (float)w_w, (float)w_h, SCREEN_NEAR, SCREEN_DEPTH); + + d3d->m_positionX = 0.0f; + d3d->m_positionY = 0.0f; + d3d->m_positionZ = -10.0f; + + d3d->m_rotationX = 0.0f; + d3d->m_rotationY = 0.0f; + d3d->m_rotationZ = 0.0f; + + if (!TextureShaderClass_InitializeShader(d3d->m_device, ahwnd)) + return false; + if (!InitializeBuffers(d3d->m_device)) + return false; + if (!UpdateBuffers(d3d->m_deviceContext, 0, 0)) + return false; + + write_log(_T("D3D11 init end\n")); + return true; +} + +static void xD3D11_free(bool immediate) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + write_log(_T("D3D11 free start\n")); + + // Before shutting down set to windowed mode or when you release the swap chain it will throw an exception. + if (d3d->m_swapChain) + { + d3d->m_swapChain->SetFullscreenState(false, NULL); + } + if (d3d->m_rasterState) + { + d3d->m_rasterState->Release(); + d3d->m_rasterState = 0; + } + + if (d3d->m_renderTargetView) + { + d3d->m_renderTargetView->Release(); + d3d->m_renderTargetView = 0; + } + + if (d3d->m_swapChain) + { + d3d->m_swapChain->Release(); + d3d->m_swapChain = 0; + } + if (d3d->m_layout) { + d3d->m_layout->Release(); + d3d->m_layout = NULL; + } + if (d3d->m_vertexShader) { + d3d->m_vertexShader->Release(); + d3d->m_vertexShader = NULL; + } + if (d3d->m_pixelShader) { + d3d->m_pixelShader->Release(); + d3d->m_pixelShader = NULL; + } + + if (d3d->m_sampleState) { + d3d->m_sampleState->Release(); + d3d->m_sampleState = NULL; + } + if (d3d->m_indexBuffer) { + d3d->m_indexBuffer->Release(); + d3d->m_indexBuffer = 0; + } + if (d3d->m_vertexBuffer) { + d3d->m_vertexBuffer->Release(); + d3d->m_vertexBuffer = 0; + } + if (d3d->m_matrixBuffer) { + d3d->m_matrixBuffer->Release(); + d3d->m_matrixBuffer = 0; + } + + FreeTexture(); + + if (d3d->m_deviceContext) + { + d3d->m_deviceContext->ClearState(); + d3d->m_deviceContext->Flush(); + d3d->m_deviceContext->Release(); + d3d->m_deviceContext = 0; + } + + if (d3d->m_device) + { + d3d->m_device->Release(); + d3d->m_device = 0; + } + + write_log(_T("D3D11 free end\n")); +} + + +static const TCHAR *xD3D11_init(HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) +{ + if (xxD3D11_init(ahwnd, w_w, w_h, depth, freq, mmult)) + return NULL; + xD3D11_free(true); + return _T("D3D11 ERROR!"); +} + +static bool TextureShaderClass_SetShaderParameters(ID3D11DeviceContext* deviceContext, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, + D3DXMATRIX projectionMatrix, ID3D11ShaderResourceView* texture) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + MatrixBufferType* dataPtr; + unsigned int bufferNumber; + + + // Transpose the matrices to prepare them for the shader. + D3DXMatrixTranspose(&worldMatrix, &worldMatrix); + D3DXMatrixTranspose(&viewMatrix, &viewMatrix); + D3DXMatrixTranspose(&projectionMatrix, &projectionMatrix); + + // Lock the constant buffer so it can be written to. + result = deviceContext->Map(d3d->m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr = (MatrixBufferType*)mappedResource.pData; + + // Copy the matrices into the constant buffer. + dataPtr->world = worldMatrix; + dataPtr->view = viewMatrix; + dataPtr->projection = projectionMatrix; + + // Unlock the constant buffer. + deviceContext->Unmap(d3d->m_matrixBuffer, 0); + + // Set the position of the constant buffer in the vertex shader. + bufferNumber = 0; + + // Now set the constant buffer in the vertex shader with the updated values. + deviceContext->VSSetConstantBuffers(bufferNumber, 1, &d3d->m_matrixBuffer); + + // Set shader texture resource in the pixel shader. + deviceContext->PSSetShaderResources(0, 1, &texture); + + return true; +} + +static void RenderBuffers(ID3D11DeviceContext* deviceContext) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + unsigned int stride; + unsigned int offset; + + + // Set vertex buffer stride and offset. + stride = sizeof(VertexType); + offset = 0; + + // Set the vertex buffer to active in the input assembler so it can be rendered. + deviceContext->IASetVertexBuffers(0, 1, &d3d->m_vertexBuffer, &stride, &offset); + + // Set the index buffer to active in the input assembler so it can be rendered. + deviceContext->IASetIndexBuffer(d3d->m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); + + // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. + deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); +} + +static void BeginScene(float red, float green, float blue, float alpha) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + float color[4]; + + + // Setup the color to clear the buffer to. + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = alpha; + + // Bind the render target view and depth stencil buffer to the output render pipeline. + d3d->m_deviceContext->OMSetRenderTargets(1, &d3d->m_renderTargetView, NULL); + + // Clear the back buffer. + d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); + + return; +} + +static void EndScene(void) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + HRESULT hr; + + // Present the back buffer to the screen since rendering is complete. + struct apmode *apm = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + if (isfullscreen() > 0) { + hr = d3d->m_swapChain->Present(apm->gfx_vflip == 0 ? 0 : 1, 0); + } else { + UINT presentFlags = d3d->m_tearingSupport ? DXGI_PRESENT_ALLOW_TEARING : 0; + // Present as fast as possible. + hr = d3d->m_swapChain->Present(0, 0); + } + if (FAILED(hr)) + write_log(_T("D3D11 Present %08x\n"), hr); + + return; +} + +static void TextureShaderClass_RenderShader(ID3D11DeviceContext* deviceContext, int indexCount) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + // Set the vertex input layout. + deviceContext->IASetInputLayout(d3d->m_layout); + + // Set the vertex and pixel shaders that will be used to render this triangle. + deviceContext->VSSetShader(d3d->m_vertexShader, NULL, 0); + deviceContext->PSSetShader(d3d->m_pixelShader, NULL, 0); + + // Set the sampler state in the pixel shader. + deviceContext->PSSetSamplers(0, 1, &d3d->m_sampleState); + + // Render the triangle. + deviceContext->DrawIndexed(indexCount, 0, 0); + + return; +} + +static bool TextureShaderClass_Render(ID3D11DeviceContext* deviceContext, int indexCount, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, + D3DXMATRIX projectionMatrix, ID3D11ShaderResourceView* texture) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + bool result; + + + // Set the shader parameters that it will use for rendering. + result = TextureShaderClass_SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture); + if (!result) + { + return false; + } + + // Now render the prepared buffers with the shader. + TextureShaderClass_RenderShader(deviceContext, indexCount); + + return true; +} + +static void CameraClass_Render() +{ + struct d3d11struct *d3d = &d3d11data[0]; + + D3DXVECTOR3 up, position, lookAt; + float yaw, pitch, roll; + D3DXMATRIX rotationMatrix; + + + // Setup the vector that points upwards. + up.x = 0.0f; + up.y = 1.0f; + up.z = 0.0f; + + // Setup the position of the camera in the world. + position.x = d3d->m_positionX; + position.y = d3d->m_positionY; + position.z = d3d->m_positionZ; + + // Setup where the camera is looking by default. + lookAt.x = 0.0f; + lookAt.y = 0.0f; + lookAt.z = 1.0f; + + // Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians. + pitch = d3d->m_rotationX * 0.0174532925f; + yaw = d3d->m_rotationY * 0.0174532925f; + roll = d3d->m_rotationZ * 0.0174532925f; + + // Create the rotation matrix from the yaw, pitch, and roll values. + D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll); + + // Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin. + D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix); + D3DXVec3TransformCoord(&up, &up, &rotationMatrix); + + // Translate the rotated camera position to the location of the viewer. + lookAt = position + lookAt; + + // Finally create the view matrix from the three updated vectors. + D3DXMatrixLookAtLH(&d3d->m_viewMatrix, &position, &lookAt, &up); + + return; +} + +static bool GraphicsClass_Render(float rotation) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + bool result; + + + // Clear the buffers to begin the scene. + BeginScene(0.0f, 0.0f, 0.0f, 1.0f); + + // Generate the view matrix based on the camera's position. + CameraClass_Render(); + + // Put the bitmap vertex and index buffers on the graphics pipeline to prepare them for drawing. + RenderBuffers(d3d->m_deviceContext); + + // Render the bitmap with the texture shader. + result = TextureShaderClass_Render(d3d->m_deviceContext, d3d->m_indexCount, d3d->m_worldMatrix, d3d->m_viewMatrix, d3d->m_orthoMatrix, d3d->texture); + if (!result) + { + return false; + } + + return true; +} + +static bool xD3D11_renderframe(bool immediate) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + GraphicsClass_Render(0); + + return true; +} + + +static void xD3D11_showframe(void) +{ + // Present the rendered scene to the screen. + EndScene(); +} + +static void xD3D11_clear(void) +{ + BeginScene(0, 0, 0, 0); +} + +static void xD3D11_refresh(void) +{ +} + +static bool xD3D11_alloctexture(int w, int h) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + d3d->m_bitmapWidth = w; + d3d->m_bitmapHeight = h; + UpdateBuffers(d3d->m_deviceContext, 0, 0); + return CreateTexture(); +} + +static uae_u8 *xD3D11_locktexture(int *pitch, int *height, bool fullupdate) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + D3D11_MAPPED_SUBRESOURCE map; + HRESULT hr = d3d->m_deviceContext->Map(d3d->texture2d, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + if (FAILED(hr)) { + write_log(_T("D3D11 Map() %08x\n"), hr); + return false; + } + *pitch = map.RowPitch; + if (height) + *height = d3d->m_bitmapHeight; + d3d->texturelocked++; + return (uae_u8*)map.pData; +} + +static void xD3D11_unlocktexture(void) +{ + struct d3d11struct *d3d = &d3d11data[0]; + + if (!d3d->texturelocked) + return; + d3d->texturelocked--; + + d3d->m_deviceContext->Unmap(d3d->texture2d, 0); +} + +static void xD3D11_flushtexture(int miny, int maxy) +{ + struct d3d11struct *d3d = &d3d11data[0]; +} + +static void xD3D11_restore(void) +{ + +} + +static void xD3D11_guimode(bool guion) +{ + +} + +static void xD3D11_vblank_reset(double freq) +{ + +} + +static int xD3D11_canshaders(void) +{ + return 0; +} +static int xD3D11_goodenough(void) +{ + return 0; +} + +void d3d11_select(void) +{ + D3D_free = xD3D11_free; + D3D_init = xD3D11_init; + D3D_renderframe = xD3D11_renderframe; + D3D_alloctexture = xD3D11_alloctexture; + D3D_refresh = xD3D11_refresh; + D3D_restore = xD3D11_restore; + + D3D_locktexture = xD3D11_locktexture; + D3D_unlocktexture = xD3D11_unlocktexture; + D3D_flushtexture = xD3D11_flushtexture; + + D3D_showframe = xD3D11_showframe; + D3D_showframe_special = NULL; + D3D_guimode = xD3D11_guimode; + D3D_getDC = NULL; + D3D_isenabled = NULL; + D3D_clear = xD3D11_clear; + D3D_canshaders = xD3D11_canshaders; + D3D_goodenough = xD3D11_goodenough; + D3D_setcursor = NULL; + D3D_getvblankpos = NULL; + D3D_getrefreshrate = NULL; + D3D_vblank_reset = xD3D11_vblank_reset; +} + +void d3d_select(struct uae_prefs *p) +{ + if (p->gfx_api == 2) + d3d11_select(); + else + d3d9_select(); +} diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 925f7e6a..00b229b9 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -21,7 +21,7 @@ #include "sysconfig.h" #define USETHREADCHARACTERICS 1 -#define _WIN32_WINNT 0x700 /* XButtons + MOUSEHWHEEL=XP, Jump List=Win7 */ +#define _WIN32_WINNT 0x0A00 #include #include @@ -3687,6 +3687,7 @@ void target_fixup_options (struct uae_prefs *p) } } + d3d_select(p); } void target_default_options (struct uae_prefs *p, int type) @@ -7012,7 +7013,7 @@ int isdllversion (const TCHAR *name, int version, int revision, int subver, int DWORD dwVersionHandle, dwFileVersionInfoSize; LPVOID lpFileVersionData = NULL; int ok = 0; - + dwFileVersionInfoSize = GetFileVersionInfoSize (name, &dwVersionHandle); if (dwFileVersionInfoSize) { if (lpFileVersionData = xcalloc (uae_u8, dwFileVersionInfoSize)) { @@ -7173,17 +7174,7 @@ const TCHAR **uaenative_get_library_dirs (void) typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD); #ifndef NDEBUG -typedef struct _PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY { - union { - DWORD Flags; - struct { - DWORD RaiseExceptionOnInvalidHandleReference : 1; - DWORD HandleExceptionsPermanentlyEnabled : 1; - DWORD ReservedFlags : 30; - }; - }; -} PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY; -typedef BOOL (WINAPI* SETPROCESSMITIGATIONPOLICY)(DWORD, PVOID, SIZE_T); +typedef BOOL(WINAPI* SETPROCESSMITIGATIONPOLICY)(DWORD, PVOID, SIZE_T); static SETPROCESSMITIGATIONPOLICY pSetProcessMitigationPolicy; #endif diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 89a6ea0a..69c8865a 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1902,6 +1902,7 @@ static int open_windows (bool mousecapture) static bool started = false; int ret, i; + d3d_select(&currprefs); changevblankthreadmode (VBLANKTH_IDLE); screen_is_initialized = 0; @@ -2911,6 +2912,7 @@ static void gfxmode_reset (void) } } #endif + d3d_select(&currprefs); } int machdep_init (void) diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 0b351fd6..6d73c863 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -11040,10 +11040,11 @@ static void values_to_miscdlg (HWND hDlg) misc_scsi (hDlg); misc_lang (hDlg); - SendDlgItemMessage (hDlg, IDC_DXMODE, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage (hDlg, IDC_DXMODE, CB_ADDSTRING, 0, (LPARAM)_T("DirectDraw")); - SendDlgItemMessage (hDlg, IDC_DXMODE, CB_ADDSTRING, 0, (LPARAM)_T("Direct3D")); - SendDlgItemMessage (hDlg, IDC_DXMODE, CB_SETCURSEL, workprefs.gfx_api, 0); + SendDlgItemMessage(hDlg, IDC_DXMODE, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hDlg, IDC_DXMODE, CB_ADDSTRING, 0, (LPARAM)_T("DirectDraw")); + SendDlgItemMessage(hDlg, IDC_DXMODE, CB_ADDSTRING, 0, (LPARAM)_T("Direct3D 9")); + SendDlgItemMessage(hDlg, IDC_DXMODE, CB_ADDSTRING, 0, (LPARAM)_T("Direct3D 11")); + SendDlgItemMessage(hDlg, IDC_DXMODE, CB_SETCURSEL, workprefs.gfx_api, 0); SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_RESETCONTENT, 0, 0); SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)_T("NonLocalVRAM")); @@ -11249,6 +11250,7 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) v = SendDlgItemMessage (hDlg, IDC_DXMODE, CB_GETCURSEL, 0, 0L); if (v != CB_ERR) { workprefs.gfx_api = v; + d3d_select(&workprefs); enable_for_miscdlg (hDlg); } break; diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj b/od-win32/winuae_msvc15/winuae_msvc.vcxproj index 4d97ba52..f25c1722 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj @@ -156,27 +156,27 @@ winuae64 winuae64 winuae64 - $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath) - $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;C:\dev\include;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;C:\dev\include;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath) + $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.16299.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath) C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath) C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\dev\include;$(IncludePath) $(ReferencePath) - $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;$(LibraryPath) + $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath) true true true true C:\dev\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) C:\dev\lib\x64;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;C:\dev\lib\x64;$(LibraryPath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;C:\dev\lib\x64;$(LibraryPath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;C:\dev\lib\x64;$(LibraryPath) + C:\dev\include;$(IncludePath) + C:\dev\include;$(IncludePath) + C:\dev\lib\x64;$(LibraryPath) + C:\dev\lib\x64;$(LibraryPath) + C:\dev\include;$(IncludePath) + C:\dev\lib\x64;$(LibraryPath) @@ -479,7 +479,7 @@ Full - OnlyExplicitInline + AnySuitable true Speed true @@ -921,6 +921,7 @@ + diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters index 54847e26..32da58e0 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters @@ -856,6 +856,9 @@ common + + win32 + -- 2.47.3