[WINED3D] Move device pointer into the BaseShader class.

Ivan Gyurdiev ivg231 at gmail.com
Wed Sep 27 06:14:46 CDT 2006


Type: Cleanup/Bugfix

Why:
To avoid a runtime crash if the relative position of this field is 
changed in either pixel or vertex shaders.
Shared GLSL code makes unsafe casts trying to get to this field.

-------------- next part --------------
---
 dlls/wined3d/arb_program_shader.c |    7 +++++--
 dlls/wined3d/device.c             |   14 ++++++++++++--
 dlls/wined3d/glsl_shader.c        |   11 ++++++++---
 dlls/wined3d/pixelshader.c        |   10 ++++++----
 dlls/wined3d/vertexshader.c       |   13 ++++++++-----
 dlls/wined3d/wined3d_private.h    |    5 +++--
 6 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 47397d6..7e6231c 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -114,6 +114,7 @@ void shader_arb_load_constants(
         IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
         IWineD3DVertexDeclarationImpl* vertexDeclaration = 
             (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
+        IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) vshader->baseShader.device;
 
         if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
             /* Load DirectX 8 float constants for vertex shader */
@@ -129,7 +130,7 @@ void shader_arb_load_constants(
                                    &stateBlock->set_vconstantsF);
 
         /* Upload the position fixup */
-        GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, ARB_SHADER_PRIVCONST_POS, vshader_impl->wineD3DDevice->posFixup));
+        GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, ARB_SHADER_PRIVCONST_POS, deviceImpl->posFixup));
     }
 
     if (usePixelShader) {
@@ -617,6 +618,8 @@ void pshader_hw_map2gl(SHADER_OPCODE_ARG
 void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
 
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
+    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+
     DWORD dst = arg->dst;
     DWORD* src = arg->src;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -670,7 +673,7 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* a
          tex_type = "2D";
   }
 
-  if(This->wineD3DDevice->stateBlock->textureState[reg_sampler_code][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+  if (deviceImpl->stateBlock->textureState[reg_sampler_code][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
       shader_addline(buffer, "TXP %s, %s, texture[%lu], %s;\n",
           reg_dest, reg_coord, reg_sampler_code, tex_type);
   } else {
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7aef3ac..ff05832 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -95,6 +95,16 @@ #define D3DCREATEOBJECTINSTANCE(object, 
     *pp##type = (IWineD3D##type *) object; \
 }
 
+#define D3DCREATESHADEROBJECTINSTANCE(object, type) { \
+    object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
+    D3DMEMCHECK(object, pp##type); \
+    object->lpVtbl = &IWineD3D##type##_Vtbl;  \
+    object->parent       = parent; \
+    object->ref          = 1; \
+    object->baseShader.device = (IWineD3DDevice*) This; \
+    *pp##type = (IWineD3D##type *) object; \
+}
+
 #define  D3DCREATERESOURCEOBJECTINSTANCE(object, type, d3dtype, _size){ \
     object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
     D3DMEMCHECK(object, pp##type); \
@@ -1934,7 +1944,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
-    D3DCREATEOBJECTINSTANCE(object, VertexShader)
+    D3DCREATESHADEROBJECTINSTANCE(object, VertexShader)
     object->baseShader.shader_ins = IWineD3DVertexShaderImpl_shader_ins;
 
     TRACE("(%p) : Created Vertex shader %p\n", This, *ppVertexShader);
@@ -1979,7 +1989,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
     IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
     HRESULT hr = WINED3D_OK;
 
-    D3DCREATEOBJECTINSTANCE(object, PixelShader)
+    D3DCREATESHADEROBJECTINSTANCE(object, PixelShader)
     object->baseShader.shader_ins = IWineD3DPixelShaderImpl_shader_ins;
     hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction);
     if (WINED3D_OK == hr) {
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 0e48cdb..63d8bfd 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -288,6 +288,7 @@ void shader_glsl_load_constants(
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
         IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) vshader;
+        IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) vshader->baseShader.device;
         GLint pos;
 
         IWineD3DVertexDeclarationImpl* vertexDeclaration =
@@ -319,7 +320,7 @@ void shader_glsl_load_constants(
         /* Upload the position fixup params */
         pos = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup"));
         checkGLcall("glGetUniformLocationARB");
-        GL_EXTCALL(glUniform4fvARB(pos, 1, &vshader_impl->wineD3DDevice->posFixup[0]));
+        GL_EXTCALL(glUniform4fvARB(pos, 1, &deviceImpl->posFixup[0]));
         checkGLcall("glUniform4fvARB");
     }
 
@@ -596,10 +597,12 @@ static void shader_glsl_get_register_nam
     /* oPos, oFog and oPts in D3D */
     const char* hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
 
-    WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)((IWineD3DPixelShaderImpl*)arg->shader)->wineD3DDevice->wineD3D)->gl_info;
     DWORD reg = param & D3DSP_REGNUM_MASK;
     DWORD regtype = shader_get_regtype(param);
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
+    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    WineD3D_GL_Info* gl_info = &((IWineD3DImpl*)deviceImpl->wineD3D)->gl_info;
+
     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
     char tmpStr[50];
 
@@ -1356,6 +1359,8 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG*
     /* FIXME: Make this work for more than just 2D textures */
     
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
+    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD hex_version = This->baseShader.hex_version;
 
@@ -1387,7 +1392,7 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG*
     }         
 
     sampler_type = arg->reg_maps->samplers[sampler_code] & WINED3DSP_TEXTURETYPE_MASK;
-    if(This->wineD3DDevice->stateBlock->textureState[sampler_code][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+    if(deviceImpl->stateBlock->textureState[sampler_code][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
         switch(sampler_type) {
 
             case WINED3DSTT_2D:
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 814c40e..98ec7d7 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -31,7 +31,7 @@ #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 
-#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info
+#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->baseShader.device)->wineD3D))->gl_info
 
 #if 0 /* Must not be 1 in cvs version */
 # define PSTRACE(A) TRACE A
@@ -102,8 +102,8 @@ static HRESULT  WINAPI IWineD3DPixelShad
 
 static HRESULT  WINAPI IWineD3DPixelShaderImpl_GetDevice(IWineD3DPixelShader* iface, IWineD3DDevice **pDevice){
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    IWineD3DDevice_AddRef((IWineD3DDevice *)This->wineD3DDevice);
-    *pDevice = (IWineD3DDevice *)This->wineD3DDevice;
+    IWineD3DDevice_AddRef(This->baseShader.device);
+    *pDevice = This->baseShader.device;
     TRACE("(%p) returning %p\n", This, *pDevice);
     return WINED3D_OK;
 }
@@ -944,7 +944,9 @@ static HRESULT WINAPI IWineD3DPixelShade
 }
 
 static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader *iface) {
+
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
+    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     CONST DWORD *function = This->baseShader.function;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     HRESULT hr;
@@ -963,7 +965,7 @@ static HRESULT WINAPI IWineD3DPixelShade
     /* Second pass: figure out which registers are used, what the semantics are, etc.. */
     memset(reg_maps, 0, sizeof(shader_reg_maps));
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
-                                    This->semantics_in, NULL, This->baseShader.function, This->wineD3DDevice->stateBlock);
+        This->semantics_in, NULL, This->baseShader.function, deviceImpl->stateBlock);
     if (hr != WINED3D_OK) return hr;
     /* FIXME: validate reg_maps against OpenGL */
 
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 2d7ab58..47a8957 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -31,7 +31,7 @@ #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 
-#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info
+#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->baseShader.device)->wineD3D))->gl_info
 
 /* Shader debugging - Change the following line to enable debugging of software
       vertex shaders                                                             */
@@ -659,6 +659,8 @@ BOOL vshader_input_is_color(
     unsigned int regnum) {
 
     IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
+    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+
     DWORD usage_token = This->semantics_in[regnum].usage;
     DWORD usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
     DWORD usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
@@ -669,7 +671,7 @@ BOOL vshader_input_is_color(
         vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->vertexDeclaration;
     } else {
         /* D3D9 declaration */
-        vertexDeclaration = (IWineD3DVertexDeclarationImpl *)((IWineD3DDeviceImpl *)This->wineD3DDevice)->stateBlock->vertexDecl;
+        vertexDeclaration = (IWineD3DVertexDeclarationImpl *) (deviceImpl->stateBlock->vertexDecl);
     }
 
     if (vertexDeclaration) {
@@ -1135,8 +1137,8 @@ static HRESULT WINAPI IWineD3DVertexShad
 
 static HRESULT WINAPI IWineD3DVertexShaderImpl_GetDevice(IWineD3DVertexShader* iface, IWineD3DDevice **pDevice){
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    IWineD3DDevice_AddRef((IWineD3DDevice *)This->wineD3DDevice);
-    *pDevice = (IWineD3DDevice *)This->wineD3DDevice;
+    IWineD3DDevice_AddRef(This->baseShader.device);
+    *pDevice = This->baseShader.device;
     TRACE("(%p) returning %p\n", This, *pDevice);
     return WINED3D_OK;
 }
@@ -1173,6 +1175,7 @@ static HRESULT WINAPI IWineD3DVertexShad
 static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
+    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     HRESULT hr;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
 
@@ -1200,7 +1203,7 @@ static HRESULT WINAPI IWineD3DVertexShad
     /* Second pass: figure out registers used, semantics, etc.. */
     memset(reg_maps, 0, sizeof(shader_reg_maps));
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
-       This->semantics_in, This->semantics_out, pFunction, This->wineD3DDevice->stateBlock);
+       This->semantics_in, This->semantics_out, pFunction, deviceImpl->stateBlock);
     if (hr != WINED3D_OK) return hr;
 
     This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9921d4c..e1598f5 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1587,6 +1587,9 @@ typedef struct IWineD3DBaseShaderClass
     struct list constantsI;
     shader_reg_maps reg_maps;
 
+    /* Pointer to the parent device */
+    IWineD3DDevice *device;
+
 } IWineD3DBaseShaderClass;
 
 typedef struct IWineD3DBaseShaderImpl {
@@ -1689,7 +1692,6 @@ typedef struct IWineD3DVertexShaderImpl 
 
     /* IWineD3DVertexShaderImpl */
     IUnknown                    *parent;
-    IWineD3DDeviceImpl          *wineD3DDevice;
 
     char                        usesFog;
     DWORD                       usage;
@@ -1723,7 +1725,6 @@ typedef struct IWineD3DPixelShaderImpl {
 
     /* IWineD3DPixelShaderImpl */
     IUnknown                   *parent;
-    IWineD3DDeviceImpl         *wineD3DDevice;
 
     /* Pixel shader input semantics */
     semantic semantics_in [MAX_REG_INPUT];
-- 
1.4.2



More information about the wine-patches mailing list