1#include "d3d11app.h"
2#include <X11/Xlib.h>
3#include <galliumdxgi.h>
4#include <sys/time.h>
5
6static d3d11_application* app;
7static IDXGISwapChain* swap_chain;
8unsigned width, height;
9DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
10static ID3D11Device* dev;
11static ID3D11DeviceContext* ctx;
12
13double get_time()
14{
15	struct timeval tv;
16	gettimeofday(&tv, 0);
17	return (double)tv.tv_sec + (double)tv.tv_usec * 0.000001;
18}
19
20int main(int argc, char** argv)
21{
22	Display* dpy = XOpenDisplay(0);
23	Visual* visual = DefaultVisual(dpy, DefaultScreen(dpy));
24	Colormap cmap = XCreateColormap(dpy, RootWindow(dpy, DefaultScreen(dpy)), visual, AllocNone);
25	XSetWindowAttributes swa;
26	swa.colormap = cmap;
27	swa.border_pixel = 0;
28	swa.event_mask = StructureNotifyMask;
29	width = 512;
30	height = 512;
31	Window win = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)), 0, 0, width, height, 0, CopyFromParent, InputOutput, visual, CWBorderPixel | CWColormap| CWEventMask, &swa);
32	XMapWindow(dpy, win);
33
34	GalliumDXGIUseX11Display(dpy, 0);
35
36	DXGI_SWAP_CHAIN_DESC swap_chain_desc;
37	memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
38	swap_chain_desc.BufferDesc.Width = width;
39	swap_chain_desc.BufferDesc.Height = height;
40	swap_chain_desc.BufferDesc.Format = format;
41	swap_chain_desc.SampleDesc.Count = 1;
42	swap_chain_desc.SampleDesc.Quality = 0;
43	swap_chain_desc.OutputWindow = (HWND)win;
44	swap_chain_desc.Windowed = TRUE;
45	swap_chain_desc.BufferCount = 3;
46	swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
47	swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
48
49	D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_10_0;
50
51	HRESULT hr =D3D11CreateDeviceAndSwapChain(
52		NULL,
53		D3D_DRIVER_TYPE_HARDWARE,
54		NULL,
55		D3D11_CREATE_DEVICE_SINGLETHREADED,
56		NULL,
57		0,
58		D3D11_SDK_VERSION,
59		&swap_chain_desc,
60		&swap_chain,
61		&dev,
62		&feature_level,
63		&ctx);
64	if(!SUCCEEDED(hr))
65	{
66		fprintf(stderr, "Failed to create D3D11 device (hresult %08x)\n", hr);
67		return 1;
68	}
69
70	app = d3d11_application_create();
71	if(!app->init(dev, argc, argv))
72		return 1;
73
74	double start_time = get_time();
75
76	MSG msg;
77	for(;;)
78	{
79		XEvent event;
80		if(XPending(dpy))
81		{
82			XNextEvent(dpy, &event);
83			if(event.type == DestroyNotify)
84				break;
85			switch(event.type)
86			{
87			case ConfigureNotify:
88				width = event.xconfigure.width;
89				height = event.xconfigure.height;
90				swap_chain->ResizeBuffers(3, width, height, format, 0);
91				break;
92			}
93		}
94		else if(width && height)
95		{
96			ID3D11Texture2D* tex;
97			ID3D11RenderTargetView* rtv;
98			ensure(swap_chain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&tex));
99			ensure(dev->CreateRenderTargetView(tex, NULL, &rtv));
100
101			double ctime = get_time() - start_time;
102
103			app->draw(ctx, rtv, width, height, ctime);
104			ctx->OMSetRenderTargets(0, 0, 0);
105
106			tex->Release();
107			rtv->Release();
108			swap_chain->Present(0, 0);
109		}
110		else
111			XPeekEvent(dpy, &event);
112	}
113	return (int) msg.wParam;
114}
115