DXGL r595 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r594‎ | r595 | r596 >
Date:14:54, 22 February 2015
Author:admin
Status:new
Tags:
Comment:
Implement the asynchronous queue from r149. Currently D3D doesn't work.
Modified paths:
  • /ddraw/common.h (modified) (history)
  • /ddraw/ddraw.vcxproj (modified) (history)
  • /ddraw/ddraw.vcxproj.filters (modified) (history)
  • /ddraw/glDirectDraw.cpp (modified) (history)
  • /ddraw/glDirectDrawSurface.cpp (modified) (history)
  • /ddraw/glRenderWindow.cpp (modified) (history)
  • /ddraw/glRenderer.cpp (modified) (history)
  • /ddraw/glRenderer.h (modified) (history)
  • /ddraw/opqueue.c (deleted) (history)
  • /ddraw/opqueue.h (deleted) (history)
  • /ddraw/spinlock.h (deleted) (history)
  • /ddraw/spinlock.x86.asm (deleted) (history)

Diff [purge]

Index: ddraw/spinlock.h
@@ -1,32 +0,0 @@
2 -// DXGL
3 -// Copyright (C) 2015 William Feely
4 -
5 -// This library is free software; you can redistribute it and/or
6 -// modify it under the terms of the GNU Lesser General Public
7 -// License as published by the Free Software Foundation; either
8 -// version 2.1 of the License, or (at your option) any later version.
9 -
10 -// This library is distributed in the hope that it will be useful,
11 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 -// Lesser General Public License for more details.
14 -
15 -// You should have received a copy of the GNU Lesser General Public
16 -// License along with this library; if not, write to the Free Software
17 -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 -
19 -#pragma once
20 -#ifndef _SPINLOCK_H
21 -#define _SPINLOCK_H
22 -
23 -#ifdef __cplusplus
24 -extern "C" {
25 -#endif
26 -
27 -void _enterspinlock(DWORD *spinlock);
28 -void _exitspinlock(DWORD *spinlock);
29 -
30 -#ifdef __cplusplus
31 -}
32 -#endif
33 -#endif //_SPINLOCK_H
\ No newline at end of file
Index: ddraw/opqueue.c
@@ -1,157 +0,0 @@
2 -// DXGL
3 -// Copyright (C) 2015 William Feely
4 -
5 -// This library is free software; you can redistribute it and/or
6 -// modify it under the terms of the GNU Lesser General Public
7 -// License as published by the Free Software Foundation; either
8 -// version 2.1 of the License, or (at your option) any later version.
9 -
10 -// This library is distributed in the hope that it will be useful,
11 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 -// Lesser General Public License for more details.
14 -
15 -// You should have received a copy of the GNU Lesser General Public
16 -// License along with this library; if not, write to the Free Software
17 -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 -
19 -#include "common.h"
20 -#include "opqueue.h"
21 -#include "spinlock.h"
22 -
23 -BOOL opqueue_init(OPQUEUE *queue)
24 -{
25 - if (!queue) return FALSE;
26 - if (queue->data_size) return TRUE;
27 - else queue->data_size = 1048576;
28 - queue->writeptr = queue->readptr = 0;
29 - queue->waitfull = FALSE;
30 - queue->data = malloc(queue->data_size);
31 - if (!queue->data)
32 - {
33 - queue->data_size = 0;
34 - return FALSE;
35 - }
36 - queue->writelock = queue->readlock = 0;
37 - queue->waitevent = CreateEvent(NULL, FALSE, FALSE, NULL);
38 - if (!queue->waitevent)
39 - {
40 - free(queue->data);
41 - queue->data_size = 0;
42 - return FALSE;
43 - }
44 - return TRUE;
45 -}
46 -
47 -void opqueue_delete(OPQUEUE *queue)
48 -{
49 - if (!queue->data_size) return;
50 - CloseHandle(queue->waitevent);
51 - free(queue->data);
52 - ZeroMemory(queue, sizeof(OPQUEUE));
53 -}
54 -
55 -BOOL opqueue_alloc(OPQUEUE *queue, DWORD size)
56 -{
57 - BYTE *ptr;
58 - DWORD newsize;
59 - if ((size * 3) > queue->data_size)
60 - {
61 - _enterspinlock(&queue->readlock);
62 - _enterspinlock(&queue->writelock);
63 - newsize = NextMultipleOf64K(size * 3);
64 - ptr = realloc(queue->data, newsize);
65 - if (ptr)
66 - {
67 - queue->data = ptr;
68 - queue->data_size = newsize;
69 - _exitspinlock(&queue->writelock);
70 - _exitspinlock(&queue->readlock);
71 - return TRUE;
72 - }
73 - else
74 - {
75 - _exitspinlock(&queue->writelock);
76 - _exitspinlock(&queue->readlock);
77 - return FALSE;
78 - }
79 - }
80 - return TRUE;
81 -}
82 -
83 -BYTE *opqueue_putlock(OPQUEUE *queue, DWORD size)
84 -{
85 - BYTE *ptr;
86 - BOOL wraparound = FALSE;
87 - BOOL waitfull = FALSE;
88 - if (!queue->data_size) return NULL;
89 - if (size > queue->data_size) return NULL; // Large items should use opqueue_alloc before attempting to do opqueue_put
90 - _enterspinlock(&queue->writelock);
91 - if (queue->writeptr + size > queue->data_size)
92 - {
93 - wraparound = TRUE;
94 - while(queue->readptr)
95 - {
96 - waitfull = TRUE;
97 - _exitspinlock(&queue->writelock);
98 - _enterspinlock(&queue->readlock);
99 - queue->waitfull = TRUE;
100 - _exitspinlock(&queue->readlock);
101 - _enterspinlock(&queue->writelock);
102 - Sleep(0);
103 - }
104 - if (waitfull) ResetEvent(queue->waitevent);
105 - queue->waitfull = FALSE;
106 - }
107 - if (wraparound)
108 - {
109 - queue->writeptr = 0;
110 - }
111 - ptr = queue->data + queue->writeptr;
112 - return ptr;
113 -}
114 -
115 -void opqueue_putunlock(OPQUEUE *queue, DWORD size)
116 -{
117 - queue->writeptr += size;
118 - if (queue->waitempty) SetEvent(queue->waitevent);
119 - _exitspinlock(&queue->writelock);
120 -}
121 -
122 -
123 -BYTE *opqueue_getlock(OPQUEUE *queue)
124 -{
125 - BOOL exit = TRUE;
126 - _enterspinlock(&queue->readlock);
127 - _enterspinlock(&queue->writelock);
128 - if (queue->readptr == queue->writeptr)
129 - {
130 - queue->waitempty = TRUE;
131 - ResetEvent(queue->waitevent);
132 - _exitspinlock(&queue->readlock);
133 - _exitspinlock(&queue->writelock);
134 - WaitForSingleObject(queue->waitevent, INFINITE);
135 - _enterspinlock(&queue->readlock);
136 - exit = FALSE;
137 - }
138 - if(exit) _exitspinlock(&queue->writelock);
139 - return queue->data + queue->readptr;
140 -}
141 -void opqueue_getunlock(OPQUEUE *queue, DWORD size)
142 -{
143 - BOOL rewound = FALSE;
144 - queue->readptr += size;
145 - _enterspinlock(&queue->writelock);
146 - if (queue->readptr >= queue->writeptr)
147 - {
148 - queue->readptr = 0;
149 - queue->writeptr = 0;
150 - rewound = TRUE;
151 - }
152 - _exitspinlock(&queue->writelock);
153 - if (queue->waitfull)
154 - {
155 - if (rewound) SetEvent(queue->waitevent);
156 - }
157 - _exitspinlock(&queue->readlock);
158 -}
Index: ddraw/opqueue.h
@@ -1,53 +0,0 @@
2 -// DXGL
3 -// Copyright (C) 2015 William Feely
4 -
5 -// This library is free software; you can redistribute it and/or
6 -// modify it under the terms of the GNU Lesser General Public
7 -// License as published by the Free Software Foundation; either
8 -// version 2.1 of the License, or (at your option) any later version.
9 -
10 -// This library is distributed in the hope that it will be useful,
11 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 -// Lesser General Public License for more details.
14 -
15 -// You should have received a copy of the GNU Lesser General Public
16 -// License along with this library; if not, write to the Free Software
17 -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 -
19 -#pragma once
20 -#ifndef _OPQUEUE_H
21 -#define _OPQUEUE_H
22 -
23 -#ifdef __cplusplus
24 -extern "C" {
25 -#endif
26 -
27 -struct OPQUEUE;
28 -
29 -typedef struct OPQUEUE
30 -{
31 - ULONG_PTR data_size;
32 - ULONG_PTR writeptr;
33 - ULONG_PTR readptr;
34 - BYTE *data;
35 - HANDLE waitevent;
36 - BOOL waitfull;
37 - BOOL waitempty;
38 - DWORD writelock;
39 - DWORD readlock;
40 -} OPQUEUE;
41 -
42 -BOOL opqueue_init(OPQUEUE *queue);
43 -void opqueue_delete(OPQUEUE *queue);
44 -BOOL opqueue_alloc(OPQUEUE *queue, DWORD size);
45 -BYTE *opqueue_putlock(OPQUEUE *queue, DWORD size);
46 -void opqueue_putunlock(OPQUEUE *queue, DWORD size);
47 -BYTE *opqueue_getlock(OPQUEUE *queue);
48 -void opqueue_getunlock(OPQUEUE *queue, DWORD size);
49 -
50 -#ifdef __cplusplus
51 -}
52 -#endif
53 -
54 -#endif //_OPQUEUE_H
\ No newline at end of file
Index: ddraw/spinlock.x86.asm
@@ -1,58 +0,0 @@
2 -; DXGL
3 -; Copyright (C) 2015 William Feely
4 -
5 -; This library is free software; you can redistribute it and/or
6 -; modify it under the terms of the GNU Lesser General Public
7 -; License as published by the Free Software Foundation; either
8 -; version 2.1 of the License, or (at your option) any later version.
9 -
10 -; This library is distributed in the hope that it will be useful,
11 -; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 -; Lesser General Public License for more details.
14 -
15 -; You should have received a copy of the GNU Lesser General Public
16 -; License along with this library; if not, write to the Free Software
17 -; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 -
19 -.model flat, c
20 -.code
21 -extern C smp:dword
22 -Sleep PROTO STDCALL arg1:DWORD
23 -
24 -_enterspinlock proc uses eax ecx esi, spinlock:ptr dword
25 - mov eax, smp
26 - mov esi, spinlock
27 - test eax, eax
28 - jz nosmp
29 -smpproc:
30 - mov ecx, 1000
31 - jmp spin_main
32 -nosmp:
33 - xor ecx, ecx
34 -spin_main:
35 - mov eax, 1
36 - xchg eax, [esi]
37 - test eax, eax
38 - jnz spintest
39 - ret
40 -spintest:
41 - test ecx, ecx
42 - jz sleeploop
43 - dec ecx
44 - jmp spin_main
45 -sleeploop:
46 - push ecx
47 - invoke Sleep, 0
48 - pop ecx
49 - jmp spin_main
50 -_enterspinlock endp
51 -
52 -_exitspinlock proc uses eax, spinlock:ptr dword
53 - mov esi, spinlock
54 - xor eax, eax
55 - xchg eax, [esi]
56 - ret
57 -_exitspinlock endp
58 -
59 -end
\ No newline at end of file
Index: ddraw/common.h
@@ -31,7 +31,6 @@
3232 #include "include/GL/glext.h"
3333 #include "include/GL/wglext.h"
3434 #include "glExtensions.h"
35 -#include "opqueue.h"
3635 #ifdef __cplusplus
3736 #include "string.h"
3837 #include "ShaderGen2D.h"
Index: ddraw/ddraw.vcxproj
@@ -295,13 +295,11 @@
296296 <ClInclude Include="include\GL\wglext.h" />
297297 <ClInclude Include="include\winedef.h" />
298298 <ClInclude Include="matrix.h" />
299 - <ClInclude Include="opqueue.h" />
300299 <ClInclude Include="resource.h" />
301300 <ClInclude Include="scalers.h" />
302301 <ClInclude Include="ShaderGen3D.h" />
303302 <ClInclude Include="ShaderGen2D.h" />
304303 <ClInclude Include="ShaderManager.h" />
305 - <ClInclude Include="spinlock.h" />
306304 <ClInclude Include="string.h" />
307305 <ClInclude Include="TextureManager.h" />
308306 <ClInclude Include="timer.h" />
@@ -382,14 +380,6 @@
383381 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug no DXGL|Win32'">NotUsing</PrecompiledHeader>
384382 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug No MSVCRT|Win32'">NotUsing</PrecompiledHeader>
385383 </ClCompile>
386 - <ClCompile Include="opqueue.c">
387 - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Trace|Win32'">NotUsing</PrecompiledHeader>
388 - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release no DXGL|Win32'">NotUsing</PrecompiledHeader>
389 - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
390 - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
391 - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug no DXGL|Win32'">NotUsing</PrecompiledHeader>
392 - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug No MSVCRT|Win32'">NotUsing</PrecompiledHeader>
393 - </ClCompile>
394384 <ClCompile Include="precomp.cpp">
395385 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug no DXGL|Win32'">Create</PrecompiledHeader>
396386 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
@@ -453,9 +443,6 @@
454444 <ItemGroup>
455445 <ResourceCompile Include="ddraw.rc" />
456446 </ItemGroup>
457 - <ItemGroup>
458 - <MASM Include="spinlock.x86.asm" />
459 - </ItemGroup>
460447 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
461448 <ImportGroup Label="ExtensionTargets">
462449 <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
Index: ddraw/ddraw.vcxproj.filters
@@ -146,12 +146,6 @@
147147 <ClInclude Include="hooks.h">
148148 <Filter>Header Files</Filter>
149149 </ClInclude>
150 - <ClInclude Include="spinlock.h">
151 - <Filter>Header Files</Filter>
152 - </ClInclude>
153 - <ClInclude Include="opqueue.h">
154 - <Filter>Header Files</Filter>
155 - </ClInclude>
156150 </ItemGroup>
157151 <ItemGroup>
158152 <ClCompile Include="ddraw.cpp">
@@ -253,9 +247,6 @@
254248 <ClCompile Include="dllmain.c">
255249 <Filter>Source Files</Filter>
256250 </ClCompile>
257 - <ClCompile Include="opqueue.c">
258 - <Filter>Source Files</Filter>
259 - </ClCompile>
260251 </ItemGroup>
261252 <ItemGroup>
262253 <ResourceCompile Include="ddraw.rc">
@@ -262,9 +253,4 @@
263254 <Filter>Resource Files</Filter>
264255 </ResourceCompile>
265256 </ItemGroup>
266 - <ItemGroup>
267 - <MASM Include="spinlock.x86.asm">
268 - <Filter>Source Files</Filter>
269 - </MASM>
270 - </ItemGroup>
271257 </Project>
\ No newline at end of file
Index: ddraw/glDirectDraw.cpp
@@ -1164,7 +1164,7 @@
11651165 mode.dmSize = sizeof(DEVMODE);
11661166 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode);
11671167 glRenderer_Init(tmprenderer, 16, 16, mode.dmBitsPerPel, false, mode.dmDisplayFrequency, hGLWnd, NULL, FALSE);
1168 - glRenderer_Sync(tmprenderer);
 1168+ glRenderer_Sync(tmprenderer,0);
11691169 if (tmprenderer->ext->glver_major >= 3) fullrop = TRUE;
11701170 if (tmprenderer->ext->GLEXT_EXT_gpu_shader4) fullrop = TRUE;
11711171 glRenderer_Delete(tmprenderer);
@@ -1172,7 +1172,7 @@
11731173 }
11741174 else
11751175 {
1176 - glRenderer_Sync(renderer);
 1176+ glRenderer_Sync(renderer,0);
11771177 if (renderer->ext->glver_major >= 3) fullrop = TRUE;
11781178 if (renderer->ext->GLEXT_EXT_gpu_shader4) fullrop = TRUE;
11791179 }
Index: ddraw/glDirectDrawSurface.cpp
@@ -867,7 +867,7 @@
868868 this->Blt(lpDestRect, ddInterface->tmpsurface, &tmprect, dwFlags, lpDDBltFx);
869869 }
870870 else glRenderer_Blt(ddInterface->renderer,lpDestRect,src,this,lpSrcRect,dwFlags,lpDDBltFx);
871 - if (this == ddInterface->primary) glRenderer_Sync(ddInterface->renderer);
 871+ if (this == ddInterface->primary) glRenderer_Sync(ddInterface->renderer,0);
872872 TRACE_EXIT(23, DD_OK);
873873 return DD_OK;
874874 }
@@ -990,7 +990,7 @@
991991 else if(dwFlags & DDFLIP_INTERVAL4) swapinterval=4;
992992 else swapinterval=1;
993993 }
994 - glRenderer_Sync(ddInterface->renderer);
 994+ glRenderer_Sync(ddInterface->renderer,0);
995995 int flips = 1;
996996 if(lpDDSurfaceTargetOverride)
997997 {
Index: ddraw/glRenderWindow.cpp
@@ -129,7 +129,7 @@
130130 #ifdef _DEBUG
131131 if(hotkeyregistered) UnregisterHotKey(hWnd,1);
132132 #endif
133 - SendMessage(hWnd,WM_CLOSE,0,0);
 133+ PostMessage(hWnd,WM_CLOSE,0,0);
134134 WaitForSingleObject(hThread,INFINITE);
135135 CloseHandle(hThread);
136136 }
Index: ddraw/glRenderer.cpp
@@ -23,7 +23,6 @@
2424 #include "glDirectDrawSurface.h"
2525 #include "glDirectDrawPalette.h"
2626 #include "glRenderWindow.h"
27 -#include "spinlock.h"
2827 #include "glRenderer.h"
2928 #include "glDirect3DDevice.h"
3029 #include "glDirect3DLight.h"
@@ -36,6 +35,7 @@
3736 extern "C" {
3837
3938 const GLushort bltindices[4] = {0,1,2,3};
 39+const RECT nullrect = { -1, -1, -1, -1 };
4040
4141 /**
4242 * Expands a 5-bit value to 8 bits.
@@ -79,6 +79,126 @@
8080 }
8181
8282 /**
 83+* Adds a command to the renderer queue.\n
 84+* If the command requires more space than the queue buffer, the buffer will be
 85+* expanded. If there is no free space for the command, execution will pause
 86+* until the queue has been sufficiently emptied.
 87+* @param This
 88+* Pointer to glRenderer object
 89+* @param opcode
 90+* Code that describes the command to be added to the queue.
 91+* @param mode
 92+* Method to use for synchronization:
 93+* - 0: Do not fail the call
 94+* - 1: Fail if queue is full
 95+* - 2: Fail if queue is not empty
 96+* @param size
 97+* Size of the command in DWORDs
 98+* @param paramcount
 99+* Number of parameters to add to the queue command.
 100+* @param ...
 101+* Parameters for the command, when required. This is given in pairs of two
 102+* arguments:
 103+* - size: The size of the parameter, in bytes. Note that parameters are DWORD
 104+* aligned. The size cannot exceed the size of the command, minus data already
 105+* written to the queue.
 106+* - pointer: A pointer to the data to be added to the command.\n
 107+* If no parameters are used for the opcode, then supply 0 and NULL for the ...
 108+* parameter.
 109+* @return
 110+* Zero if the call succeeds, nonzero otherwise.
 111+*/
 112+int glRenderer_AddQueue(glRenderer *This, DWORD opcode, int mode, DWORD size, int paramcount, ...)
 113+{
 114+ EnterCriticalSection(&This->queuecs);
 115+ if ((mode == 2) && This->queuelength)
 116+ {
 117+ LeaveCriticalSection(&This->queuecs);
 118+ return 1;
 119+ }
 120+ va_list params;
 121+ // Check queue size
 122+ va_start(params, paramcount);
 123+ int argsize;
 124+ void *argptr;
 125+ if (size > This->queuesize)
 126+ {
 127+ This->queue = (LPDWORD)realloc(This->queue, (This->queuesize + size)*sizeof(DWORD));
 128+ This->queuesize += size;
 129+ }
 130+ if (This->queuesize - This->queue_write < size)
 131+ {
 132+ if (This->queue_read < size)
 133+ {
 134+ if (mode == 1)
 135+ {
 136+ LeaveCriticalSection(&This->queuecs);
 137+ return 1;
 138+ }
 139+ if (This->queue_write < This->queuesize)
 140+ {
 141+ This->queue[This->queue_write] = OP_RESETQUEUE;
 142+ This->queuelength++;
 143+ }
 144+ LeaveCriticalSection(&This->queuecs);
 145+ glRenderer_Sync(This, size);
 146+ EnterCriticalSection(&This->queuecs);
 147+ }
 148+ }
 149+ if (This->queue_write < This->queue_read)
 150+ {
 151+ if (This->queue_read - This->queue_write < size)
 152+ {
 153+ LeaveCriticalSection(&This->queuecs);
 154+ glRenderer_Sync(This, size);
 155+ EnterCriticalSection(&This->queuecs);
 156+ }
 157+ }
 158+ This->queue[This->queue_write++] = opcode;
 159+ This->queue[This->queue_write++] = size;
 160+ size -= 2;
 161+ for (int i = 0; i < paramcount; i++)
 162+ {
 163+ argsize = va_arg(params, int);
 164+ argptr = va_arg(params, void*);
 165+ if (!argsize) continue;
 166+ if ((NextMultipleOf4(argsize) / 4) > size) break;
 167+ This->queue[This->queue_write++] = argsize;
 168+ if (argptr) memcpy(This->queue + This->queue_write, argptr, argsize);
 169+ This->queue_write += (NextMultipleOf4(argsize) / 4);
 170+ size -= (NextMultipleOf4(argsize) / 4);
 171+ }
 172+ va_end(params);
 173+ This->queuelength++;
 174+ if (!This->running) SetEvent(This->start);
 175+ LeaveCriticalSection(&This->queuecs);
 176+ return 0;
 177+}
 178+
 179+/**
 180+* Waits until the specified amount of queue space is free
 181+* @param This
 182+* Pointer to glRenderer object
 183+* @param size
 184+* If nonzero, the number of DWORDs that must be available within the queue.
 185+* If zero, waits until the queue is empty.
 186+*/
 187+void glRenderer_Sync(glRenderer *This, int size)
 188+{
 189+ EnterCriticalSection(&This->queuecs);
 190+ if (!This->queuelength && !This->running)
 191+ {
 192+ LeaveCriticalSection(&This->queuecs);
 193+ return;
 194+ }
 195+ ResetEvent(This->sync);
 196+ This->syncsize = size;
 197+ if (!This->running) SetEvent(This->start);
 198+ LeaveCriticalSection(&This->queuecs);
 199+ WaitForSingleObject(This->sync, INFINITE);
 200+}
 201+
 202+/**
83203 * Internal function for uploading surface content to an OpenGL texture
84204 * @param This
85205 * Pointer to glRenderer object
@@ -127,9 +247,6 @@
128248 {
129249 BYTE *outbuffer;
130250 DWORD outx, outy, outpitch, outbpp;
131 - UPLOADOP *uploadop;
132 - DWORD *opbuffer;
133 - DWORD uploadopsize;
134251 if (bpp == 15) outbpp = 16;
135252 else outbpp = bpp;
136253 if ((x == bigx && y == bigy) || !bigbuffer)
@@ -166,7 +283,8 @@
167284 }
168285
169286 /**
170 - * Internal function for downloading surface content from an OpenGL texture
 287+ * Internal function for downloading surface content from an OpenGL texture.
 288+ * Forwards the request to the Texture Manager.
171289 * @param This
172290 * Pointer to glRenderer object
173291 * @param buffer
@@ -200,7 +318,6 @@
201319 void glRenderer_Init(glRenderer *This, DWORD width, DWORD height, DWORD bpp, BOOL fullscreen, DWORD frequency, HWND hwnd, glDirectDraw7 *glDD7, BOOL devwnd)
202320 {
203321 LONG_PTR winstyle, winstyleex;
204 - INITOP *initop;
205322 This->oldswap = 0;
206323 This->fogcolor = 0;
207324 This->fogstart = 0.0f;
@@ -211,8 +328,11 @@
212329 This->hRC = NULL;
213330 This->PBO = 0;
214331 This->dib.enabled = false;
 332+ This->running = FALSE;
215333 This->hWnd = hwnd;
216 - This->syncevent = CreateEvent(NULL, FALSE, FALSE, NULL);
 334+ This->busy = CreateEvent(NULL, FALSE, FALSE, NULL);
 335+ InitializeCriticalSection(&This->commandcs);
 336+ InitializeCriticalSection(&This->queuecs);
217337 if (fullscreen)
218338 {
219339 winstyle = GetWindowLongPtrA(This->hWnd, GWL_STYLE);
@@ -225,23 +345,19 @@
226346 {
227347 // TODO: Adjust window rect
228348 }
 349+ EnterCriticalSection(&This->commandcs);
229350 SetWindowPos(This->hWnd,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
230351 This->RenderWnd = new glRenderWindow(width,height,fullscreen,This->hWnd,glDD7,devwnd);
231 - This->queue.data_size = 0;
232 - opqueue_init(&This->queue);
233 - initop = (INITOP*)opqueue_putlock(&This->queue,sizeof(INITOP));
234 - initop->opcode.opcode = OP_INIT;
235 - initop->opcode.size = sizeof(INITOP);
236 - initop->width = width;
237 - initop->height = height;
238 - initop->bpp = bpp;
239 - initop->fullscreen = fullscreen;
240 - initop->frequency = frequency;
241 - initop->devwnd = devwnd;
242 - initop->hwnd = This->hWnd;
243 - initop->glDD7 = glDD7;
244 - opqueue_putunlock(&This->queue, sizeof(INITOP));
 352+ This->inputs[0] = (void*)width;
 353+ This->inputs[1] = (void*)height;
 354+ This->inputs[2] = (void*)bpp;
 355+ This->inputs[3] = (void*)fullscreen;
 356+ This->inputs[4] = (void*)frequency;
 357+ This->inputs[5] = (void*)This->hWnd;
 358+ This->inputs[6] = glDD7;
245359 This->hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)glRenderer__Entry, This, 0, NULL);
 360+ WaitForSingleObject(This->busy, INFINITE);
 361+ LeaveCriticalSection(&This->commandcs);
246362 }
247363
248364 /**
@@ -251,40 +367,19 @@
252368 */
253369 void glRenderer_Delete(glRenderer *This)
254370 {
255 - DELETEOP *deleteop;
256371 MSG Msg;
257 - deleteop = (DELETEOP*)opqueue_putlock(&This->queue, sizeof(DELETEOP));
258 - deleteop->opcode.opcode = OP_DELETE;
259 - deleteop->opcode.size = sizeof(DELETEOP);
260 - opqueue_putunlock(&This->queue, sizeof(DELETEOP));
261 - while (!This->shutdownfinished)
262 - {
263 - if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
264 - {
265 - TranslateMessage(&Msg);
266 - DispatchMessage(&Msg);
267 - }
268 - Sleep(0);
269 - }
270 - CloseHandle(This->syncevent);
 372+ EnterCriticalSection(&This->commandcs);
 373+ glRenderer_AddQueue(This, OP_DELETE, 0, 2, 0);
 374+ LeaveCriticalSection(&This->commandcs);
 375+ WaitForObjectAndMessages(This->hThread);
 376+ DeleteCriticalSection(&This->commandcs);
 377+ CloseHandle(This->busy);
 378+ CloseHandle(This->sync);
 379+ CloseHandle(This->start);
271380 CloseHandle(This->hThread);
272381 }
273382
274383 /**
275 - * Waits for the queue to be emptied
276 - * @param This
277 - * Pointer to glRenderer object
278 - */
279 -void glRenderer_Sync(glRenderer *This)
280 -{
281 - SYNCOP *syncop = (SYNCOP*)opqueue_putlock(&This->queue, sizeof(SYNCOP));
282 - syncop->opcode.opcode = OP_SYNC;
283 - syncop->opcode.size = sizeof(SYNCOP);
284 - opqueue_putunlock(&This->queue, sizeof(SYNCOP));
285 - WaitForSingleObject(This->syncevent, INFINITE);
286 -}
287 -
288 -/**
289384 * Creates an OpenGL texture.
290385 * @param This
291386 * Pointer to glRenderer object
@@ -305,17 +400,10 @@
306401 */
307402 void glRenderer_MakeTexture(glRenderer *This, TEXTURE *texture, DWORD width, DWORD height)
308403 {
309 - CREATEOP *texop;
310 - texture->width = width;
311 - texture->height = height;
312 - texop = (CREATEOP*)opqueue_putlock(&This->queue, sizeof(CREATEOP));
313 - texop->opcode.opcode = OP_CREATE;
314 - texop->opcode.size = sizeof(CREATEOP);
315 - texop->width = width;
316 - texop->height = height;
317 - texop->texture = texture;
318 - opqueue_putunlock(&This->queue, sizeof(CREATEOP));
319 - glRenderer_Sync(This);
 404+ EnterCriticalSection(&This->commandcs);
 405+ glRenderer_AddQueue(This, OP_CREATE, 0, 8, 3, 4, &texture, 4, &width, 4, &height);
 406+ glRenderer_Sync(This, 0);
 407+ LeaveCriticalSection(&This->commandcs);
320408 }
321409
322410 /**
@@ -347,7 +435,6 @@
348436 {
349437 BYTE *outbuffer;
350438 DWORD outx, outy, outpitch, outbpp;
351 - UPLOADOP *uploadop;
352439 DWORD *opbuffer;
353440 DWORD uploadopsize;
354441 if (bpp == 15) outbpp = 16;
@@ -382,19 +469,11 @@
383470 outy = bigy;
384471 outpitch = bigpitch;
385472 }
386 - uploadopsize = sizeof(UPLOADOP) + (outy*outpitch);
387 - opqueue_alloc(&This->queue, uploadopsize);
388 - uploadop = (UPLOADOP*)opqueue_putlock(&This->queue, uploadopsize);
389 - opbuffer = (DWORD*)&uploadop[1];
390 - uploadop->opcode.opcode = OP_UPLOAD;
391 - uploadop->opcode.size = uploadopsize;
392 - uploadop->width = outx;
393 - uploadop->height = outy;
394 - uploadop->pitch = outpitch;
395 - uploadop->miplevel = miplevel;
396 - uploadop->texture = texture;
397 - memcpy(opbuffer, outbuffer, outy*outpitch);
398 - opqueue_putunlock(&This->queue, uploadopsize);
 473+ EnterCriticalSection(&This->commandcs);
 474+ glRenderer_AddQueue(This, OP_UPLOAD, 0, 14, 6, 4, &outbuffer, 4, &texture, 4, &outx, 4, &outy,
 475+ 4, &outpitch, 4, &miplevel);
 476+ glRenderer_Sync(This, 0);
 477+ LeaveCriticalSection(&This->commandcs);
399478 }
400479
401480 /**
@@ -427,7 +506,6 @@
428507 BOOL doscale;
429508 BYTE *inbuffer;
430509 DWORD inx, iny, inpitch;
431 - DOWNLOADOP *downloadop;
432510 if ((x == bigx && y == bigy) || !bigbuffer)
433511 {
434512 doscale = FALSE;
@@ -444,14 +522,10 @@
445523 iny = bigy;
446524 inpitch = bigpitch;
447525 }
448 - downloadop = (DOWNLOADOP*)opqueue_putlock(&This->queue, sizeof(DOWNLOADOP));
449 - downloadop->opcode.opcode = OP_DOWNLOAD;
450 - downloadop->opcode.size = sizeof(DOWNLOADOP);
451 - downloadop->miplevel = miplevel;
452 - downloadop->buffer = inbuffer;
453 - downloadop->texture = texture;
454 - opqueue_putunlock(&This->queue, sizeof(DOWNLOADOP));
455 - glRenderer_Sync(This);
 526+ EnterCriticalSection(&This->commandcs);
 527+ glRenderer_AddQueue(This, OP_DOWNLOAD, 0, 8, 3, 4, &inbuffer, 4, &texture, 4, &miplevel);
 528+ glRenderer_Sync(This, 0);
 529+ LeaveCriticalSection(&This->commandcs);
456530 if (doscale)
457531 {
458532 switch (bpp)
@@ -483,12 +557,9 @@
484558 */
485559 void glRenderer_DeleteTexture(glRenderer *This, TEXTURE * texture)
486560 {
487 - DELETETEXOP *deleteop = (DELETETEXOP*)opqueue_putlock(&This->queue, sizeof(DELETETEXOP));
488 - deleteop->opcode.opcode = OP_DELETETEX;
489 - deleteop->opcode.size = 4 * sizeof(DWORD);
490 - deleteop->texture = texture;
491 - opqueue_putunlock(&This->queue, 4 * sizeof(DWORD));
492 - glRenderer_Sync(This);
 561+ EnterCriticalSection(&This->commandcs);
 562+ glRenderer_AddQueue(This, OP_DELETETEX, 0, 4, 1, 4, &texture);
 563+ LeaveCriticalSection(&This->commandcs);
493564 }
494565
495566 /**
@@ -506,42 +577,36 @@
507578 * entire surface will be used.
508579 * @param dwFlags
509580 * Flags to determine the behavior of the blitter. Certain flags control the
510 - * synchronization of the operation: (not yet implemented)
 581+ * synchronization of the operation: (not yet fully implemented)
511582 * - DDBLT_ASYNC: Adds the command to the queue. If the queue is full, returns
512583 * DDERR_WASSTILLDRAWING.
513584 * - DDBLT_DONOTWAIT: Fails and returns DDERR_WASSTILLDRAWING if the queue is full.
514 - * - DDBLT_WAIT: Waits until the Blt command is processed before returning.
 585+ * - DDBLT_WAIT: Waits until the Blt command is added to the queue before returning.
515586 * @param lpDDBltFx
516587 * Effect parameters for the Blt operation.
517588 */
518 -void glRenderer_Blt(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *src,
 589+HRESULT glRenderer_Blt(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *src,
519590 glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
520591 {
521 - RECT r,r2;
522 - if(((dest->ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER)) &&
523 - (dest->ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) ||
524 - ((dest->ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
525 - !(dest->ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP)))
 592+ DWORD nullfx = 0xFFFFFFFF;
 593+ RECT emptyrect = nullrect;
 594+ EnterCriticalSection(&This->commandcs);
 595+ int syncmode = 0;
 596+ if (dwFlags & DDBLT_ASYNC) syncmode = 1;
 597+ if (dwFlags & DDBLT_DONOTWAIT) syncmode = 2;
 598+ if (!lpSrcRect) lpSrcRect = &emptyrect;
 599+ if (!lpDestRect) lpDestRect = &emptyrect;
 600+ int fxsize = 4;
 601+ if (lpDDBltFx) fxsize = sizeof(DDBLTFX);
 602+ else lpDDBltFx = (LPDDBLTFX)&nullfx;
 603+ if (glRenderer_AddQueue(This, OP_BLT, syncmode, 11 + (sizeof(RECT) / 2) + (fxsize / 4), 6, sizeof(RECT), lpDestRect, 4, &src,
 604+ 4, &dest, sizeof(RECT), lpSrcRect, 4, &dwFlags, fxsize, lpDDBltFx))
526605 {
527 - GetClientRect(This->hWnd,&r);
528 - GetClientRect(This->RenderWnd->GetHWnd(),&r2);
529 - if(memcmp(&r2,&r,sizeof(RECT)))
530 - SetWindowPos(This->RenderWnd->GetHWnd(),NULL,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
 606+ LeaveCriticalSection(&This->commandcs);
 607+ return DDERR_WASSTILLDRAWING;
531608 }
532 - BLTOP *bltop = (BLTOP*)opqueue_putlock(&This->queue, sizeof(BLTOP));
533 - bltop->opcode.opcode = OP_BLT;
534 - bltop->opcode.size = sizeof(BLTOP);
535 - bltop->nulls = 0;
536 - if(lpDestRect) memcpy(&bltop->destrect, lpDestRect, sizeof(RECT));
537 - else bltop->nulls |= 1;
538 - if(lpSrcRect) memcpy(&bltop->srcrect, lpSrcRect, sizeof(RECT));
539 - else bltop->nulls |= 2;
540 - bltop->flags = dwFlags;
541 - if (lpDDBltFx) memcpy(&bltop->bltfx, lpDDBltFx, sizeof(DDBLTFX));
542 - else bltop->nulls |= 4;
543 - bltop->dest = dest;
544 - bltop->src = src;
545 - opqueue_putunlock(&This->queue, sizeof(BLTOP));
 609+ LeaveCriticalSection(&This->commandcs);
 610+ return DD_OK;
546611 }
547612
548613 /**
@@ -561,16 +626,10 @@
562627 */
563628 void glRenderer_DrawScreen(glRenderer *This, TEXTURE *texture, TEXTURE *paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src, GLint vsync)
564629 {
565 - DRAWSCREENOP *drawop = (DRAWSCREENOP*)opqueue_putlock(&This->queue, sizeof(DRAWSCREENOP));
566 - drawop->opcode.opcode = OP_DRAWSCREEN;
567 - drawop->opcode.size = sizeof(DRAWSCREENOP);
568 - drawop->texture = texture;
569 - drawop->paltex = paltex;
570 - drawop->dest = dest;
571 - drawop->src = src;
572 - drawop->vsync = vsync;
573 - opqueue_putunlock(&This->queue, sizeof(DRAWSCREENOP));
574 - glRenderer_Sync(This);
 630+ EnterCriticalSection(&This->commandcs);
 631+ glRenderer_AddQueue(This, OP_DRAWSCREEN, 0, 12, 5, 4, &texture, 4, &paltex, 4, &dest, 4, &src, 4, &vsync);
 632+ glRenderer_Sync(This, 0);
 633+ LeaveCriticalSection(&This->commandcs);
575634 }
576635
577636 /**
@@ -582,13 +641,9 @@
583642 */
584643 void glRenderer_InitD3D(glRenderer *This, int zbuffer, int x, int y)
585644 {
586 - INITD3DOP *initop = (INITD3DOP*)opqueue_putlock(&This->queue, sizeof(INITD3DOP));
587 - initop->opcode.opcode = OP_INITD3D;
588 - initop->opcode.size = sizeof(INITD3DOP);
589 - initop->zbuffer = zbuffer;
590 - initop->x = x;
591 - initop->y = y;
592 - opqueue_putunlock(&This->queue, sizeof(INITD3DOP));
 645+ EnterCriticalSection(&This->commandcs);
 646+ glRenderer_AddQueue(This, OP_INITD3D, 0, 8, 3, 4, &zbuffer, 4, &x, 4, &y);
 647+ LeaveCriticalSection(&This->commandcs);
593648 }
594649
595650 /**
@@ -612,35 +667,24 @@
613668 */
614669 void glRenderer_Clear(glRenderer *This, glDirectDrawSurface7 *target, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil)
615670 {
616 - CLEAROP *clearop;
617 - D3DRECT *rectbuffer;
618 - DWORD opsize = sizeof(CLEAROP) + (dwCount*sizeof(D3DRECT));
619 - if (opsize > 131072) opqueue_alloc(&This->queue, opsize);
620 - clearop = (CLEAROP*)opqueue_putlock(&This->queue, opsize);
621 - clearop->opcode.opcode = OP_CLEAR;
622 - clearop->opcode.size = opsize;
623 - clearop->target = target;
624 - clearop->count = dwCount;
625 - clearop->flags = dwFlags;
626 - clearop->color = dwColor;
627 - clearop->z = dvZ;
628 - clearop->stencil = dwStencil;
629 - rectbuffer = (D3DRECT*)&clearop[1];
630 - if (dwCount) memcpy(rectbuffer, lpRects, dwCount*sizeof(D3DRECT));
631 - opqueue_putunlock(&This->queue, opsize);
 671+ EnterCriticalSection(&This->commandcs);
 672+ int rectsize = dwCount * sizeof(D3DRECT);
 673+ glRenderer_AddQueue(This, OP_CLEAR, 0, 15 + (rectsize / 4), 7, 4, &target, 4, &dwCount,
 674+ 4, &dwFlags, 4, &dwColor, 4, &dvZ, 4, &dwStencil, rectsize, lpRects);
 675+ LeaveCriticalSection(&This->commandcs);
632676 }
633677
634678 /**
635 - * Instructs the OpenGL driver to send all queued commands to the GPU.
 679+ * Instructs the OpenGL driver to send all queued commands to the GPU, and empties the queue.
636680 * @param This
637681 * Pointer to glRenderer object
638682 */
639683 void glRenderer_Flush(glRenderer *This)
640684 {
641 - FLUSHOP *flushop = (FLUSHOP*)opqueue_putlock(&This->queue, sizeof(FLUSHOP));
642 - flushop->opcode.opcode = OP_FLUSH;
643 - flushop->opcode.size = sizeof(FLUSHOP);
644 - opqueue_putunlock(&This->queue, sizeof(FLUSHOP));
 685+ EnterCriticalSection(&This->commandcs);
 686+ glRenderer_AddQueue(This, OP_CLEAR, 0, 2, 0, 0, NULL);
 687+ glRenderer_Sync(This, 0);
 688+ LeaveCriticalSection(&This->commandcs);
645689 }
646690
647691 /**
@@ -658,35 +702,11 @@
659703 */
660704 void glRenderer_SetWnd(glRenderer *This, DWORD width, DWORD height, DWORD bpp, DWORD fullscreen, DWORD frequency, HWND newwnd, BOOL devwnd)
661705 {
662 - SETWNDOP *setwndop;
663 - MSG Msg;
664 - if(fullscreen && newwnd)
665 - {
666 - SetWindowLongPtrA(newwnd,GWL_EXSTYLE,WS_EX_APPWINDOW);
667 - SetWindowLongPtrA(newwnd,GWL_STYLE,WS_OVERLAPPED);
668 - ShowWindow(newwnd,SW_MAXIMIZE);
669 - }
670 - setwndop = (SETWNDOP*)opqueue_putlock(&This->queue, sizeof(SETWNDOP));
671 - This->setwndfinished = FALSE;
672 - setwndop->opcode.opcode = OP_SETWND;
673 - setwndop->opcode.size = sizeof(SETWNDOP);
674 - setwndop->width = width;
675 - setwndop->height = height;
676 - setwndop->bpp = bpp;
677 - setwndop->fullscreen = fullscreen;
678 - setwndop->frequency = frequency;
679 - setwndop->hwnd = newwnd;
680 - setwndop->devwnd = devwnd;
681 - opqueue_putunlock(&This->queue, sizeof(SETWNDOP));
682 - while (!This->setwndfinished)
683 - {
684 - if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
685 - {
686 - TranslateMessage(&Msg);
687 - DispatchMessage(&Msg);
688 - }
689 - Sleep(0);
690 - }
 706+ EnterCriticalSection(&This->commandcs);
 707+ glRenderer_AddQueue(This, OP_SETWND, 0, 16, 7, 4, &width, 4, &height, 4, &bpp, 4, &fullscreen,
 708+ 4, &frequency, 4, &newwnd, 4, &devwnd);
 709+ glRenderer_Sync(This, 0);
 710+ LeaveCriticalSection(&This->commandcs);
691711 }
692712 /**
693713 * Draws one or more primitives to the currently selected render target.
@@ -718,32 +738,17 @@
719739 void glRenderer_DrawPrimitives(glRenderer *This, glDirect3DDevice7 *device, GLenum mode, DWORD stride, BYTE *vertices, DWORD dwVertexTypeDesc, DWORD count, LPWORD indices,
720740 DWORD indexcount, DWORD flags)
721741 {
722 - DRAWPRIMITIVESOP *drawop;
723 - BYTE *vertexop;
724 - BYTE *indexop;
725 - DWORD vertexsize = NextMultipleOfWord(count * stride);
726 - DWORD indexsize = NextMultipleOfWord(indexcount * sizeof(WORD));
727 - DWORD opsize = sizeof(DRAWPRIMITIVESOP) + vertexsize + indexsize;
728 - if (opsize > 131072) opqueue_alloc(&This->queue, opsize);
729 - drawop = (DRAWPRIMITIVESOP*)opqueue_putlock(&This->queue, opsize);
730 - vertexop = (BYTE*)&drawop[1];
731 - indexop = vertexop + vertexsize;
732 - drawop->opcode.opcode = OP_DRAWPRIMITIVES;
733 - drawop->opcode.size = opsize;
734 - drawop->device = device;
735 - drawop->mode = mode;
736 - drawop->stride = stride;
737 - drawop->fvf = dwVertexTypeDesc;
738 - drawop->count = count;
739 - drawop->indexcount = indexcount;
740 - drawop->flags = flags;
741 - drawop->vertexoffset = sizeof(DRAWPRIMITIVESOP);
742 - if (indices) drawop->indexoffset = sizeof(DRAWPRIMITIVESOP) + vertexsize;
743 - else drawop->indexcount = 0;
744 - memcpy(vertexop, vertices, count*stride);
745 - if (indices) memcpy(indexop, indices, indexcount*sizeof(WORD));
746 - opqueue_putunlock(&This->queue, opsize);
747 - if (flags & D3DDP_WAIT) glRenderer_Sync(This);
 742+ EnterCriticalSection(&This->commandcs);
 743+ DWORD vertsize = 0;
 744+ DWORD indexsize = 0;
 745+ if (!indices) indexcount = 0;
 746+ vertsize = (stride * count) / 4;
 747+ indexsize = NextMultipleOf2(indexcount) / 2;
 748+ glRenderer_AddQueue(This, OP_DRAWPRIMITIVES, 0, 16 + vertsize + indexsize, 8, 4, &device,
 749+ 4, &mode, 4, &stride, 4, &dwVertexTypeDesc, 4, &count, 4, &indexcount,
 750+ vertsize, vertices, indexsize, indices);
 751+ if (flags & D3DDP_WAIT) glRenderer_Sync(This, 0);
 752+ LeaveCriticalSection(&This->commandcs);
748753 }
749754
750755 /**
@@ -755,12 +760,10 @@
756761 */
757762 void glRenderer_DeleteFBO(glRenderer *This, FBO *fbo)
758763 {
759 - DELETEFBOOP *fboop = (DELETEFBOOP*)opqueue_putlock(&This->queue, sizeof(DELETEFBOOP));
760 - fboop->opcode.opcode = OP_DELETEFBO;
761 - fboop->opcode.size = sizeof(DELETEFBOOP);
762 - fboop->fbo = fbo;
763 - opqueue_putunlock(&This->queue, sizeof(DELETEFBOOP));
764 - glRenderer_Sync(This);
 764+ EnterCriticalSection(&This->commandcs);
 765+ glRenderer_AddQueue(This, OP_DELETEFBO, 0, 4, 1, 4, &fbo);
 766+ glRenderer_Sync(This, 0);
 767+ LeaveCriticalSection(&This->commandcs);
765768 }
766769
767770 /**
@@ -772,11 +775,9 @@
773776 */
774777 void glRenderer_UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface)
775778 {
776 - UPDATECLIPPEROP *updateop = (UPDATECLIPPEROP*)opqueue_putlock(&This->queue, sizeof(UPDATECLIPPEROP));
777 - updateop->opcode.opcode = OP_UPDATECLIPPER;
778 - updateop->opcode.size = sizeof(UPDATECLIPPEROP);
779 - updateop->surface = surface;
780 - opqueue_putunlock(&This->queue, sizeof(UPDATECLIPPEROP));
 779+ EnterCriticalSection(&This->commandcs);
 780+ glRenderer_AddQueue(This, OP_UPDATECLIPPER, 0, 4, 4, surface);
 781+ LeaveCriticalSection(&This->commandcs);
781782 }
782783
783784
@@ -803,18 +804,12 @@
804805 */
805806 void glRenderer_DepthFill(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *dest, LPDDBLTFX lpDDBltFx)
806807 {
807 - DEPTHFILLOP *depthop = (DEPTHFILLOP*)opqueue_putlock(&This->queue, sizeof(DEPTHFILLOP));
808 - depthop->opcode.opcode = OP_DEPTHFILL;
809 - depthop->opcode.size = sizeof(DEPTHFILLOP);
810 - if (lpDestRect)
811 - {
812 - depthop->userect = TRUE;
813 - memcpy(&depthop->rect, lpDestRect, sizeof(RECT));
814 - }
815 - else depthop->userect = FALSE;
816 - memcpy(&depthop->bltfx, lpDDBltFx, sizeof(DDBLTFX));
817 - depthop->dest = dest;
818 - opqueue_putunlock(&This->queue, sizeof(DEPTHFILLOP));
 808+ EnterCriticalSection(&This->commandcs);
 809+ RECT emptyrect = nullrect;
 810+ if (!lpDestRect) lpDestRect = &emptyrect;
 811+ glRenderer_AddQueue(This, OP_DEPTHFILL, 0, 4 + (sizeof(RECT) / 4) + (sizeof(DDBLTFX) / 4),
 812+ 3, 4, dest, sizeof(RECT), lpDestRect, sizeof(DDBLTFX), lpDDBltFx);
 813+ LeaveCriticalSection(&This->commandcs);
819814 }
820815
821816 /**
@@ -828,12 +823,10 @@
829824 */
830825 void glRenderer_SetRenderState(glRenderer *This, D3DRENDERSTATETYPE dwRendStateType, DWORD dwRenderState)
831826 {
832 - SETRENDERSTATEOP *stateop = (SETRENDERSTATEOP*)opqueue_putlock(&This->queue, sizeof(SETRENDERSTATEOP));
833 - stateop->opcode.opcode = OP_SETRENDERSTATE;
834 - stateop->opcode.size = sizeof(SETRENDERSTATEOP);
835 - stateop->state = dwRendStateType;
836 - stateop->value = dwRenderState;
837 - opqueue_putunlock(&This->queue, sizeof(SETRENDERSTATEOP));
 827+ EnterCriticalSection(&This->commandcs);
 828+ if (!This->running) This->renderstate[dwRendStateType] = dwRenderState;
 829+ else glRenderer_AddQueue(This, OP_SETRENDERSTATE, 0, 6, 2, 4, &dwRendStateType, 4, &dwRenderState);
 830+ LeaveCriticalSection(&This->commandcs);
838831 }
839832
840833 /**
@@ -847,12 +840,9 @@
848841 */
849842 void glRenderer_SetTexture(glRenderer *This, DWORD dwStage, glDirectDrawSurface7 *Texture)
850843 {
851 - SETTEXTUREOP *texop = (SETTEXTUREOP*)opqueue_putlock(&This->queue, sizeof(SETTEXTUREOP));
852 - texop->opcode.opcode = OP_SETTEXTURE;
853 - texop->opcode.size = sizeof(SETTEXTUREOP);
854 - texop->stage = dwStage;
855 - texop->texture = Texture;
856 - opqueue_putunlock(&This->queue, sizeof(SETTEXTUREOP));
 844+ EnterCriticalSection(&This->commandcs);
 845+ glRenderer_AddQueue(This, OP_SETTEXTURE, 0, 6, 2, 4, &dwStage, 4, &Texture);
 846+ LeaveCriticalSection(&This->commandcs);
857847 }
858848
859849 /**
@@ -868,13 +858,9 @@
869859 */
870860 void glRenderer_SetTextureStageState(glRenderer *This, DWORD dwStage, D3DTEXTURESTAGESTATETYPE dwState, DWORD dwValue)
871861 {
872 - SETTEXTURESTAGESTATEOP *stateop = (SETTEXTURESTAGESTATEOP*)opqueue_putlock(&This->queue, sizeof(SETTEXTURESTAGESTATEOP));
873 - stateop->opcode.opcode = OP_SETTEXTURESTAGESTATE;
874 - stateop->opcode.size = sizeof(SETTEXTURESTAGESTATEOP);
875 - stateop->stage = dwStage;
876 - stateop->state = dwState;
877 - stateop->value = dwValue;
878 - opqueue_putunlock(&This->queue, sizeof(SETTEXTURESTAGESTATEOP));
 862+ EnterCriticalSection(&This->commandcs);
 863+ glRenderer_AddQueue(This, OP_SETTEXTURESTAGESTATE, 0, 8, 3, 4, &dwStage, 4, &dwState, 4, &dwValue);
 864+ LeaveCriticalSection(&This->commandcs);
879865 }
880866
881867 /**
@@ -888,12 +874,11 @@
889875 */
890876 void glRenderer_SetTransform(glRenderer *This, D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix)
891877 {
892 - SETTRANSFORMOP *transformop = (SETTRANSFORMOP*)opqueue_putlock(&This->queue, sizeof(SETTRANSFORMOP));
893 - transformop->opcode.opcode = OP_SETTRANSFORM;
894 - transformop->opcode.size = sizeof(SETTRANSFORMOP);
895 - transformop->state = dtstTransformStateType;
896 - memcpy(&transformop->matrix, lpD3DMatrix, sizeof(D3DMATRIX));
897 - opqueue_putunlock(&This->queue, sizeof(SETTRANSFORMOP));
 878+ EnterCriticalSection(&This->commandcs);
 879+ if (!This->running) memcpy(&This->transform[dtstTransformStateType], lpD3DMatrix, sizeof(D3DMATRIX));
 880+ else glRenderer_AddQueue(This, OP_SETTRANSFORM, 0, 4 + (sizeof(D3DMATRIX) / 4), 2,
 881+ 4, &dtstTransformStateType, sizeof(D3DMATRIX), lpD3DMatrix);
 882+ LeaveCriticalSection(&This->commandcs);
898883 }
899884
900885 /**
@@ -905,11 +890,11 @@
906891 */
907892 void glRenderer_SetMaterial(glRenderer *This, LPD3DMATERIAL7 lpMaterial)
908893 {
909 - SETMATERIALOP *materialop = (SETMATERIALOP*)opqueue_putlock(&This->queue, sizeof(SETMATERIALOP));
910 - materialop->opcode.opcode = OP_SETMATERIAL;
911 - materialop->opcode.size = sizeof(SETMATERIALOP);
912 - memcpy(&materialop->material, lpMaterial, sizeof(D3DMATERIAL));
913 - opqueue_putunlock(&This->queue, sizeof(SETMATERIALOP));
 894+ EnterCriticalSection(&This->commandcs);
 895+ if (!This->running) memcpy(&This->material, lpMaterial, sizeof(D3DMATERIAL7));
 896+ glRenderer_AddQueue(This, OP_SETMATERIAL, 0, 2 + (sizeof(D3DMATERIAL7) / 4), 1,
 897+ sizeof(D3DMATERIAL), lpMaterial);
 898+ LeaveCriticalSection(&This->commandcs);
914899 }
915900
916901 /**
@@ -926,13 +911,15 @@
927912
928913 void glRenderer_SetLight(glRenderer *This, DWORD index, LPD3DLIGHT7 light, BOOL remove)
929914 {
930 - SETLIGHTOP *lightop = (SETLIGHTOP*)opqueue_putlock(&This->queue, sizeof(SETLIGHTOP));
931 - lightop->opcode.opcode = OP_SETLIGHT;
932 - lightop->opcode.size = sizeof(SETLIGHTOP);
933 - lightop->index = index;
934 - lightop->remove = remove;
935 - if(light) memcpy(&lightop->light, light, sizeof(D3DLIGHT7));
936 - opqueue_putunlock(&This->queue, sizeof(SETLIGHTOP));
 915+ EnterCriticalSection(&This->commandcs);
 916+ D3DLIGHT7 null_light;
 917+ D3DLIGHT7 *light7;
 918+ DWORD _remove = remove;
 919+ if (light) light7 = light;
 920+ else light7 = &null_light;
 921+ glRenderer_AddQueue(This, OP_SETLIGHT, 0, 6 + (sizeof(D3DLIGHT7) / 4), 3, 4, &index,
 922+ 4, &_remove, sizeof(D3DLIGHT7), light7);
 923+ LeaveCriticalSection(&This->commandcs);
937924 }
938925
939926 /**
@@ -944,11 +931,10 @@
945932 */
946933 void glRenderer_SetViewport(glRenderer *This, LPD3DVIEWPORT7 lpViewport)
947934 {
948 - SETVIEWPORTOP *viewportop = (SETVIEWPORTOP*)opqueue_putlock(&This->queue, sizeof(SETVIEWPORTOP));
949 - viewportop->opcode.opcode = OP_SETVIEWPORT;
950 - viewportop->opcode.size = sizeof(SETVIEWPORTOP);
951 - memcpy(&viewportop->viewport, lpViewport, sizeof(D3DVIEWPORT7));
952 - opqueue_putunlock(&This->queue,sizeof(SETVIEWPORTOP));
 935+ EnterCriticalSection(&This->commandcs);
 936+ glRenderer_AddQueue(This, OP_SETVIEWPORT, 0, 2 + (sizeof(D3DVIEWPORT7) / 4), 1,
 937+ sizeof(D3DVIEWPORT7), lpViewport);
 938+ LeaveCriticalSection(&This->commandcs);
953939 }
954940
955941 /**
@@ -961,37 +947,27 @@
962948 DWORD WINAPI glRenderer__Entry(glRenderer *This)
963949 {
964950 float tmpfloats[16];
965 - NULLOP *opcode;
966 - SETWNDOP *wndop;
967 - CREATEOP *createop;
968 - UPLOADOP *uploadop;
969 - DOWNLOADOP *downloadop;
970 - DELETETEXOP *deletetexop;
971 - BLTOP *bltop;
972 - DRAWSCREENOP *drawscreenop;
973 - INITD3DOP *initd3dop;
974 - CLEAROP *clearop;
975 - DRAWPRIMITIVESOP *drawprimitivesop;
976 - BYTE *drawprimitivesdata;
977 - DELETEFBOOP *deletefboop;
978 - UPDATECLIPPEROP *updateclipperop;
979 - DEPTHFILLOP *depthfillop;
980 - SETRENDERSTATEOP *setrenderstateop;
981 - SETTEXTUREOP *settextureop;
982 - SETTEXTURESTAGESTATEOP *settexturestagestateop;
983 - SETTRANSFORMOP *settransformop;
984 - SETMATERIALOP *setmaterialop;
985 - SETLIGHTOP *setlightop;
986 - SETVIEWPORTOP *setviewportop;
987 - This->shutdownfinished = FALSE;
988 - INITOP *initop = (INITOP*)opqueue_getlock(&This->queue);
989 - glRenderer__InitGL(This, initop->width, initop->height, initop->bpp, initop->fullscreen,
990 - initop->frequency, initop->hwnd, initop->glDD7);
991 - opqueue_getunlock(&This->queue, initop->opcode.size);
992 - while(1)
 951+ RECT *r1;
 952+ RECT *r2;
 953+ DDBLTFX *fxptr;
 954+ glRenderer__InitGL(This, (DWORD)This->inputs[0], (DWORD)This->inputs[1], (DWORD)This->inputs[2],
 955+ (BOOL)This->inputs[3],(DWORD)This->inputs[4], (HWND)This->inputs[5], (glDirectDraw7*)This->inputs[6]);
 956+ This->dead = false;
 957+ This->queue = (LPDWORD)malloc(1048576);
 958+ This->queuesize = 1048576 / sizeof(DWORD);
 959+ This->queuelength = This->queue_read = This->queue_write = This->syncsize = 0;
 960+ SetEvent(This->busy);
 961+ This->start = CreateEvent(NULL, TRUE, FALSE, NULL);
 962+ ResetEvent(This->start);
 963+ This->sync = CreateEvent(NULL, TRUE, FALSE, NULL);
 964+queueloop:
 965+ WaitForSingleObject(&This->start, INFINITE);
 966+ if (This->queuelength)
993967 {
994 - opcode = (NULLOP*)opqueue_getlock(&This->queue);
995 - switch(opcode->opcode.opcode)
 968+ EnterCriticalSection(&This->queuecs);
 969+ This->running = TRUE;
 970+ LeaveCriticalSection(&This->queuecs);
 971+ switch (This->queue[This->queue_read])
996972 {
997973 case OP_DELETE:
998974 if(This->hRC)
@@ -1032,135 +1008,150 @@
10331009 This->hDC = NULL;
10341010 delete This->RenderWnd;
10351011 This->RenderWnd = NULL;
1036 - opqueue_getunlock(&This->queue, opcode->opcode.size);
1037 - opqueue_delete(&This->queue);
1038 - This->shutdownfinished = TRUE;
1039 - return 0;
 1012+ This->dead = true;
10401013 break;
1041 - case OP_SYNC:
1042 - SetEvent(This->syncevent);
1043 - opqueue_getunlock(&This->queue, opcode->opcode.size);
 1014+ case OP_NULL:
10441015 break;
10451016 case OP_SETWND:
1046 - wndop = (SETWNDOP*)opcode;
1047 - glRenderer__SetWnd(This, wndop->width, wndop->height, wndop->bpp, wndop->fullscreen,
1048 - wndop->frequency, wndop->hwnd, wndop->devwnd);
1049 - opqueue_getunlock(&This->queue, wndop->opcode.size);
 1017+ if (This->queue[This->queue_read + 1] != 16) break;
 1018+ glRenderer__SetWnd(This, (DWORD)This->queue[This->queue_read + 3], (DWORD)This->queue[This->queue_read + 5],
 1019+ (DWORD)This->queue[This->queue_read + 7], (DWORD)This->queue[This->queue_read + 9], (DWORD)This->queue[This->queue_read + 11],
 1020+ (HWND)This->queue[This->queue_read + 13], (BOOL)This->queue[This->queue_read + 15]);
10501021 break;
10511022 case OP_CREATE:
1052 - createop = (CREATEOP*)opcode;
1053 - glRenderer__MakeTexture(This, createop->texture, createop->width, createop->height);
1054 - opqueue_getunlock(&This->queue, createop->opcode.size);
 1023+ if (This->queue[This->queue_read + 1] != 8) break;
 1024+ glRenderer__MakeTexture(This, (TEXTURE*)This->queue[This->queue_read + 3],
 1025+ (DWORD)This->queue[This->queue_read + 5], (DWORD)This->queue[This->queue_read + 7]);
10551026 break;
10561027 case OP_UPLOAD:
1057 - uploadop = (UPLOADOP*)opcode;
1058 - glRenderer__UploadTexture(This, (BYTE*)&uploadop[1], uploadop->texture, uploadop->width, uploadop->height,
1059 - uploadop->pitch, uploadop->miplevel);
1060 - opqueue_getunlock(&This->queue, uploadop->opcode.size);
 1028+ if (This->queue[This->queue_read + 1] != 14) break;
 1029+ glRenderer__UploadTexture(This, (BYTE*)This->queue[This->queue_read + 3], (TEXTURE*)This->queue[This->queue_read + 5],
 1030+ (DWORD)This->queue[This->queue_read + 7], (DWORD)This->queue[This->queue_read + 9],
 1031+ (DWORD)This->queue[This->queue_read + 11], (DWORD)This->queue[This->queue_read + 13]);
10611032 break;
10621033 case OP_DOWNLOAD:
1063 - downloadop = (DOWNLOADOP*)opcode;
1064 - glRenderer__DownloadTexture(This, downloadop->buffer, downloadop->texture, downloadop->miplevel);
1065 - opqueue_getunlock(&This->queue, downloadop->opcode.size);
 1034+ if (This->queue[This->queue_read + 1] != 8) break;
 1035+ glRenderer__DownloadTexture(This, (BYTE*)This->queue[This->queue_read + 3],
 1036+ (TEXTURE*)This->queue[This->queue_read + 5], (DWORD)This->queue[This->queue_read + 7]);
10661037 break;
10671038 case OP_DELETETEX:
1068 - deletetexop = (DELETETEXOP*)opcode;
1069 - glRenderer__DeleteTexture(This,deletetexop->texture);
1070 - opqueue_getunlock(&This->queue, deletetexop->opcode.size);
 1039+ if (This->queue[This->queue_read + 1] != 4) break;
 1040+ glRenderer__DeleteTexture(This, (TEXTURE*)This->queue[This->queue_read + 3]);
10711041 break;
10721042 case OP_BLT:
1073 - bltop = (BLTOP*)opcode;
1074 - glRenderer__Blt(This, (bltop->nulls & 1) ? NULL : &bltop->destrect, bltop->src, bltop->dest,
1075 - (bltop->nulls & 2) ? NULL : &bltop->srcrect, bltop->flags, (bltop->nulls & 4) ? NULL : &bltop->bltfx);
1076 - opqueue_getunlock(&This->queue, bltop->opcode.size);
 1043+ if (This->queue[This->queue_read + 1] < (10 + (sizeof(RECT) / 2))) break;
 1044+ r1 = (RECT*)&This->queue[This->queue_read + 3];
 1045+ r2 = (RECT*)&This->queue[This->queue_read + 8 + (sizeof(RECT) / 4)];
 1046+ if (!memcmp(r1, &nullrect, sizeof(RECT))) r1 = NULL;
 1047+ if (!memcmp(r2, &nullrect, sizeof(RECT))) r2 = NULL;
 1048+ if ((This->queue[This->queue_read + 10 + (sizeof(RECT) / 2)]) == 4) fxptr = NULL;
 1049+ else fxptr = (DDBLTFX*)&This->queue[This->queue_read + 11 + (sizeof(RECT) / 2)];
 1050+ glRenderer__Blt(This, r1, (glDirectDrawSurface7*)This->queue[This->queue_read + 4 + (sizeof(RECT) / 4)],
 1051+ (glDirectDrawSurface7*)This->queue[This->queue_read + 6 + (sizeof(RECT) / 4)], r2,
 1052+ (DWORD)This->queue[This->queue_read + 9 + (sizeof(RECT) / 2)], fxptr);
10771053 break;
10781054 case OP_DRAWSCREEN:
1079 - drawscreenop = (DRAWSCREENOP*)opcode;
1080 - glRenderer__DrawScreen(This, drawscreenop->texture, drawscreenop->paltex, drawscreenop->dest,
1081 - drawscreenop->src, drawscreenop->vsync);
1082 - opqueue_getunlock(&This->queue, drawscreenop->opcode.size);
 1055+ if (This->queue[This->queue_read + 1] != 12) break;
 1056+ glRenderer__DrawScreen(This, (TEXTURE*)This->queue[This->queue_read + 3], (TEXTURE*)This->queue[This->queue_read + 5],
 1057+ (glDirectDrawSurface7*)This->queue[This->queue_read + 7], (glDirectDrawSurface7*)This->queue[This->queue_read + 9],
 1058+ (GLint)This->queue[This->queue_read + 11]);
10831059 break;
10841060 case OP_INITD3D:
1085 - initd3dop = (INITD3DOP*)opcode;
1086 - glRenderer__InitD3D(This, initd3dop->zbuffer, initd3dop->x, initd3dop->y);
1087 - opqueue_getunlock(&This->queue, initd3dop->opcode.size);
 1061+ if (This->queue[This->queue_read + 1] != 8) break;
 1062+ glRenderer__InitD3D(This,(int)This->queue[This->queue_read+3],(int)This->queue[This->queue_read+5],
 1063+ (int)This->queue[This->queue_read + 7]);
10881064 break;
10891065 case OP_CLEAR:
1090 - clearop = (CLEAROP*)opcode;
1091 - glRenderer__Clear(This, clearop->target, clearop->count, (LPD3DRECT)&clearop[1],
1092 - clearop->flags, clearop->color, clearop->z, clearop->stencil);
1093 - opqueue_getunlock(&This->queue, clearop->opcode.size);
 1066+ if (This->queue[This->queue_read + 1] < 15) break;
 1067+ if (This->queue[This->queue_read + 14] != 0) r1 = (RECT*)&This->queue[This->queue_read + 15];
 1068+ else r1 = NULL;
 1069+ glRenderer__Clear(This, (glDirectDrawSurface7*)This->queue[This->queue_read + 3], (DWORD)This->queue[This->queue_read + 5],
 1070+ (LPD3DRECT)r1, (DWORD)This->queue[This->queue_read + 7], (DWORD)This->queue[This->queue_read + 9],
 1071+ (D3DVALUE)This->queue[This->queue_read + 11], (DWORD)This->queue[This->queue_read + 13]);
10941072 break;
10951073 case OP_FLUSH:
 1074+ if (This->queue[This->queue_read + 1] != 2) break;
10961075 glRenderer__Flush(This);
1097 - opqueue_getunlock(&This->queue, opcode->opcode.size);
10981076 break;
10991077 case OP_DRAWPRIMITIVES:
1100 - drawprimitivesop = (DRAWPRIMITIVESOP*)opcode;
1101 - drawprimitivesdata = (BYTE*)opcode;
1102 - glRenderer__DrawPrimitives(This, drawprimitivesop->device, drawprimitivesop->mode, drawprimitivesop->stride,
1103 - &drawprimitivesdata[drawprimitivesop->vertexoffset], drawprimitivesop->fvf, drawprimitivesop->count,
1104 - (WORD*)&drawprimitivesdata[drawprimitivesop->indexoffset], drawprimitivesop->indexcount, drawprimitivesop->flags);
1105 - opqueue_getunlock(&This->queue, drawprimitivesop->opcode.size);
 1078+ if (This->queue[This->queue_read + 1] < 16) break;
 1079+ glRenderer__DrawPrimitives(This, (glDirect3DDevice7*)This->queue[This->queue_read + 3], (GLenum)This->queue[This->queue_read+5],
 1080+ (DWORD)This->queue[This->queue_read + 7], (BYTE*)&This->queue[This->queue_read+15], (DWORD)This->queue[This->queue_read + 9],
 1081+ (DWORD)This->queue[This->queue_read + 11], (LPWORD)&This->queue[This->queue_read + 16+This->queue[This->queue_read+14]],
 1082+ (DWORD)This->queue[This->queue_read + 13], 0);
11061083 break;
11071084 case OP_DELETEFBO:
1108 - deletefboop = (DELETEFBOOP*)opcode;
1109 - glRenderer__DeleteFBO(This,deletefboop->fbo);
1110 - opqueue_getunlock(&This->queue, deletefboop->opcode.size);
 1085+ if (This->queue[This->queue_read + 1] != 4) break;
 1086+ glRenderer__DeleteFBO(This, (FBO*)This->queue[This->queue_read + 3]);
11111087 break;
11121088 case OP_UPDATECLIPPER:
1113 - updateclipperop = (UPDATECLIPPEROP*)opcode;
1114 - glRenderer__UpdateClipper(This, updateclipperop->surface);
1115 - opqueue_getunlock(&This->queue, updateclipperop->opcode.size);
 1089+ if (This->queue[This->queue_read + 1] != 4) break;
 1090+ glRenderer__UpdateClipper(This, (glDirectDrawSurface7*)This->queue[This->queue_read + 3]);
11161091 break;
11171092 case OP_DEPTHFILL:
1118 - depthfillop = (DEPTHFILLOP*)opcode;
1119 - glRenderer__DepthFill(This, depthfillop->userect ? &depthfillop->rect : NULL, depthfillop->dest,
1120 - &depthfillop->bltfx);
1121 - opqueue_getunlock(&This->queue, depthfillop->opcode.size);
 1093+ if (This->queue[This->queue_read + 1] != (4 + (sizeof(RECT) / 4) + (sizeof(DDBLTFX) / 4))) break;
 1094+ r1 = (RECT*)&This->queue[This->queue_read + 5];
 1095+ if (!memcmp(r1, &nullrect, sizeof(RECT))) r1 = NULL;
 1096+ glRenderer__DepthFill(This, r1, (glDirectDrawSurface7*)This->queue[This->queue_read + 3],
 1097+ (LPDDBLTFX)&This->queue[This->queue_read + 4 + sizeof(RECT)]);
11221098 break;
11231099 case OP_SETRENDERSTATE:
1124 - setrenderstateop = (SETRENDERSTATEOP*)opcode;
1125 - glRenderer__SetRenderState(This, setrenderstateop->state, setrenderstateop->value);
1126 - opqueue_getunlock(&This->queue, setrenderstateop->opcode.size);
 1100+ if (This->queue[This->queue_read + 1] != 6) break;
 1101+ glRenderer__SetRenderState(This, (D3DRENDERSTATETYPE)This->queue[This->queue_read + 3],
 1102+ (DWORD)This->queue[This->queue_read + 5]);
11271103 break;
11281104 case OP_SETTEXTURE:
1129 - settextureop = (SETTEXTUREOP*)opcode;
1130 - glRenderer__SetTexture(This, settextureop->stage, settextureop->texture);
1131 - opqueue_getunlock(&This->queue, settextureop->opcode.size);
 1105+ if (This->queue[This->queue_read + 1] != 6) break;
 1106+ glRenderer__SetTexture(This, (DWORD)This->queue[This->queue_read + 3],
 1107+ (glDirectDrawSurface7*)This->queue[This->queue_read + 5]);
11321108 break;
11331109 case OP_SETTEXTURESTAGESTATE:
1134 - settexturestagestateop = (SETTEXTURESTAGESTATEOP*)opcode;
1135 - glRenderer__SetTextureStageState(This, settexturestagestateop->stage,
1136 - settexturestagestateop->state, settexturestagestateop->value);
1137 - opqueue_getunlock(&This->queue, settexturestagestateop->opcode.size);
 1110+ if (This->queue[This->queue_read + 1] != 8) break;
 1111+ glRenderer__SetTextureStageState(This, (DWORD)This->queue[This->queue_read + 3],
 1112+ (D3DTEXTURESTAGESTATETYPE)This->queue[This->queue_read + 5], (DWORD)This->queue[This->queue_read + 7]);
11381113 break;
11391114 case OP_SETTRANSFORM:
1140 - settransformop = (SETTRANSFORMOP*)opcode;
1141 - glRenderer__SetTransform(This, settransformop->state, &settransformop->matrix);
1142 - opqueue_getunlock(&This->queue, settransformop->opcode.size);
 1115+ if (This->queue[This->queue_read + 1] != (4 + (sizeof(D3DMATRIX) / 4))) break;
 1116+ glRenderer__SetTransform(This, (D3DTRANSFORMSTATETYPE)This->queue[This->queue_read + 3],
 1117+ (LPD3DMATRIX)&This->queue[This->queue_read + 5]);
11431118 break;
11441119 case OP_SETMATERIAL:
1145 - setmaterialop = (SETMATERIALOP*)opcode;
1146 - glRenderer__SetMaterial(This, &setmaterialop->material);
1147 - opqueue_getunlock(&This->queue, setmaterialop->opcode.size);
 1120+ if (This->queue[This->queue_read + 1] != (2 + (sizeof(D3DMATERIAL7) / 4))) break;
 1121+ glRenderer__SetMaterial(This, (LPD3DMATERIAL7)&This->queue[This->queue_read + 3]);
11481122 break;
11491123 case OP_SETLIGHT:
1150 - setlightop = (SETLIGHTOP*)opcode;
1151 - glRenderer__SetLight(This, setlightop->index, &setlightop->light, setlightop->remove);
1152 - opqueue_getunlock(&This->queue, setlightop->opcode.size);
 1124+ if (This->queue[This->queue_read + 1] != (6 + (sizeof(D3DLIGHT7) / 4))) break;
 1125+ glRenderer__SetLight(This, (DWORD)This->queue[This->queue_read + 3], (LPD3DLIGHT7)&This->queue[This->queue_read + 7],
 1126+ (BOOL)This->queue[This->queue_read + 5]);
11531127 break;
11541128 case OP_SETVIEWPORT:
1155 - setviewportop = (SETVIEWPORTOP*)opcode;
1156 - glRenderer__SetViewport(This, &setviewportop->viewport);
1157 - opqueue_getunlock(&This->queue, setviewportop->opcode.size);
 1129+ if (This->queue[This->queue_read + 1] != (2 + (sizeof(D3DVIEWPORT7) / 4))) break;
 1130+ glRenderer__SetViewport(This, (LPD3DVIEWPORT7)&This->queue[This->queue_read + 3]);
11581131 break;
 1132+ case OP_RESETQUEUE:
 1133+ break;
11591134 default:
11601135 FIXME("Invalid opcode detected");
1161 - opqueue_getunlock(&This->queue, opcode->opcode.size);
11621136 break;
11631137 }
 1138+ EnterCriticalSection(&This->queuecs);
 1139+ This->queuelength--;
 1140+ This->queue_read += This->queue[This->queue_read + 1];
 1141+ if ((This->queue_read >= This->syncsize) && This->syncsize != 0) SetEvent(This->sync);
11641142 }
 1143+ else EnterCriticalSection(&This->queuecs);
 1144+ if (!This->queuelength)
 1145+ {
 1146+ ResetEvent(This->start);
 1147+ This->queue_read = 0;
 1148+ This->queue_write = 0;
 1149+ This->running = false;
 1150+ SetEvent(This->sync);
 1151+ }
 1152+ LeaveCriticalSection(&This->queuecs);
 1153+ if (!This->dead) goto queueloop;
 1154+ free(This->queue);
 1155+ This->queue = NULL;
11651156 return 0;
11661157 }
11671158
@@ -2163,7 +2154,6 @@
21642155 glRenderer__SetSwap(This,0);
21652156 This->util->SetViewport(0,0,width,height);
21662157 }
2167 - This->setwndfinished = TRUE;
21682158 }
21692159
21702160 void glRenderer__SetBlend(glRenderer *This, DWORD src, DWORD dest)
Index: ddraw/glRenderer.h
@@ -88,32 +88,32 @@
8989 };
9090
9191 #define OP_NULL 0
92 -#define OP_SYNC 1
93 -#define OP_INIT 2
94 -#define OP_SETWND 3
95 -#define OP_DELETE 4
96 -#define OP_CREATE 5
97 -#define OP_UPLOAD 6
98 -#define OP_UPLOADINLINE 7
99 -#define OP_DOWNLOAD 8
100 -#define OP_DELETETEX 9
101 -#define OP_BLT 10
102 -#define OP_DRAWSCREEN 11
103 -#define OP_INITD3D 12
104 -#define OP_CLEAR 13
105 -#define OP_FLUSH 14
106 -#define OP_DRAWPRIMITIVES 15
107 -#define OP_DELETEFBO 16
108 -#define OP_UPDATECLIPPER 17
109 -#define OP_DEPTHFILL 18
110 -#define OP_SETRENDERSTATE 19
111 -#define OP_SETTEXTURE 20
112 -#define OP_SETTEXTURESTAGESTATE 21
113 -#define OP_SETTRANSFORM 22
114 -#define OP_SETMATERIAL 23
115 -#define OP_SETLIGHT 24
116 -#define OP_SETVIEWPORT 25
 92+#define OP_INIT 1
 93+#define OP_SETWND 2
 94+#define OP_DELETE 3
 95+#define OP_CREATE 4
 96+#define OP_UPLOAD 5
 97+#define OP_DOWNLOAD 6
 98+#define OP_DELETETEX 7
 99+#define OP_BLT 8
 100+#define OP_DRAWSCREEN 9
 101+#define OP_INITD3D 10
 102+#define OP_CLEAR 11
 103+#define OP_FLUSH 12
 104+#define OP_DRAWPRIMITIVES 13
 105+#define OP_DELETEFBO 14
 106+#define OP_UPDATECLIPPER 15
 107+#define OP_DEPTHFILL 16
 108+#define OP_SETRENDERSTATE 17
 109+#define OP_SETTEXTURE 18
 110+#define OP_SETTEXTURESTAGESTATE 19
 111+#define OP_SETTRANSFORM 20
 112+#define OP_SETMATERIAL 21
 113+#define OP_SETLIGHT 22
 114+#define OP_SETVIEWPORT 23
117115
 116+#define OP_RESETQUEUE 0xFFFFFFFF
 117+
118118 #ifdef __cplusplus
119119 class glDirectDraw7;
120120 class glDirect3DDevice7;
@@ -126,183 +126,6 @@
127127 typedef int glRenderWindow;
128128 #endif
129129
130 -typedef struct OPCODE
131 -{
132 - DWORD opcode;
133 - DWORD size;
134 -} OPCODE;
135 -typedef struct NULLOP
136 -{
137 - OPCODE opcode;
138 -} NULLOP;
139 -typedef NULLOP SYNCOP;
140 -typedef struct INITOP
141 -{
142 - OPCODE opcode;
143 - DWORD width;
144 - DWORD height;
145 - DWORD bpp;
146 - DWORD fullscreen;
147 - DWORD frequency;
148 - DWORD devwnd;
149 - HWND hwnd;
150 - glDirectDraw7 *glDD7;
151 -} INITOP;
152 -typedef struct SETWNDOP
153 -{
154 - OPCODE opcode;
155 - DWORD width;
156 - DWORD height;
157 - DWORD bpp;
158 - DWORD frequency;
159 - DWORD fullscreen;
160 - BOOL devwnd;
161 - HWND hwnd;
162 -} SETWNDOP;
163 -typedef NULLOP DELETEOP;
164 -typedef struct CREATEOP
165 -{
166 - OPCODE opcode;
167 - DWORD width;
168 - DWORD height;
169 - TEXTURE *texture;
170 -} CREATEOP;
171 -typedef struct UPLOADOP
172 -{
173 - OPCODE opcode;
174 - DWORD width;
175 - DWORD height;
176 - DWORD pitch;
177 - DWORD miplevel;
178 - TEXTURE *texture;
179 -} UPLOADOP;
180 -typedef struct DOWNLOADOP
181 -{
182 - OPCODE opcode;
183 - DWORD miplevel;
184 - BYTE *buffer;
185 - TEXTURE *texture;
186 -} DOWNLOADOP;
187 -typedef struct DELETETEXOP
188 -{
189 - OPCODE opcode;
190 - TEXTURE *texture;
191 -} DELETETEXOP;
192 -typedef struct BLTOP
193 -{
194 - OPCODE opcode;
195 - RECT destrect;
196 - RECT srcrect;
197 - DWORD flags;
198 - DWORD nulls;
199 - DDBLTFX bltfx;
200 - glDirectDrawSurface7 *dest;
201 - glDirectDrawSurface7 *src;
202 -} BLTOP;
203 -typedef struct DRAWSCREENOP
204 -{
205 - OPCODE opcode;
206 - GLint vsync;
207 - glDirectDrawSurface7 *dest;
208 - glDirectDrawSurface7 *src;
209 - TEXTURE *texture;
210 - TEXTURE *paltex;
211 -} DRAWSCREENOP;
212 -typedef struct INITD3DOP
213 -{
214 - OPCODE opcode;
215 - DWORD zbuffer;
216 - DWORD x;
217 - DWORD y;
218 - DWORD padding;
219 -} INITD3DOP;
220 -typedef struct CLEAROP
221 -{
222 - OPCODE opcode;
223 - DWORD count;
224 - DWORD flags;
225 - DWORD color;
226 - D3DVALUE z;
227 - DWORD stencil;
228 - glDirectDrawSurface7 *target;
229 -} CLEAROP;
230 -typedef NULLOP FLUSHOP;
231 -typedef struct DRAWPRIMITIVESOP
232 -{
233 - OPCODE opcode;
234 - GLenum mode;
235 - DWORD stride;
236 - DWORD fvf;
237 - DWORD count;
238 - DWORD indexcount;
239 - DWORD flags;
240 - DWORD vertexoffset;
241 - DWORD indexoffset;
242 - glDirect3DDevice7 *device;
243 -} DRAWPRIMITIVESOP;
244 -typedef struct DELETEFBOOP
245 -{
246 - OPCODE opcode;
247 - FBO *fbo;
248 -} DELETEFBOOP;
249 -typedef struct UPDATECLIPPEROP
250 -{
251 - OPCODE opcode;
252 - glDirectDrawSurface7 *surface;
253 -} UPDATECLIPPEROP;
254 -typedef struct DEPTHFILLOP
255 -{
256 - OPCODE opcode;
257 - BOOL userect;
258 - RECT rect;
259 - DDBLTFX bltfx;
260 - glDirectDrawSurface7 *dest;
261 -} DEPTHFILLOP;
262 -typedef struct SETRENDERSTATEOP
263 -{
264 - OPCODE opcode;
265 - D3DRENDERSTATETYPE state;
266 - DWORD value;
267 -} SETRENDERSTATEOP;
268 -typedef struct SETTEXTUREOP
269 -{
270 - OPCODE opcode;
271 - DWORD stage;
272 - glDirectDrawSurface7 *texture;
273 -} SETTEXTUREOP;
274 -typedef struct SETTEXTURESTAGESTATEOP
275 -{
276 - OPCODE opcode;
277 - DWORD stage;
278 - D3DTEXTURESTAGESTATETYPE state;
279 - DWORD value;
280 - DWORD padding;
281 -} SETTEXTURESTAGESTATEOP;
282 -typedef struct SETTRANSFORMOP
283 -{
284 - OPCODE opcode;
285 - D3DTRANSFORMSTATETYPE state;
286 - DWORD padding;
287 - D3DMATRIX matrix;
288 -} SETTRANSFORMOP;
289 -typedef struct SETMATERIALOP
290 -{
291 - OPCODE opcode;
292 - D3DMATERIAL7 material;
293 -} SETMATERIALOP;
294 -typedef struct SETLIGHTOP
295 -{
296 - OPCODE opcode;
297 - DWORD index;
298 - BOOL remove;
299 - D3DLIGHT7 light;
300 -} SETLIGHTOP;
301 -typedef struct SETVIEWPORTOP
302 -{
303 - OPCODE opcode;
304 - D3DVIEWPORT7 viewport;
305 -} SETVIEWPORTOP;
306 -
307130 extern const DWORD renderstate_default[153];
308131 extern const TEXTURESTAGE texstagedefault0;
309132 extern const TEXTURESTAGE texstagedefault1;
@@ -320,6 +143,8 @@
321144 GLCAPS gl_caps;
322145 glExtensions *ext;
323146 glDirectDraw7 *ddInterface;
 147+ void* inputs[7];
 148+ void *output;
324149 HANDLE hThread;
325150 HDC hDC;
326151 HWND hWnd;
@@ -327,7 +152,6 @@
328153 DIB dib;
329154 FBO fbo;
330155 GLuint PBO;
331 - OPQUEUE queue;
332156 unsigned int frequency;
333157 DXGLTimer timer;
334158 TEXTURE *backbuffer;
@@ -349,17 +173,28 @@
350174 D3DLIGHT7 lights[8];
351175 D3DMATRIX transform[24];
352176 D3DVIEWPORT7 viewport;
353 - BOOL shutdownfinished;
354 - BOOL setwndfinished;
355 - HANDLE syncevent;
 177+ HANDLE busy;
 178+ HANDLE start;
 179+ HANDLE sync;
 180+ BOOL running;
 181+ CRITICAL_SECTION commandcs;
 182+ CRITICAL_SECTION queuecs;
 183+ LPDWORD queue;
 184+ DWORD queuesize;
 185+ DWORD queuelength;
 186+ DWORD queue_read;
 187+ DWORD queue_write;
 188+ DWORD syncsize;
 189+ BOOL dead;
356190 } glRenderer;
357191
358192 void glRenderer_Init(glRenderer *This, DWORD width, DWORD height, DWORD bpp, BOOL fullscreen, DWORD frequency, HWND hwnd, glDirectDraw7 *glDD7, BOOL devwnd);
359193 void glRenderer_Delete(glRenderer *This);
360 -void glRenderer_Sync(glRenderer *This);
 194+int glRenderer_AddQueue(glRenderer *This, DWORD opcode, int mode, DWORD size, int paramcount, ...);
 195+void glRenderer_Sync(glRenderer *This, int size);
361196 void glRenderer_UploadTexture(glRenderer *This, BYTE *buffer, BYTE *bigbuffer, TEXTURE *texture, DWORD x, DWORD y, DWORD bigx, DWORD bigy, DWORD pitch, DWORD bigpitch, DWORD bpp, DWORD miplevel);
362197 void glRenderer_DownloadTexture(glRenderer *This, BYTE *buffer, BYTE *bigbuffer, TEXTURE *texture, DWORD x, DWORD y, DWORD bigx, DWORD bigy, DWORD pitch, DWORD bigpitch, DWORD bpp, DWORD miplevel);
363 -void glRenderer_Blt(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *src,
 198+HRESULT glRenderer_Blt(glRenderer *This, LPRECT lpDestRect, glDirectDrawSurface7 *src,
364199 glDirectDrawSurface7 *dest, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx);
365200 void glRenderer_MakeTexture(glRenderer *This, TEXTURE *texture, DWORD width, DWORD height);
366201 void glRenderer_DrawScreen(glRenderer *This, TEXTURE *texture, TEXTURE *paltex, glDirectDrawSurface7 *dest, glDirectDrawSurface7 *src, GLint vsync);

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r149Beginning of asynchronous operations. Contains some deadlocks and breaks Dir...admin17:47, 28 May 2012