[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