D3D11 window up and spinning.
This commit is contained in:
parent
611d3bbbeb
commit
6e4fb87992
|
@ -18,7 +18,13 @@
|
||||||
#include <xenia/core/mutex.h>
|
#include <xenia/core/mutex.h>
|
||||||
#include <xenia/core/pal.h>
|
#include <xenia/core/pal.h>
|
||||||
#include <xenia/core/ref.h>
|
#include <xenia/core/ref.h>
|
||||||
|
#include <xenia/core/run_loop.h>
|
||||||
#include <xenia/core/socket.h>
|
#include <xenia/core/socket.h>
|
||||||
#include <xenia/core/thread.h>
|
#include <xenia/core/thread.h>
|
||||||
|
#include <xenia/core/window.h>
|
||||||
|
|
||||||
|
#if XE_PLATFORM(WIN32)
|
||||||
|
#include <xenia/core/win32_window.h>
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
#endif // XENIA_CORE_H_
|
#endif // XENIA_CORE_H_
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_CORE_RUN_LOOP_H_
|
||||||
|
#define XENIA_CORE_RUN_LOOP_H_
|
||||||
|
|
||||||
|
#include <xenia/common.h>
|
||||||
|
#include <xenia/core/ref.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct xe_run_loop;
|
||||||
|
typedef struct xe_run_loop* xe_run_loop_ref;
|
||||||
|
|
||||||
|
|
||||||
|
xe_run_loop_ref xe_run_loop_create();
|
||||||
|
xe_run_loop_ref xe_run_loop_retain(xe_run_loop_ref run_loop);
|
||||||
|
void xe_run_loop_release(xe_run_loop_ref run_loop);
|
||||||
|
|
||||||
|
int xe_run_loop_pump(xe_run_loop_ref run_loop);
|
||||||
|
void xe_run_loop_quit(xe_run_loop_ref run_loop);
|
||||||
|
|
||||||
|
typedef void (*xe_run_loop_callback)(void* data);
|
||||||
|
void xe_run_loop_call(xe_run_loop_ref run_loop,
|
||||||
|
xe_run_loop_callback callback, void* data);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_CORE_RUN_LOOP_H_
|
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/core/run_loop.h>
|
||||||
|
|
||||||
|
#include <xenia/core/mutex.h>
|
||||||
|
#include <xenia/core/thread.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct xe_run_loop {
|
||||||
|
xe_ref_t ref;
|
||||||
|
} xe_run_loop_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define WM_XE_RUN_LOOP_QUIT (WM_APP + 0x100)
|
||||||
|
#define WM_XE_RUN_LOOP_CALL (WM_APP + 0x101)
|
||||||
|
|
||||||
|
typedef struct xe_run_loop_call {
|
||||||
|
xe_run_loop_callback callback;
|
||||||
|
void* data;
|
||||||
|
} xe_run_loop_call_t;
|
||||||
|
|
||||||
|
|
||||||
|
xe_run_loop_ref xe_run_loop_create() {
|
||||||
|
xe_run_loop_ref run_loop = (xe_run_loop_ref)xe_calloc(sizeof(xe_run_loop_t));
|
||||||
|
xe_ref_init((xe_ref)run_loop);
|
||||||
|
return run_loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xe_run_loop_dealloc(xe_run_loop_ref run_loop) {
|
||||||
|
}
|
||||||
|
|
||||||
|
xe_run_loop_ref xe_run_loop_retain(xe_run_loop_ref run_loop) {
|
||||||
|
xe_ref_retain((xe_ref)run_loop);
|
||||||
|
return run_loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xe_run_loop_release(xe_run_loop_ref run_loop) {
|
||||||
|
xe_ref_release((xe_ref)run_loop, (xe_ref_dealloc_t)xe_run_loop_dealloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int xe_run_loop_pump(xe_run_loop_ref run_loop) {
|
||||||
|
MSG msg;
|
||||||
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
switch (msg.message) {
|
||||||
|
case WM_XE_RUN_LOOP_CALL:
|
||||||
|
if (msg.wParam == (WPARAM)run_loop) {
|
||||||
|
xe_run_loop_call_t* call = (xe_run_loop_call_t*)msg.lParam;
|
||||||
|
call->callback(call->data);
|
||||||
|
xe_free(call);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_XE_RUN_LOOP_QUIT:
|
||||||
|
if (msg.lParam == (WPARAM)run_loop) {
|
||||||
|
// Done!
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xe_run_loop_quit(xe_run_loop_ref run_loop) {
|
||||||
|
PostMessage(NULL, WM_XE_RUN_LOOP_QUIT, 0, (WPARAM)run_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xe_run_loop_call(xe_run_loop_ref run_loop,
|
||||||
|
xe_run_loop_callback callback, void* data) {
|
||||||
|
xe_run_loop_call_t* call =
|
||||||
|
(xe_run_loop_call_t*)xe_calloc(sizeof(xe_run_loop_call_t));
|
||||||
|
call->callback = callback;
|
||||||
|
call->data = data;
|
||||||
|
PostMessage(NULL, WM_XE_RUN_LOOP_CALL, (WPARAM)run_loop, (LPARAM)call);
|
||||||
|
}
|
|
@ -12,9 +12,12 @@
|
||||||
'path.h',
|
'path.h',
|
||||||
'ref.cc',
|
'ref.cc',
|
||||||
'ref.h',
|
'ref.h',
|
||||||
|
'run_loop.h',
|
||||||
'socket.h',
|
'socket.h',
|
||||||
'thread.cc',
|
'thread.cc',
|
||||||
'thread.h',
|
'thread.h',
|
||||||
|
'window.cc',
|
||||||
|
'window.h',
|
||||||
],
|
],
|
||||||
|
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
@ -42,7 +45,10 @@
|
||||||
'mutex_win.cc',
|
'mutex_win.cc',
|
||||||
'pal_win.cc',
|
'pal_win.cc',
|
||||||
'path_win.cc',
|
'path_win.cc',
|
||||||
|
'run_loop_win.cc',
|
||||||
'socket_win.cc',
|
'socket_win.cc',
|
||||||
|
'win32_window.cc',
|
||||||
|
'win32_window.h',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/core/win32_window.h>
|
||||||
|
|
||||||
|
#include <dwmapi.h>
|
||||||
|
#include <tpcshrd.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static LRESULT CALLBACK Win32WindowWndProc(
|
||||||
|
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
|
Win32Window* window = 0;
|
||||||
|
if (message == WM_NCCREATE) {
|
||||||
|
LPCREATESTRUCT create_struct = (LPCREATESTRUCT)lParam;
|
||||||
|
window = (Win32Window*)create_struct->lpCreateParams;
|
||||||
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, (__int3264)(LONG_PTR)window);
|
||||||
|
} else {
|
||||||
|
window = (Win32Window*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||||
|
}
|
||||||
|
if (window) {
|
||||||
|
return window->WndProc(hWnd, message, wParam, lParam);
|
||||||
|
} else {
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Win32Window::Win32Window(xe_run_loop_ref run_loop) :
|
||||||
|
handle_(0),
|
||||||
|
Window(run_loop) {
|
||||||
|
Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32Window::~Win32Window() {
|
||||||
|
if (handle_) {
|
||||||
|
CloseWindow(handle_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::Create() {
|
||||||
|
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||||
|
|
||||||
|
width_ = 1280;
|
||||||
|
height_ = 720;
|
||||||
|
|
||||||
|
WNDCLASSEX wcex;
|
||||||
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wcex.lpfnWndProc = Win32WindowWndProc;
|
||||||
|
wcex.cbClsExtra = 0;
|
||||||
|
wcex.cbWndExtra = 0;
|
||||||
|
wcex.hInstance = hInstance;
|
||||||
|
wcex.hIcon = NULL; // LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
|
||||||
|
wcex.hIconSm = NULL; // LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
|
||||||
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
|
||||||
|
wcex.lpszMenuName = NULL;
|
||||||
|
wcex.lpszClassName = L"XeniaWindowClass";
|
||||||
|
if (!RegisterClassEx(&wcex)) {
|
||||||
|
XELOGE("RegisterClassEx failed");
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup initial size.
|
||||||
|
DWORD window_style = WS_OVERLAPPEDWINDOW;
|
||||||
|
DWORD window_ex_style = WS_EX_APPWINDOW;
|
||||||
|
RECT rc = {
|
||||||
|
0, 0,
|
||||||
|
width_, height_
|
||||||
|
};
|
||||||
|
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
|
||||||
|
// Create window.
|
||||||
|
handle_ = CreateWindowEx(
|
||||||
|
window_ex_style,
|
||||||
|
L"XeniaWindowClass",
|
||||||
|
L"Xenia",
|
||||||
|
window_style,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
rc.right - rc.left, rc.bottom - rc.top,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
hInstance,
|
||||||
|
this);
|
||||||
|
if (!handle_) {
|
||||||
|
XELOGE("CreateWindow failed");
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable flicks.
|
||||||
|
ATOM atom = GlobalAddAtom(L"MicrosoftTabletPenServiceProperty");
|
||||||
|
const DWORD_PTR dwHwndTabletProperty =
|
||||||
|
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
|
||||||
|
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
|
||||||
|
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
|
||||||
|
TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward, drag down, drag up)
|
||||||
|
TABLET_DISABLE_TOUCHSWITCH |
|
||||||
|
TABLET_DISABLE_SMOOTHSCROLLING |
|
||||||
|
TABLET_DISABLE_TOUCHUIFORCEON |
|
||||||
|
TABLET_ENABLE_MULTITOUCHDATA;
|
||||||
|
SetProp(
|
||||||
|
handle_,
|
||||||
|
L"MicrosoftTabletPenServiceProperty",
|
||||||
|
reinterpret_cast<HANDLE>(dwHwndTabletProperty));
|
||||||
|
GlobalDeleteAtom(atom);
|
||||||
|
|
||||||
|
// Enable DWM elevation.
|
||||||
|
EnableMMCSS();
|
||||||
|
|
||||||
|
ShowWindow(handle_, SW_SHOWNORMAL);
|
||||||
|
UpdateWindow(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::EnableMMCSS() {
|
||||||
|
HMODULE hLibrary = LoadLibrary(L"DWMAPI.DLL");
|
||||||
|
if (!hLibrary) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef HRESULT (__stdcall *PDwmEnableMMCSS)(BOOL);
|
||||||
|
PDwmEnableMMCSS pDwmEnableMMCSS =
|
||||||
|
(PDwmEnableMMCSS)GetProcAddress(
|
||||||
|
hLibrary, "DwmEnableMMCSS");
|
||||||
|
if (pDwmEnableMMCSS) {
|
||||||
|
pDwmEnableMMCSS(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef HRESULT (__stdcall *PDwmSetPresentParameters)(HWND, DWM_PRESENT_PARAMETERS*);
|
||||||
|
PDwmSetPresentParameters pDwmSetPresentParameters =
|
||||||
|
(PDwmSetPresentParameters)GetProcAddress(
|
||||||
|
hLibrary, "DwmSetPresentParameters");
|
||||||
|
if (pDwmSetPresentParameters) {
|
||||||
|
DWM_PRESENT_PARAMETERS pp;
|
||||||
|
memset(&pp, 0, sizeof(DWM_PRESENT_PARAMETERS));
|
||||||
|
pp.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
|
||||||
|
pp.fQueue = FALSE;
|
||||||
|
pp.cBuffer = 2;
|
||||||
|
pp.fUseSourceRate = FALSE;
|
||||||
|
pp.cRefreshesPerFrame = 1;
|
||||||
|
pp.eSampling = DWM_SOURCE_FRAME_SAMPLING_POINT;
|
||||||
|
pDwmSetPresentParameters(handle_, &pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeLibrary( hLibrary );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::set_title(const xechar_t* title) {
|
||||||
|
XEIGNORE(SetWindowText(handle_, title));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::Resize(uint32_t width, uint32_t height) {
|
||||||
|
if (width == width_ && height == height_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
|
||||||
|
RECT rc = {
|
||||||
|
0, 0,
|
||||||
|
width_, height_
|
||||||
|
};
|
||||||
|
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
// TODO(benvanik): center.
|
||||||
|
MoveWindow(handle_, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE);
|
||||||
|
|
||||||
|
OnResize(width_, height_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::ShowError(const xechar_t* message) {
|
||||||
|
XEIGNORE(MessageBox(handle_, message, L"Xenia Error", MB_ICONERROR | MB_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT Win32Window::WndProc(HWND hWnd, UINT message,
|
||||||
|
WPARAM wParam, LPARAM lParam) {
|
||||||
|
switch (message) {
|
||||||
|
case WM_NCCREATE:
|
||||||
|
handle_ = hWnd;
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
case WM_ACTIVATEAPP:
|
||||||
|
if (wParam) {
|
||||||
|
// Made active.
|
||||||
|
} else {
|
||||||
|
// Made inactive.
|
||||||
|
}
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
case WM_CLOSE:
|
||||||
|
OnClose();
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc = BeginPaint(hWnd, &ps);
|
||||||
|
EndPaint(hWnd, &ps);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case WM_ERASEBKGND:
|
||||||
|
return 0; // ignore
|
||||||
|
case WM_DISPLAYCHANGE:
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_MOVE:
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
case WM_SIZE:
|
||||||
|
{
|
||||||
|
RECT frame;
|
||||||
|
GetClientRect(handle_, &frame);
|
||||||
|
OnResize(frame.right - frame.left, frame.bottom - frame.top);
|
||||||
|
}
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_TABLET_QUERYSYSTEMGESTURESTATUS:
|
||||||
|
return
|
||||||
|
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
|
||||||
|
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
|
||||||
|
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
|
||||||
|
TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward, drag down, drag up)
|
||||||
|
TABLET_DISABLE_TOUCHSWITCH |
|
||||||
|
TABLET_DISABLE_SMOOTHSCROLLING |
|
||||||
|
TABLET_DISABLE_TOUCHUIFORCEON |
|
||||||
|
TABLET_ENABLE_MULTITOUCHDATA;
|
||||||
|
default:
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_CORE_WIN32_WINDOW_H_
|
||||||
|
#define XENIA_CORE_WIN32_WINDOW_H_
|
||||||
|
|
||||||
|
#include <xenia/common.h>
|
||||||
|
#include <xenia/core/window.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
|
||||||
|
class Win32Window : public Window {
|
||||||
|
public:
|
||||||
|
Win32Window(xe_run_loop_ref run_loop);
|
||||||
|
virtual ~Win32Window();
|
||||||
|
|
||||||
|
HWND handle() const { return handle_; }
|
||||||
|
|
||||||
|
virtual void set_title(const xechar_t* title);
|
||||||
|
|
||||||
|
virtual void Resize(uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
virtual void ShowError(const xechar_t* message);
|
||||||
|
|
||||||
|
LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HWND handle_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Create();
|
||||||
|
void EnableMMCSS();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_CORE_WIN32_WINDOW_H_
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/core/window.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::core;
|
||||||
|
|
||||||
|
|
||||||
|
Window::Window(xe_run_loop_ref run_loop) {
|
||||||
|
run_loop_ = xe_run_loop_retain(run_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::~Window() {
|
||||||
|
xe_run_loop_release(run_loop_);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_CORE_WINDOW_H_
|
||||||
|
#define XENIA_CORE_WINDOW_H_
|
||||||
|
|
||||||
|
#include <xenia/common.h>
|
||||||
|
#include <xenia/core/pal.h>
|
||||||
|
#include <xenia/core/ref.h>
|
||||||
|
#include <xenia/core/run_loop.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
|
||||||
|
class Window {
|
||||||
|
public:
|
||||||
|
Window(xe_run_loop_ref run_loop);
|
||||||
|
virtual ~Window();
|
||||||
|
|
||||||
|
virtual void set_title(const xechar_t* title) = 0;
|
||||||
|
|
||||||
|
uint32_t width() const { return width_; }
|
||||||
|
uint32_t height() const { return height_; }
|
||||||
|
virtual void Resize(uint32_t width, uint32_t height) = 0;
|
||||||
|
|
||||||
|
virtual void ShowError(const xechar_t* message) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnResize(uint32_t width, uint32_t height) {}
|
||||||
|
virtual void OnClose() {}
|
||||||
|
|
||||||
|
xe_run_loop_ref run_loop_;
|
||||||
|
|
||||||
|
uint32_t width_;
|
||||||
|
uint32_t height_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_CORE_WINDOW_H_
|
|
@ -19,11 +19,15 @@ using namespace xe::gpu::d3d11;
|
||||||
using namespace xe::gpu::xenos;
|
using namespace xe::gpu::xenos;
|
||||||
|
|
||||||
|
|
||||||
D3D11GraphicsDriver::D3D11GraphicsDriver(xe_memory_ref memory) :
|
D3D11GraphicsDriver::D3D11GraphicsDriver(
|
||||||
|
xe_memory_ref memory, ID3D11Device* device) :
|
||||||
GraphicsDriver(memory) {
|
GraphicsDriver(memory) {
|
||||||
|
device_ = device;
|
||||||
|
device_->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11GraphicsDriver::~D3D11GraphicsDriver() {
|
D3D11GraphicsDriver::~D3D11GraphicsDriver() {
|
||||||
|
device_->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11GraphicsDriver::Initialize() {
|
void D3D11GraphicsDriver::Initialize() {
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include <xenia/gpu/d3d11/d3d11-private.h>
|
#include <xenia/gpu/d3d11/d3d11-private.h>
|
||||||
#include <xenia/gpu/xenos/xenos.h>
|
#include <xenia/gpu/xenos/xenos.h>
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -24,7 +26,7 @@ namespace d3d11 {
|
||||||
|
|
||||||
class D3D11GraphicsDriver : public GraphicsDriver {
|
class D3D11GraphicsDriver : public GraphicsDriver {
|
||||||
public:
|
public:
|
||||||
D3D11GraphicsDriver(xe_memory_ref memory);
|
D3D11GraphicsDriver(xe_memory_ref memory, ID3D11Device* device);
|
||||||
virtual ~D3D11GraphicsDriver();
|
virtual ~D3D11GraphicsDriver();
|
||||||
|
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
|
@ -40,7 +42,8 @@ public:
|
||||||
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||||
uint32_t index_count);
|
uint32_t index_count);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
ID3D11Device* device_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <xenia/gpu/gpu-private.h>
|
#include <xenia/gpu/gpu-private.h>
|
||||||
#include <xenia/gpu/d3d11/d3d11_graphics_driver.h>
|
#include <xenia/gpu/d3d11/d3d11_graphics_driver.h>
|
||||||
|
#include <xenia/gpu/d3d11/d3d11_window.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
@ -18,14 +19,120 @@ using namespace xe::gpu;
|
||||||
using namespace xe::gpu::d3d11;
|
using namespace xe::gpu::d3d11;
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D11GraphicsSystem::D3D11GraphicsSystem(const CreationParams* params) :
|
D3D11GraphicsSystem::D3D11GraphicsSystem(const CreationParams* params) :
|
||||||
|
window_(0), dxgi_factory_(0), device_(0),
|
||||||
GraphicsSystem(params) {
|
GraphicsSystem(params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11GraphicsSystem::~D3D11GraphicsSystem() {
|
D3D11GraphicsSystem::~D3D11GraphicsSystem() {
|
||||||
|
if (device_) device_->Release();
|
||||||
|
if (dxgi_factory_) dxgi_factory_->Release();
|
||||||
|
delete window_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11GraphicsSystem::Initialize() {
|
void D3D11GraphicsSystem::Initialize() {
|
||||||
|
GraphicsSystem::Initialize();
|
||||||
|
|
||||||
|
// Create DXGI factory so we can get a swap chain/etc.
|
||||||
|
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1),
|
||||||
|
(void**)&dxgi_factory_);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
XELOGE("CreateDXGIFactory1 failed with %.8X", hr);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the best adapter.
|
||||||
|
// TODO(benvanik): enable nvperfhud/etc.
|
||||||
|
IDXGIAdapter1* adapter = 0;
|
||||||
|
UINT n = 0;
|
||||||
|
while (dxgi_factory_->EnumAdapters1(n, &adapter) != DXGI_ERROR_NOT_FOUND) {
|
||||||
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
|
adapter->GetDesc1(&desc);
|
||||||
|
adapter->Release();
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
// Just go with the default for now.
|
||||||
|
adapter = 0;
|
||||||
|
|
||||||
|
D3D_DRIVER_TYPE driver_type =
|
||||||
|
adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE;
|
||||||
|
|
||||||
|
UINT flags = 0;
|
||||||
|
// TODO(benvanik): runtime flag
|
||||||
|
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||||
|
|
||||||
|
// Feature level 11.0+ only.
|
||||||
|
D3D_FEATURE_LEVEL feature_levels[] = {
|
||||||
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create device.
|
||||||
|
D3D_FEATURE_LEVEL actual_feature_level;
|
||||||
|
ID3D11DeviceContext* immediate_context;
|
||||||
|
hr = D3D11CreateDevice(
|
||||||
|
adapter,
|
||||||
|
driver_type,
|
||||||
|
0, // software driver HMODULE
|
||||||
|
flags,
|
||||||
|
feature_levels,
|
||||||
|
XECOUNT(feature_levels),
|
||||||
|
D3D11_SDK_VERSION,
|
||||||
|
&device_,
|
||||||
|
&actual_feature_level,
|
||||||
|
&immediate_context);
|
||||||
|
if (adapter) {
|
||||||
|
adapter->Release();
|
||||||
|
adapter = 0;
|
||||||
|
}
|
||||||
|
if (immediate_context) {
|
||||||
|
immediate_context->Release();
|
||||||
|
immediate_context = 0;
|
||||||
|
}
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
XELOGE("D3D11CreateDevice failed with %.8X", hr);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the window.
|
||||||
|
// This will pump through the run-loop and and be where our swapping
|
||||||
|
// will take place.
|
||||||
|
XEASSERTNULL(window_);
|
||||||
|
window_ = new D3D11Window(run_loop_, dxgi_factory_, device_);
|
||||||
|
window_->set_title(XETEXT("Xenia D3D11"));
|
||||||
|
|
||||||
|
// Listen for alt-enter/etc.
|
||||||
|
dxgi_factory_->MakeWindowAssociation(window_->handle(), 0);
|
||||||
|
|
||||||
|
// Create the driver.
|
||||||
|
// This runs in the worker thread and builds command lines to present
|
||||||
|
// in the window.
|
||||||
XEASSERTNULL(driver_);
|
XEASSERTNULL(driver_);
|
||||||
driver_ = new D3D11GraphicsDriver(memory_);
|
driver_ = new D3D11GraphicsDriver(memory_, device_);
|
||||||
|
|
||||||
|
// Initial vsync kick.
|
||||||
|
DispatchInterruptCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D11GraphicsSystem::Pump() {
|
||||||
|
if (swap_pending_) {
|
||||||
|
swap_pending_ = false;
|
||||||
|
|
||||||
|
// Swap window.
|
||||||
|
// If we are set to vsync this will block.
|
||||||
|
window_->Swap();
|
||||||
|
|
||||||
|
// Dispatch interrupt callback to let the game know it can keep drawing.
|
||||||
|
DispatchInterruptCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D11GraphicsSystem::Shutdown() {
|
||||||
|
GraphicsSystem::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,15 @@
|
||||||
#include <xenia/gpu/graphics_system.h>
|
#include <xenia/gpu/graphics_system.h>
|
||||||
#include <xenia/gpu/d3d11/d3d11-private.h>
|
#include <xenia/gpu/d3d11/d3d11-private.h>
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace d3d11 {
|
namespace d3d11 {
|
||||||
|
|
||||||
|
class D3D11Window;
|
||||||
|
|
||||||
|
|
||||||
GraphicsSystem* Create(const CreationParams* params);
|
GraphicsSystem* Create(const CreationParams* params);
|
||||||
|
|
||||||
|
@ -29,7 +33,15 @@ public:
|
||||||
D3D11GraphicsSystem(const CreationParams* params);
|
D3D11GraphicsSystem(const CreationParams* params);
|
||||||
virtual ~D3D11GraphicsSystem();
|
virtual ~D3D11GraphicsSystem();
|
||||||
|
|
||||||
|
protected:
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
|
virtual void Pump();
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDXGIFactory1* dxgi_factory_;
|
||||||
|
ID3D11Device* device_;
|
||||||
|
D3D11Window* window_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/gpu/d3d11/d3d11_shader.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::gpu;
|
||||||
|
using namespace xe::gpu::d3d11;
|
||||||
|
|
||||||
|
|
||||||
|
D3D11Shader::D3D11Shader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11Shader::~D3D11Shader() {
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_D3D11_D3D11_SHADER_H_
|
||||||
|
#define XENIA_GPU_D3D11_D3D11_SHADER_H_
|
||||||
|
|
||||||
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
#include <xenia/gpu/shader.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace d3d11 {
|
||||||
|
|
||||||
|
|
||||||
|
class D3D11Shader : public Shader {
|
||||||
|
public:
|
||||||
|
D3D11Shader();
|
||||||
|
virtual ~D3D11Shader();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace d3d11
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_D3D11_D3D11_SHADER_H_
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/gpu/d3d11/d3d11_shader_cache.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::gpu;
|
||||||
|
using namespace xe::gpu::d3d11;
|
||||||
|
|
||||||
|
|
||||||
|
D3D11ShaderCache::D3D11ShaderCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11ShaderCache::~D3D11ShaderCache() {
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_D3D11_D3D11_SHADER_CACHE_H_
|
||||||
|
#define XENIA_GPU_D3D11_D3D11_SHADER_CACHE_H_
|
||||||
|
|
||||||
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
#include <xenia/gpu/shader_cache.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace d3d11 {
|
||||||
|
|
||||||
|
|
||||||
|
class D3D11ShaderCache : public ShaderCache {
|
||||||
|
public:
|
||||||
|
D3D11ShaderCache();
|
||||||
|
virtual ~D3D11ShaderCache();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace d3d11
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_D3D11_D3D11_SHADER_CACHE_H_
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/gpu/d3d11/d3d11_window.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::core;
|
||||||
|
using namespace xe::gpu;
|
||||||
|
using namespace xe::gpu::d3d11;
|
||||||
|
|
||||||
|
|
||||||
|
D3D11Window::D3D11Window(
|
||||||
|
xe_run_loop_ref run_loop,
|
||||||
|
IDXGIFactory1* dxgi_factory, ID3D11Device* device) :
|
||||||
|
Win32Window(run_loop) {
|
||||||
|
dxgi_factory_ = dxgi_factory;
|
||||||
|
dxgi_factory_->AddRef();
|
||||||
|
device_ = device;
|
||||||
|
device_->AddRef();
|
||||||
|
device_->GetImmediateContext(&context_);
|
||||||
|
|
||||||
|
swap_chain_ = 0;
|
||||||
|
render_target_view_ = 0;
|
||||||
|
|
||||||
|
// Setup swap chain.
|
||||||
|
DXGI_SWAP_CHAIN_DESC desc;
|
||||||
|
xe_zero_struct(&desc, sizeof(desc));
|
||||||
|
desc.OutputWindow = handle_;
|
||||||
|
desc.Windowed = TRUE;
|
||||||
|
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||||
|
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||||
|
|
||||||
|
// Setup buffers.
|
||||||
|
desc.BufferCount = 2;
|
||||||
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
desc.BufferDesc.Width = width_;
|
||||||
|
desc.BufferDesc.Height = height_;
|
||||||
|
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.BufferDesc.RefreshRate.Numerator = 60;
|
||||||
|
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||||
|
|
||||||
|
// Disable multisampling.
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
|
||||||
|
// Create!
|
||||||
|
HRESULT hr = dxgi_factory_->CreateSwapChain(
|
||||||
|
device_,
|
||||||
|
&desc,
|
||||||
|
&swap_chain_);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
XELOGE("CreateSwapChain failed with %.8X", hr);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a render target view to draw into.
|
||||||
|
ID3D11Texture2D* back_buffer = 0;
|
||||||
|
hr = swap_chain_->GetBuffer(
|
||||||
|
0, __uuidof(ID3D11Texture2D), (void**)&back_buffer);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
XELOGE("GetBuffer (back_buffer) failed with %.8X", hr);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hr = device_->CreateRenderTargetView(
|
||||||
|
back_buffer, NULL, &render_target_view_);
|
||||||
|
back_buffer->Release();
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
XELOGE("CreateRenderTargetView (back_buffer) failed with %.8X", hr);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context_->OMSetRenderTargets(1, &render_target_view_, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11Window::~D3D11Window() {
|
||||||
|
if (render_target_view_) render_target_view_->Release();
|
||||||
|
if (context_) {
|
||||||
|
context_->ClearState();
|
||||||
|
context_->Release();
|
||||||
|
}
|
||||||
|
if (swap_chain_) swap_chain_->Release();
|
||||||
|
if (device_) device_->Release();
|
||||||
|
if (dxgi_factory_) dxgi_factory_->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D11Window::Swap() {
|
||||||
|
// Setup the viewport.
|
||||||
|
//D3D11_VIEWPORT viewport;
|
||||||
|
//viewport.MinDepth = 0.0f;
|
||||||
|
//viewport.MaxDepth = 1.0f;
|
||||||
|
//viewport.TopLeftX = 0;
|
||||||
|
//viewport.TopLeftY = 0;
|
||||||
|
//viewport.Width = (FLOAT)width_;
|
||||||
|
//viewport.Height = (FLOAT)height_;
|
||||||
|
//context_->RSSetViewports(1, &viewport);
|
||||||
|
|
||||||
|
// Swap buffers.
|
||||||
|
// TODO(benvanik): control vsync with flag.
|
||||||
|
bool vsync = true;
|
||||||
|
HRESULT hr = swap_chain_->Present(vsync ? 1 : 0, 0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
XELOGE("Present failed with %.8X", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D11Window::OnResize(uint32_t width, uint32_t height) {
|
||||||
|
Win32Window::OnResize(width, height);
|
||||||
|
|
||||||
|
// TODO(benvanik): resize swap buffers?
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D11Window::OnClose() {
|
||||||
|
// We are the master window - if they close us, quit!
|
||||||
|
xe_run_loop_quit(run_loop_);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_D3D11_D3D11_WINDOW_H_
|
||||||
|
#define XENIA_GPU_D3D11_D3D11_WINDOW_H_
|
||||||
|
|
||||||
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace d3d11 {
|
||||||
|
|
||||||
|
|
||||||
|
class D3D11Window : public xe::core::Win32Window {
|
||||||
|
public:
|
||||||
|
D3D11Window(
|
||||||
|
xe_run_loop_ref run_loop,
|
||||||
|
IDXGIFactory1* dxgi_factory, ID3D11Device* device);
|
||||||
|
virtual ~D3D11Window();
|
||||||
|
|
||||||
|
void Swap();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnResize(uint32_t width, uint32_t height);
|
||||||
|
virtual void OnClose();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDXGIFactory1* dxgi_factory_;
|
||||||
|
ID3D11Device* device_;
|
||||||
|
IDXGISwapChain* swap_chain_;
|
||||||
|
ID3D11DeviceContext* context_;
|
||||||
|
ID3D11RenderTargetView* render_target_view_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace d3d11
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_D3D11_D3D11_WINDOW_H_
|
|
@ -8,5 +8,11 @@
|
||||||
'd3d11_graphics_driver.h',
|
'd3d11_graphics_driver.h',
|
||||||
'd3d11_graphics_system.cc',
|
'd3d11_graphics_system.cc',
|
||||||
'd3d11_graphics_system.h',
|
'd3d11_graphics_system.h',
|
||||||
|
'd3d11_shader.cc',
|
||||||
|
'd3d11_shader.h',
|
||||||
|
'd3d11_shader_cache.cc',
|
||||||
|
'd3d11_shader_cache.h',
|
||||||
|
'd3d11_window.cc',
|
||||||
|
'd3d11_window.h',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,39 @@ using namespace xe::gpu::xenos;
|
||||||
|
|
||||||
|
|
||||||
GraphicsSystem::GraphicsSystem(const CreationParams* params) :
|
GraphicsSystem::GraphicsSystem(const CreationParams* params) :
|
||||||
interrupt_callback_(0), interrupt_callback_data_(0) {
|
interrupt_callback_(0), interrupt_callback_data_(0),
|
||||||
|
swap_pending_(false) {
|
||||||
memory_ = xe_memory_retain(params->memory);
|
memory_ = xe_memory_retain(params->memory);
|
||||||
|
|
||||||
worker_ = new RingBufferWorker(memory_);
|
worker_ = new RingBufferWorker(memory_);
|
||||||
|
|
||||||
// Set during Initialize();
|
// Set during Initialize();
|
||||||
driver_ = 0;
|
driver_ = 0;
|
||||||
|
|
||||||
|
// Create the run loop used for any windows/etc.
|
||||||
|
// This must be done on the thread we create the driver.
|
||||||
|
run_loop_ = xe_run_loop_create();
|
||||||
|
|
||||||
|
// Create worker thread.
|
||||||
|
// This will initialize the graphics system.
|
||||||
|
// Init needs to happen there so that any thread-local stuff
|
||||||
|
// is created on the right thread.
|
||||||
|
running_ = true;
|
||||||
|
thread_ = xe_thread_create(
|
||||||
|
"GraphicsSystem",
|
||||||
|
(xe_thread_callback)ThreadStartThunk, this);
|
||||||
|
xe_thread_start(thread_);
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsSystem::~GraphicsSystem() {
|
GraphicsSystem::~GraphicsSystem() {
|
||||||
|
// TODO(benvanik): thread join.
|
||||||
|
running_ = false;
|
||||||
|
xe_thread_release(thread_);
|
||||||
|
|
||||||
// TODO(benvanik): worker join/etc.
|
// TODO(benvanik): worker join/etc.
|
||||||
delete worker_;
|
delete worker_;
|
||||||
|
|
||||||
|
xe_run_loop_release(run_loop_);
|
||||||
xe_memory_release(memory_);
|
xe_memory_release(memory_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +69,44 @@ void GraphicsSystem::set_processor(shared_ptr<cpu::Processor> processor) {
|
||||||
processor_ = processor;
|
processor_ = processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsSystem::ThreadStart() {
|
||||||
|
xe_run_loop_ref run_loop = xe_run_loop_retain(run_loop_);
|
||||||
|
|
||||||
|
// Initialize driver and ringbuffer.
|
||||||
|
Initialize();
|
||||||
|
XEASSERTNOTNULL(driver_);
|
||||||
|
|
||||||
|
// Main run loop.
|
||||||
|
while (running_) {
|
||||||
|
// Peek main run loop.
|
||||||
|
if (xe_run_loop_pump(run_loop)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!running_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pump worker.
|
||||||
|
worker_->Pump();
|
||||||
|
|
||||||
|
// Pump graphics system.
|
||||||
|
Pump();
|
||||||
|
}
|
||||||
|
running_ = false;
|
||||||
|
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
xe_run_loop_release(run_loop);
|
||||||
|
|
||||||
|
// TODO(benvanik): call module API to kill?
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsSystem::Initialize() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsSystem::Shutdown() {
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicsSystem::SetInterruptCallback(uint32_t callback,
|
void GraphicsSystem::SetInterruptCallback(uint32_t callback,
|
||||||
uint32_t user_data) {
|
uint32_t user_data) {
|
||||||
interrupt_callback_ = callback;
|
interrupt_callback_ = callback;
|
||||||
|
|
|
@ -29,9 +29,11 @@ class RingBufferWorker;
|
||||||
|
|
||||||
class CreationParams {
|
class CreationParams {
|
||||||
public:
|
public:
|
||||||
xe_memory_ref memory;
|
xe_memory_ref memory;
|
||||||
|
|
||||||
CreationParams() : memory(NULL) {}
|
CreationParams() :
|
||||||
|
memory(0) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +45,6 @@ public:
|
||||||
shared_ptr<cpu::Processor> processor();
|
shared_ptr<cpu::Processor> processor();
|
||||||
void set_processor(shared_ptr<cpu::Processor> processor);
|
void set_processor(shared_ptr<cpu::Processor> processor);
|
||||||
|
|
||||||
virtual void Initialize() = 0;
|
|
||||||
void SetInterruptCallback(uint32_t callback, uint32_t user_data);
|
void SetInterruptCallback(uint32_t callback, uint32_t user_data);
|
||||||
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count);
|
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count);
|
||||||
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
||||||
|
@ -52,6 +53,8 @@ public:
|
||||||
virtual void WriteRegister(uint32_t r, uint64_t value);
|
virtual void WriteRegister(uint32_t r, uint64_t value);
|
||||||
|
|
||||||
void DispatchInterruptCallback();
|
void DispatchInterruptCallback();
|
||||||
|
bool swap_pending() const { return swap_pending_; }
|
||||||
|
void set_swap_pending(bool value) { swap_pending_ = value; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// TODO(benvanik): have an HasRegisterHandler() so that the JIT can
|
// TODO(benvanik): have an HasRegisterHandler() so that the JIT can
|
||||||
|
@ -64,17 +67,33 @@ public:
|
||||||
this_ptr->WriteRegister(r, value);
|
this_ptr->WriteRegister(r, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Initialize();
|
||||||
|
virtual void Pump() = 0;
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void ThreadStartThunk(GraphicsSystem* this_ptr) {
|
||||||
|
this_ptr->ThreadStart();
|
||||||
|
}
|
||||||
|
void ThreadStart();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GraphicsSystem(const CreationParams* params);
|
GraphicsSystem(const CreationParams* params);
|
||||||
|
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
shared_ptr<cpu::Processor> processor_;
|
shared_ptr<cpu::Processor> processor_;
|
||||||
|
|
||||||
|
xe_run_loop_ref run_loop_;
|
||||||
|
xe_thread_ref thread_;
|
||||||
|
bool running_;
|
||||||
|
|
||||||
GraphicsDriver* driver_;
|
GraphicsDriver* driver_;
|
||||||
RingBufferWorker* worker_;
|
RingBufferWorker* worker_;
|
||||||
|
|
||||||
uint32_t interrupt_callback_;
|
uint32_t interrupt_callback_;
|
||||||
uint32_t interrupt_callback_data_;
|
uint32_t interrupt_callback_data_;
|
||||||
|
bool swap_pending_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,15 +34,11 @@ NopGraphicsSystem::NopGraphicsSystem(const CreationParams* params) :
|
||||||
}
|
}
|
||||||
|
|
||||||
NopGraphicsSystem::~NopGraphicsSystem() {
|
NopGraphicsSystem::~NopGraphicsSystem() {
|
||||||
if (vsync_timer_) {
|
|
||||||
DeleteTimerQueueTimer(timer_queue_, vsync_timer_, NULL);
|
|
||||||
}
|
|
||||||
if (timer_queue_) {
|
|
||||||
DeleteTimerQueueEx(timer_queue_, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NopGraphicsSystem::Initialize() {
|
void NopGraphicsSystem::Initialize() {
|
||||||
|
GraphicsSystem::Initialize();
|
||||||
|
|
||||||
XEASSERTNULL(driver_);
|
XEASSERTNULL(driver_);
|
||||||
driver_ = new NopGraphicsDriver(memory_);
|
driver_ = new NopGraphicsDriver(memory_);
|
||||||
|
|
||||||
|
@ -59,3 +55,17 @@ void NopGraphicsSystem::Initialize() {
|
||||||
100,
|
100,
|
||||||
WT_EXECUTEINTIMERTHREAD);
|
WT_EXECUTEINTIMERTHREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NopGraphicsSystem::Pump() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NopGraphicsSystem::Shutdown() {
|
||||||
|
if (vsync_timer_) {
|
||||||
|
DeleteTimerQueueTimer(timer_queue_, vsync_timer_, NULL);
|
||||||
|
}
|
||||||
|
if (timer_queue_) {
|
||||||
|
DeleteTimerQueueEx(timer_queue_, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsSystem::Shutdown();
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,10 @@ public:
|
||||||
NopGraphicsSystem(const CreationParams* params);
|
NopGraphicsSystem(const CreationParams* params);
|
||||||
virtual ~NopGraphicsSystem();
|
virtual ~NopGraphicsSystem();
|
||||||
|
|
||||||
|
protected:
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
|
virtual void Pump();
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE timer_queue_;
|
HANDLE timer_queue_;
|
||||||
|
|
|
@ -21,20 +21,12 @@ using namespace xe::gpu::xenos;
|
||||||
|
|
||||||
RingBufferWorker::RingBufferWorker(xe_memory_ref memory) :
|
RingBufferWorker::RingBufferWorker(xe_memory_ref memory) :
|
||||||
memory_(memory), driver_(0) {
|
memory_(memory), driver_(0) {
|
||||||
running_ = true;
|
|
||||||
write_ptr_index_event_ = CreateEvent(
|
write_ptr_index_event_ = CreateEvent(
|
||||||
NULL, FALSE, FALSE, NULL);
|
NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
thread_ = xe_thread_create(
|
|
||||||
"RingBufferWorker",
|
|
||||||
(xe_thread_callback)ThreadStartThunk, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RingBufferWorker::~RingBufferWorker() {
|
RingBufferWorker::~RingBufferWorker() {
|
||||||
// TODO(benvanik): thread join.
|
|
||||||
running_ = false;
|
|
||||||
SetEvent(write_ptr_index_event_);
|
SetEvent(write_ptr_index_event_);
|
||||||
xe_thread_release(thread_);
|
|
||||||
CloseHandle(write_ptr_index_event_);
|
CloseHandle(write_ptr_index_event_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +36,6 @@ void RingBufferWorker::Initialize(GraphicsDriver* driver,
|
||||||
primary_buffer_ptr_ = ptr;
|
primary_buffer_ptr_ = ptr;
|
||||||
primary_buffer_size_ = page_count * 4 * 1024;
|
primary_buffer_size_ = page_count * 4 * 1024;
|
||||||
read_ptr_index_ = 0;
|
read_ptr_index_ = 0;
|
||||||
|
|
||||||
xe_thread_start(thread_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RingBufferWorker::EnableReadPointerWriteBack(uint32_t ptr,
|
void RingBufferWorker::EnableReadPointerWriteBack(uint32_t ptr,
|
||||||
|
@ -64,40 +54,40 @@ void RingBufferWorker::UpdateWritePointer(uint32_t value) {
|
||||||
SetEvent(write_ptr_index_event_);
|
SetEvent(write_ptr_index_event_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RingBufferWorker::ThreadStart() {
|
void RingBufferWorker::Pump() {
|
||||||
uint8_t* p = xe_memory_addr(memory_);
|
uint8_t* p = xe_memory_addr(memory_);
|
||||||
|
|
||||||
while (running_) {
|
if (write_ptr_index_ == 0xBAADF00D ||
|
||||||
if (write_ptr_index_ == 0xBAADF00D ||
|
read_ptr_index_ == write_ptr_index_) {
|
||||||
read_ptr_index_ == write_ptr_index_) {
|
// Check if the pointer has moved.
|
||||||
// Wait for the command buffer pointer to move.
|
// We wait a short bit here to yield time. Since we are also running the
|
||||||
// TODO(benvanik): only wait for a bit and check running_.
|
// main window display we don't want to pause too long, though.
|
||||||
WaitForSingleObject(write_ptr_index_event_, INFINITE);
|
const int wait_time_ms = 1;
|
||||||
if (!running_) {
|
if (WaitForSingleObject(write_ptr_index_event_,
|
||||||
break;
|
wait_time_ms) == WAIT_TIMEOUT) {
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
if (read_ptr_index_ == write_ptr_index_) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (read_ptr_index_ == write_ptr_index_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Process the new commands.
|
// Process the new commands.
|
||||||
XELOGGPU("Ring buffer thread work");
|
XELOGGPU("Ring buffer thread work");
|
||||||
|
|
||||||
// TODO(benvanik): handle wrapping around
|
// TODO(benvanik): handle wrapping around
|
||||||
// read_ptr_index_ = (read_ptr_index_ + 1) % (primary_buffer_size_ / 4);
|
// read_ptr_index_ = (read_ptr_index_ + 1) % (primary_buffer_size_ / 4);
|
||||||
XEASSERT(write_ptr_index_ >= read_ptr_index_);
|
XEASSERT(write_ptr_index_ >= read_ptr_index_);
|
||||||
uint32_t length = write_ptr_index_ - read_ptr_index_;
|
uint32_t length = write_ptr_index_ - read_ptr_index_;
|
||||||
if (length) {
|
if (length) {
|
||||||
ExecuteSegment(primary_buffer_ptr_ + read_ptr_index_ * 4, length);
|
ExecuteSegment(primary_buffer_ptr_ + read_ptr_index_ * 4, length);
|
||||||
read_ptr_index_ = write_ptr_index_;
|
read_ptr_index_ = write_ptr_index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(benvanik): use read_ptr_update_freq_ and only issue after moving
|
// TODO(benvanik): use read_ptr_update_freq_ and only issue after moving
|
||||||
// that many indices.
|
// that many indices.
|
||||||
if (read_ptr_writeback_ptr_) {
|
if (read_ptr_writeback_ptr_) {
|
||||||
XESETUINT32BE(p + read_ptr_writeback_ptr_, read_ptr_index_);
|
XESETUINT32BE(p + read_ptr_writeback_ptr_, read_ptr_index_);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,17 +33,13 @@ public:
|
||||||
|
|
||||||
void UpdateWritePointer(uint32_t value);
|
void UpdateWritePointer(uint32_t value);
|
||||||
|
|
||||||
|
void Pump();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void ThreadStartThunk(RingBufferWorker* this_ptr) {
|
|
||||||
this_ptr->ThreadStart();
|
|
||||||
}
|
|
||||||
void ThreadStart();
|
|
||||||
void ExecuteSegment(uint32_t ptr, uint32_t length);
|
void ExecuteSegment(uint32_t ptr, uint32_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
xe_thread_ref thread_;
|
|
||||||
bool running_;
|
|
||||||
|
|
||||||
GraphicsDriver* driver_;
|
GraphicsDriver* driver_;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/gpu/shader.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::gpu;
|
||||||
|
|
||||||
|
|
||||||
|
Shader::Shader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader() {
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_SHADER_H_
|
||||||
|
#define XENIA_GPU_SHADER_H_
|
||||||
|
|
||||||
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
|
||||||
|
|
||||||
|
class Shader {
|
||||||
|
public:
|
||||||
|
Shader();
|
||||||
|
virtual ~Shader();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_SHADER_H_
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/gpu/shader_cache.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::gpu;
|
||||||
|
|
||||||
|
|
||||||
|
ShaderCache::ShaderCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderCache::~ShaderCache() {
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_SHADER_CACHE_H_
|
||||||
|
#define XENIA_GPU_SHADER_CACHE_H_
|
||||||
|
|
||||||
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
|
||||||
|
|
||||||
|
class ShaderCache {
|
||||||
|
public:
|
||||||
|
ShaderCache();
|
||||||
|
virtual ~ShaderCache();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_SHADER_CACHE_H_
|
|
@ -11,6 +11,10 @@
|
||||||
'graphics_system.h',
|
'graphics_system.h',
|
||||||
'ring_buffer_worker.cc',
|
'ring_buffer_worker.cc',
|
||||||
'ring_buffer_worker.h',
|
'ring_buffer_worker.h',
|
||||||
|
'shader.cc',
|
||||||
|
'shader.h',
|
||||||
|
'shader_cache.cc',
|
||||||
|
'shader_cache.h',
|
||||||
],
|
],
|
||||||
|
|
||||||
'includes': [
|
'includes': [
|
||||||
|
|
|
@ -154,8 +154,6 @@ void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1,
|
||||||
// r4 = function ptr (cleanup callback?)
|
// r4 = function ptr (cleanup callback?)
|
||||||
// r5 = 0
|
// r5 = 0
|
||||||
// r6/r7 = some binary data in .data
|
// r6/r7 = some binary data in .data
|
||||||
|
|
||||||
gs->Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -366,6 +364,24 @@ SHIM_CALL VdRetrainEDRAM_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL VdSwap_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
XELOGD(
|
||||||
|
"VdSwap(?)");
|
||||||
|
|
||||||
|
KernelState* kernel_state = shared_kernel_state_;
|
||||||
|
XEASSERTNOTNULL(kernel_state);
|
||||||
|
GraphicsSystem* gs = kernel_state->processor()->graphics_system().get();
|
||||||
|
if (!gs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gs->set_swap_pending(true);
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
@ -387,6 +403,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdPersistDisplay, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", VdPersistDisplay, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdRetrainEDRAMWorker, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", VdRetrainEDRAMWorker, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", VdRetrainEDRAM, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", VdRetrainEDRAM, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", VdSwap, state);
|
||||||
|
|
||||||
xe_memory_ref memory = state->memory();
|
xe_memory_ref memory = state->memory();
|
||||||
uint8_t* mem = xe_memory_addr(memory);
|
uint8_t* mem = xe_memory_addr(memory);
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
|
xe_run_loop_ref run_loop_;
|
||||||
shared_ptr<Backend> backend_;
|
shared_ptr<Backend> backend_;
|
||||||
shared_ptr<GraphicsSystem> graphics_system_;
|
shared_ptr<GraphicsSystem> graphics_system_;
|
||||||
shared_ptr<Processor> processor_;
|
shared_ptr<Processor> processor_;
|
||||||
|
@ -40,10 +41,12 @@ private:
|
||||||
shared_ptr<Debugger> debugger_;
|
shared_ptr<Debugger> debugger_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Run::Run() {
|
Run::Run() :
|
||||||
|
memory_(0), run_loop_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Run::~Run() {
|
Run::~Run() {
|
||||||
|
xe_run_loop_release(run_loop_);
|
||||||
xe_memory_release(memory_);
|
xe_memory_release(memory_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +65,7 @@ int Run::Setup() {
|
||||||
backend_ = shared_ptr<Backend>(new xe::cpu::x64::X64Backend());
|
backend_ = shared_ptr<Backend>(new xe::cpu::x64::X64Backend());
|
||||||
|
|
||||||
params.memory = memory_;
|
params.memory = memory_;
|
||||||
graphics_system_ = shared_ptr<GraphicsSystem>(xe::gpu::CreateNop(¶ms));
|
graphics_system_ = shared_ptr<GraphicsSystem>(xe::gpu::Create(¶ms));
|
||||||
|
|
||||||
debugger_ = shared_ptr<Debugger>(new Debugger());
|
debugger_ = shared_ptr<Debugger>(new Debugger());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue