DXGL r678 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r677‎ | r678 | r679 >
Date:15:12, 14 August 2016
Author:admin
Status:new
Tags:
Comment:
Sort and use binary search for shaders; make shader list dynamically sized.
Contains some WIP code for an upcoming update, currently non-functional.
Modified paths:
  • /ddraw/ShaderGen2D.cpp (modified) (history)
  • /ddraw/ShaderGen3D.cpp (modified) (history)
  • /ddraw/ShaderGen3D.h (modified) (history)
  • /ddraw/common.h (modified) (history)
  • /ddraw/ddraw.vcxproj (modified) (history)
  • /ddraw/ddraw.vcxproj.filters (modified) (history)
  • /ddraw/glDirect3DViewport.h (modified) (history)
  • /ddraw/glDirectDrawSurface.cpp (modified) (history)
  • /ddraw/glRenderer.cpp (modified) (history)
  • /ddraw/glRenderer.h (modified) (history)
  • /ddraw/struct.h (modified) (history)
  • /ddraw/struct_command.h (added) (history)

Diff [purge]

Index: ddraw/ShaderGen2D.cpp
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2013 William Feely
 3+// Copyright (C) 2013-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -1024,5 +1024,6 @@
10251025 gen->genshaders2D[index].shader.uniforms[10] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "colorsizesrc");
10261026 gen->genshaders2D[index].shader.uniforms[11] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "colorsizedest");
10271027 gen->genshaders2D[index].shader.uniforms[12] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "fillcolor");
1028 -
 1028+
 1029+ gen->genshaders2D[index].id = id;
10291030 }
\ No newline at end of file
Index: ddraw/ShaderGen3D.cpp
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2012-2015 William Feely
 3+// Copyright (C) 2012-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -133,12 +133,40 @@
134134 }
135135 if(This->genshaders) free(This->genshaders);
136136 This->genshaders = NULL;
137 - This->current_genshader = -1;
 137+ This->current_genshader = NULL;
138138 This->shadercount = 0;
139139 This->genindex = 0;
140140 }
141141
142142 /**
 143+ * Sort 2D shaders callback, for qsort and bsearch functions
 144+ * @param elem1
 145+ * First item to compare
 146+ * @param elem2
 147+ * Second item to compare
 148+ * @return
 149+ * negative if elem1 is less than elem2, positive if greater, zero if same
 150+ */
 151+int __cdecl compshader2D(const GenShader2D *elem1, const GenShader2D *elem2)
 152+{
 153+ return elem1->id - elem2->id;
 154+}
 155+
 156+/**
 157+* Sort 2D shaders callback, for qsort and bsearch functions
 158+* @param elem1
 159+* First item to compare
 160+* @param elem2
 161+* Second item to compare
 162+* @return
 163+* negative if elem1 is less than elem2, positive if greater, zero if same
 164+*/
 165+int __cdecl compshader3D(const GenShader *elem1, const GenShader *elem2)
 166+{
 167+ return memcmp(&elem1->id, &elem2->id, 9 * sizeof(__int64));
 168+}
 169+
 170+/**
143171 * Sets a shader by render state. If the shader does not exist, generates it.
144172 * @param This
145173 * Pointer to ShaderGen3D structure
@@ -156,7 +184,7 @@
157185 */
158186 void ShaderGen3D_SetShader(ShaderGen3D *This, __int64 id, __int64 *texstate, int type, ShaderGen2D *gen2d)
159187 {
160 - int shaderindex = -1;
 188+ //int shaderindex = -1;
161189 switch(type)
162190 {
163191 case 0: // Static built-in shader
@@ -164,24 +192,20 @@
165193 This->ext->glUseProgram(This->shaders->shaders[id].prog);
166194 This->current_shader = This->shaders->shaders[id].prog;
167195 This->current_shadertype = 0;
168 - This->current_genshader = -1;
 196+ This->current_genshader = NULL;
169197 break;
170198 case 1: // 2D generated shader
171199 if ((This->current_shadertype == 1) && (id == This->current_shader)) return;
172200 This->current_shader = id;
173201 This->current_shadertype = 1;
174 - for (int i = 0; i < gen2d->shadercount; i++)
 202+ GenShader2D key2d;
 203+ GenShader2D *shader2d;
 204+ key2d.id = id;
 205+ shader2d = (GenShader2D*)bsearch(&key2d, gen2d->genshaders2D, gen2d->genindex, sizeof(GenShader2D),
 206+ (int(__cdecl *) (const void *, const void *))compshader2D);
 207+ if (!shader2d)
175208 {
176 - if (This->shaders->gen2d->genshaders2D[i].id == id)
177 - {
178 - shaderindex = i;
179 - break;
180 - }
181 - }
182 - if (shaderindex == -1)
183 - {
184209 gen2d->shadercount++;
185 - if (gen2d->shadercount > 256) gen2d->shadercount = 256;
186210 if (gen2d->genshaders2D[gen2d->genindex].shader.prog)
187211 {
188212 This->ext->glUseProgram(0);
@@ -193,14 +217,28 @@
194218 ZeroMemory(&gen2d->genshaders2D[gen2d->genindex], sizeof(GenShader2D));
195219 }
196220 ShaderGen2D_CreateShader2D(gen2d, gen2d->genindex, id);
197 - shaderindex = gen2d->genindex;
198221 gen2d->genindex++;
199 - if (gen2d->genindex >= 256) gen2d->genindex = 0;
 222+ if (gen2d->genindex >= gen2d->maxshaders)
 223+ {
 224+ GenShader2D *tmp2dgen = (GenShader2D*)realloc(gen2d->genshaders2D,
 225+ gen2d->maxshaders * 2 * sizeof(GenShader2D));
 226+ if (!tmp2dgen) gen2d->genindex = 0;
 227+ else
 228+ {
 229+ ZeroMemory(&tmp2dgen[gen2d->maxshaders], gen2d->maxshaders * sizeof(GenShader2D));
 230+ gen2d->genshaders2D = tmp2dgen;
 231+ gen2d->maxshaders *= 2;
 232+ }
 233+ }
 234+ qsort(gen2d->genshaders2D, gen2d->genindex, sizeof(GenShader2D),
 235+ (int(__cdecl *) (const void *, const void *))compshader2D);
 236+ shader2d = (GenShader2D*)bsearch(&key2d, gen2d->genshaders2D, gen2d->genindex, sizeof(GenShader2D),
 237+ (int(__cdecl *) (const void *, const void *))compshader2D);
200238 }
201 - gen2d->genshaders2D[shaderindex].id = id;
202 - This->ext->glUseProgram(gen2d->genshaders2D[shaderindex].shader.prog);
203 - This->current_prog = gen2d->genshaders2D[shaderindex].shader.prog;
204 - This->current_genshader = shaderindex;
 239+ if (!shader2d) return; // Out of memory condition
 240+ This->ext->glUseProgram(shader2d->shader.prog);
 241+ This->current_prog = shader2d->shader.prog;
 242+ This->current_genshader = (GenShader*)shader2d;
205243 break;
206244 case 2: // 3D generated shader
207245 if((This->current_shadertype == 2) && (id == This->current_shader))
@@ -209,20 +247,15 @@
210248 }
211249 This->current_shader = id;
212250 This->current_shadertype = 2;
213 - for(int i = 0; i < This->shadercount; i++)
 251+ GenShader key3d;
 252+ GenShader *shader3d;
 253+ key3d.id = id;
 254+ memcpy(&key3d.texids, texstate, 8 * sizeof(__int64));
 255+ shader3d = (GenShader*)bsearch(&key3d, This->genshaders, This->genindex, sizeof(GenShader),
 256+ (int(__cdecl *) (const void *, const void *))compshader3D);
 257+ if(!shader3d)
214258 {
215 - if(This->genshaders[i].id == id)
216 - {
217 - bool texidmatch = true;
218 - for(int j = 0; j < 8; j++)
219 - if(This->genshaders[i].texids[j] != texstate[j]) texidmatch = false;
220 - if(texidmatch) shaderindex = i;
221 - }
222 - }
223 - if(shaderindex == -1)
224 - {
225259 This->shadercount++;
226 - if(This->shadercount > 256) This->shadercount = 256;
227260 if(This->genshaders[This->genindex].shader.prog)
228261 {
229262 This->ext->glUseProgram(0);
@@ -234,16 +267,28 @@
235268 ZeroMemory(&This->genshaders[This->genindex],sizeof(GenShader));
236269 }
237270 ShaderGen3D_CreateShader(This, This->genindex,id,texstate);
238 - shaderindex = This->genindex;
239271 This->genindex++;
240 - if(This->genindex >= 256) This->genindex = 0;
 272+ if (This->genindex >= This->maxshaders)
 273+ {
 274+ GenShader *tmp3dgen = (GenShader*)realloc(This->genshaders,
 275+ This->maxshaders * 2 * sizeof(GenShader));
 276+ if (!tmp3dgen) This->genindex = 0;
 277+ else
 278+ {
 279+ ZeroMemory(&tmp3dgen[This->maxshaders], This->maxshaders * sizeof(GenShader));
 280+ This->genshaders = tmp3dgen;
 281+ This->maxshaders *= 2;
 282+ }
 283+ }
 284+ qsort(This->genshaders, This->genindex, sizeof(GenShader),
 285+ (int(__cdecl *) (const void *, const void *))compshader3D);
 286+ shader3d = (GenShader*)bsearch(&key3d, This->genshaders, This->genindex, sizeof(GenShader),
 287+ (int(__cdecl *) (const void *, const void *))compshader3D);
241288 }
242 - This->genshaders[shaderindex].id = id;
243 - for(int i = 0; i < 8; i++)
244 - This->genshaders[shaderindex].texids[i] = texstate[i];
245 - This->ext->glUseProgram(This->genshaders[shaderindex].shader.prog);
246 - This->current_prog = This->genshaders[shaderindex].shader.prog;
247 - This->current_genshader = shaderindex;
 289+ if (!shader3d) return; // Out of memory condition
 290+ This->ext->glUseProgram(shader3d->shader.prog);
 291+ This->current_prog = shader3d->shader.prog;
 292+ This->current_genshader = shader3d;
248293 }
249294 }
250295
@@ -1442,6 +1487,10 @@
14431488 unifkeybits[7] = i + '0';
14441489 This->genshaders[index].shader.uniforms[153 + i] = This->ext->glGetUniformLocation(This->genshaders[index].shader.prog, unifkeybits);
14451490 }
 1491+
 1492+ This->genshaders[index].id = id;
 1493+ for (int i = 0; i < 8; i++)
 1494+ This->genshaders[index].texids[i] = texstate[i];
14461495 }
14471496
14481497 }
\ No newline at end of file
Index: ddraw/ShaderGen3D.h
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2012-2015 William Feely
 3+// Copyright (C) 2012-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -48,7 +48,7 @@
4949 typedef struct ShaderGen3D
5050 {
5151 GenShader *genshaders;
52 - int current_genshader;
 52+ GenShader *current_genshader;
5353 __int64 current_shader;
5454 __int64 current_texid[8];
5555 int current_shadertype;
Index: ddraw/common.h
@@ -32,6 +32,7 @@
3333 #include "include/GL/wglext.h"
3434 #include "struct.h"
3535 #include "const.h"
 36+#include "struct_command.h"
3637 #include "glExtensions.h"
3738 #ifdef __cplusplus
3839 #include "string.h"
@@ -90,6 +91,7 @@
9192 #define ERR(error) return error;
9293 #endif
9394
 95+static INLINE int NextMultipleOf1024(int number){return ((number + 1023) & (~1023));}
9496 static INLINE int NextMultipleOf8(int number){return ((number+7) & (~7));}
9597 static INLINE int NextMultipleOf4(int number){return ((number+3) & (~3));}
9698 static INLINE int NextMultipleOf2(int number){return ((number+1) & (~1));}
Index: ddraw/ddraw.vcxproj
@@ -316,6 +316,7 @@
317317 <ClInclude Include="string.h" />
318318 <ClInclude Include="glTexture.h" />
319319 <ClInclude Include="struct.h" />
 320+ <ClInclude Include="struct_command.h" />
320321 <ClInclude Include="timer.h" />
321322 <ClInclude Include="trace.h" />
322323 <ClInclude Include="util.h" />
Index: ddraw/ddraw.vcxproj.filters
@@ -155,6 +155,9 @@
156156 <ClInclude Include="const.h">
157157 <Filter>Header Files</Filter>
158158 </ClInclude>
 159+ <ClInclude Include="struct_command.h">
 160+ <Filter>Header Files</Filter>
 161+ </ClInclude>
159162 </ItemGroup>
160163 <ItemGroup>
161164 <ClCompile Include="ddraw.cpp">
Index: ddraw/glDirect3DViewport.h
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2011-2014 William Feely
 3+// Copyright (C) 2011-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -44,7 +44,7 @@
4545 D3DVIEWPORT2 viewport;
4646 int viewportver;
4747 bool current;
48 -};
 48+} glDirect3DViewport3;
4949
5050 typedef struct glDirect3DViewport3Vtbl
5151 {
@@ -69,7 +69,7 @@
7070 HRESULT(WINAPI *SetBackgroundDepth2)(glDirect3DViewport3 *This, LPDIRECTDRAWSURFACE4 lpDDS);
7171 HRESULT(WINAPI *GetBackgroundDepth2)(glDirect3DViewport3 *This, LPDIRECTDRAWSURFACE4* lplpDDS, LPBOOL lpValid);
7272 HRESULT(WINAPI *Clear2)(glDirect3DViewport3 *This, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil);
73 -};
 73+} glDirect3DViewport3Vtbl;
7474
7575 HRESULT glDirect3DViewport3_Create(LPDIRECT3DVIEWPORT3 *viewport);
7676 void glDirect3DViewport3_SetCurrent(glDirect3DViewport3 *This, bool current);
Index: ddraw/glDirectDrawSurface.cpp
@@ -909,14 +909,6 @@
910910 glTexture **textures = new glTexture*[ddsd.dwBackBufferCount+1];
911911 textures[0] = texture;
912912 tmp = this;
913 - /*if(dirty & 1)
914 - {
915 - glRenderer_UploadTexture(ddInterface->renderer,buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,
916 - fakex,fakey,ddsd.lPitch,(NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*fakex)),
917 - ddsd.ddpfPixelFormat.dwRGBBitCount,miplevel);
918 - dirty &= ~1;
919 - }
920 - this->dirty |= 2;*/
921913 for(i = 0; i < ddsd.dwBackBufferCount; i++)
922914 {
923915 tmp = tmp->GetBackbuffer();
Index: ddraw/glRenderer.cpp
@@ -93,6 +93,182 @@
9494 }
9595
9696 /**
 97+ * Checks the command buffer and flips it if too full.
 98+ * @param This
 99+ * Pointer to glRenderer object
 100+ * @param cmdsize
 101+ * Requested size for command buffer
 102+ */
 103+void CheckCmdBuffer(glRenderer *This, DWORD cmdsize, DWORD uploadsize, DWORD vertexsize, DWORD indexsize)
 104+{
 105+ BOOL over = FALSE;
 106+ if (cmdsize)
 107+ {
 108+ if ((This->state.cmd->write_ptr_cmd + cmdsize) > This->state.cmd->cmdsize)
 109+ over = TRUE;
 110+ }
 111+ if (uploadsize)
 112+ {
 113+ if ((This->state.cmd->write_ptr_upload + uploadsize) > This->state.cmd->uploadsize)
 114+ over = TRUE;
 115+ }
 116+ if (vertexsize)
 117+ {
 118+ if ((This->state.cmd->write_ptr_vertex + vertexsize) > This->state.cmd->vertices->size)
 119+ over = TRUE;
 120+ }
 121+ if (indexsize)
 122+ {
 123+ if ((This->state.cmd->write_ptr_index + indexsize) > This->state.cmd->indices->size)
 124+ over = TRUE;
 125+ }
 126+ if (over) glRenderer_EndCommand(This, FALSE, TRUE);
 127+}
 128+
 129+/**
 130+ * Adds a command to the active command buffer.
 131+ * @param This
 132+ * Pointer to glRenderer object
 133+ * @param command
 134+ * Formatted command to add to buffer.
 135+ * Command format:
 136+ * First DWORD: Command ID, see glRenderer.h
 137+ * Second DWORD: Size of command data, rounded up to nearest DWORD
 138+ * Third DWORD and beyond: command data
 139+ * @return
 140+ * Return value specific to command, DD_OK if succeeded.
 141+ */
 142+HRESULT glRenderer_AddCommand(glRenderer *This, BYTE *command)
 143+{
 144+ DWORD opcode = (DWORD)*command;
 145+ DWORD cmdsize = (DWORD)*((unsigned char*)command + 4);
 146+ BYTE *cmddata = command + 8;
 147+ SetWndCommand *wndcmd = (SetWndCommand*)cmddata;
 148+ HRESULT error;
 149+ // Command specific variables
 150+ RECT wndrect;
 151+ int screenx, screeny;
 152+ LONG_PTR winstyle, winstyleex;
 153+ EnterCriticalSection(&This->cs);
 154+ switch (opcode)
 155+ {
 156+ case OP_NULL:
 157+ error = DD_OK; // No need to write to the command buffer
 158+ break;
 159+ case OP_SETWND: // Should be invoked from glRenderer_SetWnd which flushes the
 160+ // command buffer then executes the command on its own.
 161+ error = DDERR_UNSUPPORTED;
 162+ break;
 163+ case OP_DELETE: // Should be executed by itself, flushes command buffer then
 164+ // destroys glRenderer object.
 165+ error = DDERR_UNSUPPORTED;
 166+ break;
 167+ case OP_CREATE: // Creates a texture. Needs to sync in order to return the
 168+ // texture object.
 169+ CheckCmdBuffer(This, cmdsize + 8, 0, 0, 0);
 170+ memcpy(This->state.cmd->cmdbuffer + This->state.cmd->write_ptr_cmd, command, cmdsize + 8);
 171+ This->state.cmd->write_ptr_cmd += (cmdsize + 8);
 172+ error = DD_OK;
 173+ break;
 174+ case OP_UPLOAD: // This one can fill the upload buffer fast; upload buffer is
 175+ // initialized to 2x primary for <=128MB, 1.5x for <=256MB, or
 176+ // 1.25x for >256MB upload buffer size.
 177+ ((UploadTextureCmd*)command)->texturesize =
 178+ ((UploadTextureCmd*)command)->texture->levels[((UploadTextureCmd*)command)->level].ddsd.lPitch
 179+ * ((UploadTextureCmd*)command)->texture->levels[((UploadTextureCmd*)command)->level].ddsd.dwHeight;
 180+ ((UploadTextureCmd*)command)->content =
 181+ (BYTE*)((UploadTextureCmd*)command)->texture->levels[((UploadTextureCmd*)command)->level].buffer;
 182+ ((UploadTextureCmd*)command)->offset = This->state.cmd->write_ptr_upload;
 183+ CheckCmdBuffer(This, cmdsize + 8, 0, 0, 0);
 184+ memcpy(This->state.cmd->cmdbuffer + This->state.cmd->write_ptr_cmd, command, cmdsize + 8);
 185+ This->state.cmd->write_ptr_cmd += (cmdsize + 8);
 186+ memcpy(This->state.cmd->uploadbuffer + This->state.cmd->write_ptr_upload,
 187+ ((UploadTextureCmd*)command)->content, ((UploadTextureCmd*)command)->texturesize);
 188+ error = DD_OK;
 189+ break;
 190+ case OP_DOWNLOAD: // Downloads a texture. Needs to sync in order to receive the
 191+ // texture data.
 192+ CheckCmdBuffer(This, cmdsize + 8, 0, 0, 0);
 193+ memcpy(This->state.cmd->cmdbuffer + This->state.cmd->write_ptr_cmd, command, cmdsize + 8);
 194+ This->state.cmd->write_ptr_cmd += (cmdsize + 8);
 195+ error = DD_OK;
 196+ break;
 197+ case OP_DELETETEX: // Deletes a texture. Non-blocking becuase frontend has
 198+ // forgotten the texture.
 199+ CheckCmdBuffer(This, cmdsize + 8, 0, 0, 0);
 200+ memcpy(This->state.cmd->cmdbuffer + This->state.cmd->write_ptr_cmd, command, cmdsize + 8);
 201+ This->state.cmd->write_ptr_cmd += (cmdsize + 8);
 202+ error = DD_OK;
 203+ break;
 204+ case OP_BLT: // Perform a Blt() operation, issuing necessary commands to set it
 205+ // up.
 206+ error = DDERR_CURRENTLYNOTAVAIL;
 207+ break;
 208+ case OP_DRAWSCREEN: // Draws the screen. Flip command buffer after executing.
 209+ error = DDERR_UNSUPPORTED;
 210+ break;
 211+ case OP_INITD3D: // Initialize renderer for Direct3D rendering.
 212+ error = DDERR_CURRENTLYNOTAVAIL;
 213+ break;
 214+ case OP_CLEAR: // Clears full renderbuffer or one or more rects.
 215+ // Size should hold number of rects plus each rect, or 0 for screen.
 216+ error = DDERR_CURRENTLYNOTAVAIL;
 217+ break;
 218+ case OP_FLUSH: // Probably should consider retiring this one. Flip buffers if called.
 219+ error = DDERR_CURRENTLYNOTAVAIL;
 220+ break;
 221+ case OP_DRAWPRIMITIVES: // Add primitives to the render buffer, check and adjust buffer
 222+ // state.
 223+ error = DDERR_CURRENTLYNOTAVAIL;
 224+ break;
 225+ case OP_UPDATECLIPPER: // Add pre-processed vertices to update the clipper.
 226+ error = DDERR_CURRENTLYNOTAVAIL;
 227+ break;
 228+ case OP_DEPTHFILL: // Performs a depth fill on a depth surface, using a BltCommand structure.
 229+ error = DDERR_CURRENTLYNOTAVAIL;
 230+ break;
 231+ case OP_SETRENDERSTATE: // Sets a Direct3D Render State.
 232+ error = DDERR_CURRENTLYNOTAVAIL;
 233+ break;
 234+ case OP_SETTEXTURE: // Binds a texture object to a Direct3D texture stage.
 235+ error = DDERR_CURRENTLYNOTAVAIL;
 236+ break;
 237+ case OP_SETTEXTURESTAGESTATE: // Sets a state object for a Direct3D texture stage.
 238+ error = DDERR_CURRENTLYNOTAVAIL;
 239+ break;
 240+ case OP_SETTRANSFORM: // Sets one of the Direct3D fixed-function matrices.
 241+ error = DDERR_CURRENTLYNOTAVAIL;
 242+ break;
 243+ case OP_SETMATERIAL: // Sets the Direct3D fixed-function material.
 244+ error = DDERR_CURRENTLYNOTAVAIL;
 245+ break;
 246+ case OP_SETLIGHT: // Sets one of the Direct3D fixed-function light states.
 247+ error = DDERR_CURRENTLYNOTAVAIL;
 248+ break;
 249+ case OP_SETVIEWPORT: // Sets the Direct3D viewport. May be
 250+ error = DDERR_CURRENTLYNOTAVAIL;
 251+ break;
 252+ case OP_SETTEXTURECOLORKEY: // Sets a color key or colorkey range on a texture object.
 253+ error = DDERR_CURRENTLYNOTAVAIL;
 254+ break;
 255+ case OP_MAKETEXTUREPRIMARY: // Sets or removes primary scaling on a z-buffer.
 256+ error = DDERR_CURRENTLYNOTAVAIL;
 257+ break;
 258+ case OP_DXGLBREAK: // Breakpoint command, flip buffers and wait or just add to command stream?
 259+ error = DDERR_CURRENTLYNOTAVAIL;
 260+ break;
 261+ case OP_SETMODE2D: // Set up renderer for 2D DirectDraw commands.
 262+ error = DDERR_CURRENTLYNOTAVAIL;
 263+ break;
 264+ default:
 265+ error = DDERR_INVALIDPARAMS;
 266+ break;
 267+ }
 268+ LeaveCriticalSection(&This->cs);
 269+ return error;
 270+}
 271+
 272+/**
97273 * Sets the Windows OpenGL swap interval
98274 * @param This
99275 * Pointer to glRenderer object
@@ -274,6 +450,12 @@
275451 */
276452 void glRenderer_MakeTexture(glRenderer *This, glTexture *texture)
277453 {
 454+ /*MakeTextureCmd cmd;
 455+ cmd.opcode = OP_CREATE;
 456+ cmd.size = sizeof(glTexture*);
 457+ cmd.texture = texture;
 458+ glRenderer_AddCommand(This, (BYTE*)&cmd);
 459+ glRenderer_EndCommand(This, TRUE, FALSE);*/
278460 EnterCriticalSection(&This->cs);
279461 This->inputs[0] = texture;
280462 This->opcode = OP_CREATE;
@@ -293,6 +475,12 @@
294476 */
295477 void glRenderer_UploadTexture(glRenderer *This, glTexture *texture, GLint level)
296478 {
 479+ /*UploadTextureCmd cmd;
 480+ cmd.opcode = OP_UPLOAD;
 481+ cmd.size = sizeof(UploadTextureCmd) - 8;
 482+ cmd.texture = texture;
 483+ cmd.level = level;
 484+ glRenderer_AddCommand(This, (BYTE*)&cmd);*/
297485 EnterCriticalSection(&This->cs);
298486 This->inputs[0] = texture;
299487 This->inputs[1] = (void*)level;
@@ -313,6 +501,13 @@
314502 */
315503 void glRenderer_DownloadTexture(glRenderer *This, glTexture *texture, GLint level)
316504 {
 505+ /*DownloadTextureCmd cmd;
 506+ cmd.opcode = OP_DOWNLOAD;
 507+ cmd.size = sizeof(DownloadTextureCmd) - 8;
 508+ cmd.texture = texture;
 509+ cmd.level = level;
 510+ glRenderer_AddCommand(This, (BYTE*)&cmd);
 511+ glRenderer_EndCommand(This, TRUE, FALSE);*/
317512 EnterCriticalSection(&This->cs);
318513 This->inputs[0] = texture;
319514 This->inputs[1] = (void*)level;
@@ -331,6 +526,11 @@
332527 */
333528 void glRenderer_DeleteTexture(glRenderer *This, glTexture * texture)
334529 {
 530+ /*DeleteTextureCmd cmd;
 531+ cmd.opcode = OP_DELETE;
 532+ cmd.size = sizeof(glTexture*);
 533+ cmd.texture = texture;
 534+ glRenderer_AddCommand(This, (BYTE*)&cmd);*/
335535 EnterCriticalSection(&This->cs);
336536 This->inputs[0] = texture;
337537 This->opcode = OP_DELETETEX;
@@ -582,23 +782,6 @@
583783 }
584784
585785 /**
586 - * Deletes a framebuffer object.
587 - * @param This
588 - * Pointer to glRenderer object
589 - * @param fbo
590 - * FBO Structure containing framebuffer to delete
591 - */
592 -void glRenderer_DeleteFBO(glRenderer *This, FBO *fbo)
593 -{
594 - EnterCriticalSection(&This->cs);
595 - This->inputs[0] = fbo;
596 - This->opcode = OP_DELETEFBO;
597 - SetEvent(This->start);
598 - WaitForSingleObject(This->busy,INFINITE);
599 - LeaveCriticalSection(&This->cs);
600 -}
601 -
602 -/**
603786 * Updates a clipping stencil.
604787 * @param This
605788 * Pointer to glRenderer object
@@ -876,6 +1059,26 @@
8771060 }
8781061
8791062 /**
 1063+ * Ends a command buffer.
 1064+ * @param This
 1065+ * Pointer to glRenderer object
 1066+ * @param wait
 1067+ * TRUE to wait for the command buffer to complete
 1068+ * @param in_cs
 1069+ * If TRUE, do not take the Crtitical Section because it is already taken
 1070+ */
 1071+void glRenderer_EndCommand(glRenderer *This, BOOL wait, BOOL in_cs)
 1072+{
 1073+ if (!in_cs) EnterCriticalSection(&This->cs);
 1074+ if (!This->state.cmd->write_ptr_cmd) return; // Don't flip buffers if the front one is empty.
 1075+ This->opcode = OP_ENDCOMMAND;
 1076+ This->inputs[0] = (void*)wait;
 1077+ SetEvent(This->start);
 1078+ WaitForSingleObject(This->busy, INFINITE);
 1079+ if (!in_cs) LeaveCriticalSection(&This->cs);
 1080+}
 1081+
 1082+/**
8801083 * Main loop for glRenderer class
8811084 * @param This
8821085 * Pointer to glRenderer object
@@ -918,6 +1121,8 @@
9191122 This->backx = 0;
9201123 This->backy = 0;
9211124 }
 1125+ glRenderer__DeleteCommandBuffer(&This->cmd1);
 1126+ glRenderer__DeleteCommandBuffer(&This->cmd2);
9221127 ShaderManager_Delete(This->shaders);
9231128 glUtil_Release(This->util);
9241129 free(This->shaders);
@@ -976,9 +1181,6 @@
9771182 (GLVERTEX*)This->inputs[2],(int*)This->inputs[3],(DWORD)This->inputs[4],(LPWORD)This->inputs[5],
9781183 (DWORD)This->inputs[6],(DWORD)This->inputs[7]);
9791184 break;
980 - case OP_DELETEFBO:
981 - glRenderer__DeleteFBO(This,(FBO*)This->inputs[0]);
982 - break;
9831185 case OP_UPDATECLIPPER:
9841186 glRenderer__UpdateClipper(This,(glTexture*)This->inputs[0], (GLushort*)This->inputs[1],
9851187 (BltVertex*)This->inputs[2], (GLsizei)This->inputs[3], (GLsizei)This->inputs[4], (GLsizei)This->inputs[5]);
@@ -1018,6 +1220,9 @@
10191221 case OP_DXGLBREAK:
10201222 glRenderer__DXGLBreak(This);
10211223 break;
 1224+ case OP_ENDCOMMAND:
 1225+ glRenderer__EndCommand(This, (BOOL)This->inputs[0]);
 1226+ break;
10221227 }
10231228 }
10241229 return 0;
@@ -1171,10 +1376,42 @@
11721377 }
11731378 BufferObject_Create(&This->pbo, This->ext, This->util);
11741379 BufferObject_SetData(This->pbo, GL_PIXEL_PACK_BUFFER, width*height * 4, NULL, GL_STREAM_READ);
 1380+ ZeroMemory(&This->state, sizeof(RenderState));
 1381+ This->state.cmd = &This->cmd1;
 1382+ glRenderer__InitCommandBuffer(This, &This->cmd1, width * height * (NextMultipleOf8(bpp) / 8));
 1383+ glRenderer__InitCommandBuffer(This, &This->cmd2, width * height * (NextMultipleOf8(bpp) / 8));
 1384+ BufferObject_Map(This->cmd1.vertices, GL_ARRAY_BUFFER, GL_WRITE_ONLY);
 1385+ BufferObject_Map(This->cmd1.indices, GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
11751386 TRACE_SYSINFO();
11761387 return TRUE;
11771388 }
11781389
 1390+void glRenderer__InitCommandBuffer(glRenderer *This, CommandBuffer *cmd, size_t framesize)
 1391+{
 1392+ size_t uploadsize = NextMultipleOf1024(framesize * 2);
 1393+ if (uploadsize > 134217728) // Over 4K resolution
 1394+ uploadsize = NextMultipleOf1024((int)((float)framesize * 1.5f));
 1395+ if (uploadsize > 268435456) // Over 8K resolution
 1396+ uploadsize = NextMultipleOf1024((int)((float)framesize * 1.5f));
 1397+ ZeroMemory(cmd, sizeof(CommandBuffer));
 1398+ cmd->uploadsize = uploadsize;
 1399+ cmd->uploadbuffer = (unsigned char *)malloc(uploadsize);
 1400+ cmd->cmdsize = 1048576;
 1401+ cmd->cmdbuffer = (unsigned char *)malloc(cmd->cmdsize);
 1402+ BufferObject_Create(&cmd->vertices, This->ext, This->util);
 1403+ BufferObject_SetData(cmd->vertices, GL_ARRAY_BUFFER, 4194304, NULL, GL_DYNAMIC_DRAW);
 1404+ BufferObject_Create(&cmd->indices, This->ext, This->util);
 1405+ BufferObject_SetData(cmd->vertices, GL_ELEMENT_ARRAY_BUFFER, 262144, NULL, GL_DYNAMIC_DRAW);
 1406+}
 1407+
 1408+void glRenderer__DeleteCommandBuffer(CommandBuffer *cmd)
 1409+{
 1410+ if (cmd->uploadbuffer) free(cmd->uploadbuffer);
 1411+ if (cmd->cmdbuffer) free(cmd->cmdbuffer);
 1412+ if (cmd->vertices) BufferObject_Release(cmd->vertices);
 1413+ if (cmd->indices) BufferObject_Release(cmd->indices);
 1414+}
 1415+
11791416 void SetColorFillUniform(DWORD color, DWORD *colorsizes, int colororder, DWORD *colorbits, GLint uniform, glExtensions *ext)
11801417 {
11811418 DWORD r, g, b, a;
@@ -1406,7 +1643,7 @@
14071644 This->bltvertices[2].destt = This->bltvertices[3].destt = 1.0-((GLfloat)(destrect.bottom - destrect.top) / (GLfloat)This->backy);
14081645 }
14091646 ShaderManager_SetShader(This->shaders, shaderid, NULL, 1);
1410 - GenShader2D *shader = &This->shaders->gen2d->genshaders2D[This->shaders->gen3d->current_genshader];
 1647+ GenShader2D *shader = (GenShader2D*)This->shaders->gen3d->current_genshader;
14111648 glUtil_BlendEnable(This->util, FALSE);
14121649 do
14131650 {
@@ -2216,7 +2453,7 @@
22172454 else glUtil_DepthTest(This->util, FALSE);
22182455 if (This->renderstate[D3DRENDERSTATE_ZWRITEENABLE]) glUtil_DepthWrite(This->util, TRUE);
22192456 else glUtil_DepthWrite(This->util, FALSE);
2220 - _GENSHADER *prog = &This->shaders->gen3d->genshaders[This->shaders->gen3d->current_genshader].shader;
 2457+ _GENSHADER *prog = &This->shaders->gen3d->current_genshader->shader;
22212458 glUtil_EnableArray(This->util, prog->attribs[0], TRUE);
22222459 This->ext->glVertexAttribPointer(prog->attribs[0],3,GL_FLOAT,GL_FALSE,vertices[0].stride,vertices[0].data);
22232460 if(transformed)
@@ -3013,4 +3250,12 @@
30143251 SetEvent(This->busy);
30153252 }
30163253
 3254+void glRenderer__EndCommand(glRenderer *This, BOOL wait)
 3255+{
 3256+ // Do set-up and flip here
 3257+ if (!wait) SetEvent(This->busy);
 3258+ // Do command execution here
 3259+ if (wait) SetEvent(This->busy);
 3260+}
 3261+
30173262 }
\ No newline at end of file
Index: ddraw/glRenderer.h
@@ -96,19 +96,20 @@
9797 #define OP_CLEAR 10
9898 #define OP_FLUSH 11
9999 #define OP_DRAWPRIMITIVES 12
100 -#define OP_DELETEFBO 13
101 -#define OP_UPDATECLIPPER 14
102 -#define OP_DEPTHFILL 15
103 -#define OP_SETRENDERSTATE 16
104 -#define OP_SETTEXTURE 17
105 -#define OP_SETTEXTURESTAGESTATE 18
106 -#define OP_SETTRANSFORM 19
107 -#define OP_SETMATERIAL 20
108 -#define OP_SETLIGHT 21
109 -#define OP_SETVIEWPORT 22
110 -#define OP_DXGLBREAK 23
111 -#define OP_SETTEXTURECOLORKEY 24
112 -#define OP_MAKETEXTUREPRIMARY 25
 100+#define OP_UPDATECLIPPER 13
 101+#define OP_DEPTHFILL 14
 102+#define OP_SETRENDERSTATE 15
 103+#define OP_SETTEXTURE 16
 104+#define OP_SETTEXTURESTAGESTATE 17
 105+#define OP_SETTRANSFORM 18
 106+#define OP_SETMATERIAL 19
 107+#define OP_SETLIGHT 20
 108+#define OP_SETVIEWPORT 21
 109+#define OP_DXGLBREAK 22
 110+#define OP_SETTEXTURECOLORKEY 23
 111+#define OP_MAKETEXTUREPRIMARY 24
 112+#define OP_ENDCOMMAND 25
 113+#define OP_SETMODE2D 26
113114
114115 extern const DWORD renderstate_default[153];
115116 extern const TEXTURESTAGE texstagedefault0;
@@ -156,8 +157,12 @@
157158 D3DLIGHT7 lights[8];
158159 D3DMATRIX transform[24];
159160 D3DVIEWPORT7 viewport;
 161+ CommandBuffer cmd1, cmd2;
 162+ RenderState state;
 163+ size_t scenesize, scenesizevertex, scenesizeindex;
160164 } glRenderer;
161165
 166+HRESULT glRenderer_AddCommand(glRenderer *This, BYTE *command);
162167 void glRenderer_Init(glRenderer *This, int width, int height, int bpp, BOOL fullscreen, unsigned int frequency, HWND hwnd, glDirectDraw7 *glDD7, BOOL devwnd);
163168 void glRenderer_Delete(glRenderer *This);
164169 DWORD glRenderer_GetBPP(glRenderer *This);
@@ -174,7 +179,7 @@
175180 HRESULT glRenderer_Clear(glRenderer *This, ClearCommand *cmd);
176181 HRESULT glRenderer_DrawPrimitives(glRenderer *This, glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texformats, DWORD count, LPWORD indices,
177182 DWORD indexcount, DWORD flags);
178 -void glRenderer_DeleteFBO(glRenderer *This, FBO *fbo);
 183+//void glRenderer_UpdateClipper(glRenderer *This, glTexture *stencil, GLushort *indices, BltVertex *vertices,
179184 void glRenderer_UpdateClipper(glRenderer *This, glTexture *stencil, GLushort *indices, BltVertex *vertices,
180185 GLsizei count, GLsizei width, GLsizei height);
181186 unsigned int glRenderer_GetScanLine(glRenderer *This);
@@ -189,9 +194,12 @@
190195 void glRenderer_SetTextureColorKey(glRenderer *This, glTexture *texture, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey, GLint level);
191196 void glRenderer_MakeTexturePrimary(glRenderer *This, glTexture *texture, glTexture *parent, BOOL primary);
192197 void glRenderer_DXGLBreak(glRenderer *This);
 198+void glRenderer_EndCommand(glRenderer *This, BOOL wait, BOOL in_cs);
193199 // In-thread APIs
194200 DWORD glRenderer__Entry(glRenderer *This);
195201 BOOL glRenderer__InitGL(glRenderer *This, int width, int height, int bpp, int fullscreen, unsigned int frequency, HWND hWnd, glDirectDraw7 *glDD7);
 202+void glRenderer__InitCommandBuffer(glRenderer *This, CommandBuffer *cmd, size_t framesize);
 203+void glRenderer__DeleteCommandBuffer(CommandBuffer *cmd);
196204 void glRenderer__UploadTexture(glRenderer *This, glTexture *texture, GLint level);
197205 void glRenderer__DownloadTexture(glRenderer *This, glTexture *texture, GLint level);
198206 void glRenderer__Blt(glRenderer *This, BltCommand *cmd);
@@ -228,6 +236,7 @@
229237 void glRenderer__MakeTexturePrimary(glRenderer *This, glTexture *texture, glTexture *parent, BOOL primary);
230238 void glRenderer__SetDepthComp(glRenderer *This);
231239 void glRenderer__DXGLBreak(glRenderer *This);
 240+void glRenderer__EndCommand(glRenderer *This, BOOL wait);
232241
233242 #ifdef __cplusplus
234243 }
Index: ddraw/struct.h
@@ -352,6 +352,17 @@
353353 glExtensions *ext;
354354 } ShaderManager;
355355
 356+typedef struct SetWndCommand
 357+{
 358+ int width;
 359+ int height;
 360+ int bpp;
 361+ int fullscreen;
 362+ unsigned int frequency;
 363+ HWND newwnd;
 364+ BOOL devwnd;
 365+} SetWndCommand;
 366+
356367 typedef struct BltCommand
357368 {
358369 //DWORD opcode;
@@ -418,4 +429,27 @@
419430 HRESULT(WINAPI *SetEntries)(glDirectDrawPalette *This, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries);
420431 } glDirectDrawPaletteVtbl;
421432
 433+typedef struct CommandBuffer
 434+{
 435+ BYTE *cmdbuffer;
 436+ size_t cmdsize;
 437+ BYTE *uploadbuffer;
 438+ size_t uploadsize;
 439+ BufferObject *vertices;
 440+ BufferObject *indices;
 441+ size_t write_ptr_cmd;
 442+ size_t read_ptr_cmd;
 443+ size_t write_ptr_upload;
 444+ size_t read_ptr_upload;
 445+ size_t write_ptr_vertex;
 446+ size_t read_ptr_vertex;
 447+ size_t write_ptr_index;
 448+ size_t read_ptr_index;
 449+} CommandBuffer;
 450+
 451+typedef struct RenderState
 452+{
 453+ CommandBuffer *cmd;
 454+} RenderState;
 455+
422456 #endif //__STRUCT_H
\ No newline at end of file
Index: ddraw/struct_command.h
@@ -0,0 +1,57 @@
 2+// DXGL
 3+// Copyright (C) 2016 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 __STRUCT_COMMAND_H
 21+#define __STRUCT_COMMAND_H
 22+
 23+typedef struct MakeTextureCmd
 24+{
 25+ DWORD opcode;
 26+ DWORD size;
 27+ glTexture *texture;
 28+} MakeTextureCmd;
 29+typedef struct UploadTextureCmd
 30+{
 31+ DWORD opcode;
 32+ DWORD size;
 33+ glTexture *texture;
 34+ GLint level;
 35+ DWORD texturesize;
 36+ BYTE *content;
 37+ DWORD offset;
 38+} UploadTextureCmd;
 39+typedef struct DownloadTextureCmd
 40+{
 41+ DWORD opcode;
 42+ DWORD size;
 43+ glTexture *texture;
 44+ GLint level;
 45+} DownloadTextureCmd;
 46+typedef struct DeleteTextureCmd
 47+{
 48+ DWORD opcode;
 49+ DWORD size;
 50+ glTexture *texture;
 51+} DeleteTextureCmd;
 52+typedef struct BltCmd // Frontend command structure for Blt command.
 53+{
 54+ DWORD opcode;
 55+ DWORD size;
 56+ BltCommand cmd;
 57+} BltCmd;
 58+#endif //__STRUCT_COMMAND_H
\ No newline at end of file