Update wine d3d8 and wined3d to wine release version 0.9.49

svn path=/trunk/; revision=30393
This commit is contained in:
Magnus Olsen 2007-11-12 14:56:05 +00:00
parent 736f7a1dc9
commit 45455f92aa
30 changed files with 5688 additions and 3462 deletions

View file

@ -25,6 +25,7 @@ C_SRCS = \
resource.c \ resource.c \
state.c \ state.c \
stateblock.c \ stateblock.c \
surface_base.c \
surface.c \ surface.c \
surface_gdi.c \ surface_gdi.c \
swapchain.c \ swapchain.c \

File diff suppressed because it is too large Load diff

View file

@ -193,11 +193,13 @@ HRESULT shader_get_registers_used(
IWineD3DStateBlockImpl *stateBlock) { IWineD3DStateBlockImpl *stateBlock) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
/* There are some minor differences between pixel and vertex shaders */ /* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version); char pshader = shader_is_pshader_version(This->baseShader.hex_version);
reg_maps->bumpmat = -1; reg_maps->bumpmat = -1;
reg_maps->luminanceparams = -1;
if (pToken == NULL) if (pToken == NULL)
return WINED3D_OK; return WINED3D_OK;
@ -266,6 +268,20 @@ HRESULT shader_get_registers_used(
if (!lconst) return E_OUTOFMEMORY; if (!lconst) return E_OUTOFMEMORY;
lconst->idx = *pToken & WINED3DSP_REGNUM_MASK; lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
memcpy(&lconst->value, pToken + 1, 4 * sizeof(DWORD)); memcpy(&lconst->value, pToken + 1, 4 * sizeof(DWORD));
/* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && pshader) {
float *value = (float *) lconst->value;
if(value[0] < -1.0) value[0] = -1.0;
else if(value[0] > 1.0) value[0] = 1.0;
if(value[1] < -1.0) value[1] = -1.0;
else if(value[1] > 1.0) value[1] = 1.0;
if(value[2] < -1.0) value[2] = -1.0;
else if(value[2] > 1.0) value[2] = 1.0;
if(value[3] < -1.0) value[3] = -1.0;
else if(value[3] > 1.0) value[3] = 1.0;
}
list_add_head(&This->baseShader.constantsF, &lconst->entry); list_add_head(&This->baseShader.constantsF, &lconst->entry);
pToken += curOpcode->num_params; pToken += curOpcode->num_params;
@ -290,9 +306,15 @@ HRESULT shader_get_registers_used(
/* If there's a loop in the shader */ /* If there's a loop in the shader */
} else if (WINED3DSIO_LOOP == curOpcode->opcode || } else if (WINED3DSIO_LOOP == curOpcode->opcode ||
WINED3DSIO_REP == curOpcode->opcode) { WINED3DSIO_REP == curOpcode->opcode) {
reg_maps->loop = 1; cur_loop_depth++;
if(cur_loop_depth > max_loop_depth)
max_loop_depth = cur_loop_depth;
pToken += curOpcode->num_params; pToken += curOpcode->num_params;
} else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
WINED3DSIO_ENDREP == curOpcode->opcode) {
cur_loop_depth--;
/* For subroutine prototypes */ /* For subroutine prototypes */
} else if (WINED3DSIO_LABEL == curOpcode->opcode) { } else if (WINED3DSIO_LABEL == curOpcode->opcode) {
@ -300,14 +322,6 @@ HRESULT shader_get_registers_used(
reg_maps->labels[snum] = 1; reg_maps->labels[snum] = 1;
pToken += curOpcode->num_params; pToken += curOpcode->num_params;
} else if(WINED3DSIO_BEM == curOpcode->opcode) {
DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != regnum) {
FIXME("Pixel shader uses bem or texbem instruction on more than 1 sampler\n");
} else {
reg_maps->bumpmat = regnum;
}
/* Set texture, address, temporary registers */ /* Set texture, address, temporary registers */
} else { } else {
int i, limit; int i, limit;
@ -354,14 +368,30 @@ HRESULT shader_get_registers_used(
} }
/* texbem is only valid with < 1.4 pixel shaders */ /* texbem is only valid with < 1.4 pixel shaders */
if(WINED3DSIO_TEXBEM == curOpcode->opcode) { if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
WINED3DSIO_TEXBEML == curOpcode->opcode) {
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != sampler_code) { if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != sampler_code) {
FIXME("Pixel shader uses texbem instruction on more than 1 sampler\n"); FIXME("Pixel shader uses texbem instruction on more than 1 sampler\n");
} else { } else {
reg_maps->bumpmat = sampler_code; reg_maps->bumpmat = sampler_code;
if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
reg_maps->luminanceparams = sampler_code;
}
} }
} }
} }
if(WINED3DSIO_NRM == curOpcode->opcode) {
reg_maps->usesnrm = 1;
} else if(WINED3DSIO_BEM == curOpcode->opcode) {
DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != regnum) {
FIXME("Pixel shader uses bem or texbem instruction on more than 1 sampler\n");
} else {
reg_maps->bumpmat = regnum;
}
} else if(WINED3DSIO_DSY == curOpcode->opcode) {
reg_maps->usesdsy = 1;
}
/* This will loop over all the registers and try to /* This will loop over all the registers and try to
* make a bitmask of the ones we're interested in. * make a bitmask of the ones we're interested in.
@ -392,14 +422,43 @@ HRESULT shader_get_registers_used(
else if (WINED3DSPR_TEMP == regtype) else if (WINED3DSPR_TEMP == regtype)
reg_maps->temporary[reg] = 1; reg_maps->temporary[reg] = 1;
else if (WINED3DSPR_INPUT == regtype && !pshader) else if (WINED3DSPR_INPUT == regtype) {
reg_maps->attributes[reg] = 1; if( !pshader)
reg_maps->attributes[reg] = 1;
else {
if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
/* If relative addressing is used, we must assume that all registers
* are used. Even if it is a construct like v3[aL], we can't assume
* that v0, v1 and v2 aren't read because aL can be negative
*/
unsigned int i;
for(i = 0; i < MAX_REG_INPUT; i++) {
((IWineD3DPixelShaderImpl *) This)->input_reg_used[i] = TRUE;
}
} else {
((IWineD3DPixelShaderImpl *) This)->input_reg_used[reg] = TRUE;
}
}
}
else if (WINED3DSPR_RASTOUT == regtype && reg == 1) else if (WINED3DSPR_RASTOUT == regtype && reg == 1)
reg_maps->fog = 1; reg_maps->fog = 1;
}
else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader)
reg_maps->vpos = 1;
else if(WINED3DSPR_CONST == regtype && !pshader &&
param & WINED3DSHADER_ADDRMODE_RELATIVE) {
if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) {
((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg;
} else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) {
((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg;
}
}
}
} }
} }
reg_maps->loop_depth = max_loop_depth;
return WINED3D_OK; return WINED3D_OK;
} }
@ -699,6 +758,7 @@ void shader_generate_main(
CONST DWORD* pFunction) { CONST DWORD* pFunction) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
const DWORD *pToken = pFunction; const DWORD *pToken = pFunction;
const SHADER_OPCODE *curOpcode = NULL; const SHADER_OPCODE *curOpcode = NULL;
SHADER_HANDLER hw_fct = NULL; SHADER_HANDLER hw_fct = NULL;
@ -788,6 +848,9 @@ void shader_generate_main(
/* Call appropriate function for output target */ /* Call appropriate function for output target */
hw_fct(&hw_arg); hw_fct(&hw_arg);
/* Add color correction if needed */
device->shader_backend->shader_color_correction(&hw_arg);
/* Process instruction modifiers for GLSL apps ( _sat, etc. ) */ /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
if (This->baseShader.shader_mode == SHADER_GLSL) if (This->baseShader.shader_mode == SHADER_GLSL)
shader_glsl_add_instruction_modifiers(&hw_arg); shader_glsl_add_instruction_modifiers(&hw_arg);
@ -930,6 +993,10 @@ void shader_trace_init(
shader_dump_param(iface, *(pToken + 2), 0, 1); shader_dump_param(iface, *(pToken + 2), 0, 1);
TRACE(") "); TRACE(") ");
} }
if (opcode_token & WINED3DSI_COISSUE) {
/* PixWin marks instructions with the coissue flag with a '+' */
TRACE("+");
}
TRACE("%s", curOpcode->name); TRACE("%s", curOpcode->name);

View file

@ -161,11 +161,39 @@ DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) { HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
UINT textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) { if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
TRACE("(%p) : returning invalid call\n", This); TRACE("(%p) : returning invalid call\n", This);
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if(This->baseTexture.filterType != FilterType) {
/* What about multithreading? Do we want all the context overhead just to set this value?
* Or should we delay the applying until the texture is used for drawing? For now, apply
* immediately.
*/
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
glBindTexture(textureDimensions, This->baseTexture.textureName);
checkGLcall("glBindTexture");
switch(FilterType) {
case WINED3DTEXF_NONE:
case WINED3DTEXF_POINT:
glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST);
checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST)");
case WINED3DTEXF_LINEAR:
glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)");
default:
WARN("Unexpected filter type %d, setting to GL_NICEST\n", FilterType);
glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)");
}
LEAVE_GL();
}
This->baseTexture.filterType = FilterType; This->baseTexture.filterType = FilterType;
TRACE("(%p) :\n", This); TRACE("(%p) :\n", This);
return WINED3D_OK; return WINED3D_OK;
@ -239,6 +267,16 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP; This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP;
IWineD3DBaseTexture_SetDirty(iface, TRUE); IWineD3DBaseTexture_SetDirty(iface, TRUE);
isNewTexture = TRUE; isNewTexture = TRUE;
if(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP) {
/* This means double binding the texture at creation, but keeps the code simpler all
* in all, and the run-time path free from additional checks
*/
glBindTexture(textureDimensions, This->baseTexture.textureName);
checkGLcall("glBindTexture");
glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)");
}
} }
/* Bind the texture */ /* Bind the texture */

View file

@ -131,10 +131,12 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target); TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
#define PUSH1(att) attribs[nAttribs++] = (att);
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
if(create_pbuffer) { if(create_pbuffer) {
HDC hdc_parent = GetDC(win_handle); HDC hdc_parent = GetDC(win_handle);
int iPixelFormat = 0; int iPixelFormat = 0;
short red, green, blue, alphaBits, colorBits; short redBits, greenBits, blueBits, alphaBits, colorBits;
short depthBits, stencilBits; short depthBits, stencilBits;
IWineD3DSurface *StencilSurface = This->stencilBufferTarget; IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
@ -144,23 +146,20 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
int nAttribs = 0; int nAttribs = 0;
unsigned int nFormats; unsigned int nFormats;
#define PUSH1(att) attribs[nAttribs++] = (att);
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
/* Retrieve the specifications for the pixelformat from the backbuffer / stencilbuffer */ /* Retrieve the specifications for the pixelformat from the backbuffer / stencilbuffer */
getColorBits(target->resource.format, &red, &green, &blue, &alphaBits, &colorBits); getColorBits(target->resource.format, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits);
getDepthStencilBits(StencilBufferFormat, &depthBits, &stencilBits); getDepthStencilBits(StencilBufferFormat, &depthBits, &stencilBits);
PUSH2(WGL_DRAW_TO_PBUFFER_ARB, 1); /* We need pbuffer support; doublebuffering isn't needed */ PUSH2(WGL_DRAW_TO_PBUFFER_ARB, 1); /* We need pbuffer support; doublebuffering isn't needed */
PUSH2(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); /* Make sure we don't get a float or color index format */ PUSH2(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); /* Make sure we don't get a float or color index format */
PUSH2(WGL_COLOR_BITS_ARB, colorBits); PUSH2(WGL_COLOR_BITS_ARB, colorBits);
PUSH2(WGL_RED_BITS_ARB, redBits);
PUSH2(WGL_GREEN_BITS_ARB, greenBits);
PUSH2(WGL_BLUE_BITS_ARB, blueBits);
PUSH2(WGL_ALPHA_BITS_ARB, alphaBits); PUSH2(WGL_ALPHA_BITS_ARB, alphaBits);
PUSH2(WGL_DEPTH_BITS_ARB, depthBits); PUSH2(WGL_DEPTH_BITS_ARB, depthBits);
PUSH2(WGL_STENCIL_BITS_ARB, stencilBits); PUSH2(WGL_STENCIL_BITS_ARB, stencilBits);
PUSH1(0); /* end the list */ PUSH1(0); /* end the list */
#undef PUSH1
#undef PUSH2
/* Try to find a pixelformat that matches exactly. If that fails let ChoosePixelFormat try to find a close match */ /* Try to find a pixelformat that matches exactly. If that fails let ChoosePixelFormat try to find a close match */
if(!GL_EXTCALL(wglChoosePixelFormatARB(hdc_parent, (const int*)&attribs, NULL, 1, &iPixelFormat, &nFormats))) if(!GL_EXTCALL(wglChoosePixelFormatARB(hdc_parent, (const int*)&attribs, NULL, 1, &iPixelFormat, &nFormats)))
{ {
@ -205,10 +204,12 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
} else { } else {
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat; int iPixelFormat;
short red, green, blue, alpha; short redBits, greenBits, blueBits, alphaBits, colorBits;
short colorBits; short depthBits=0, stencilBits=0;
short depthBits, stencilBits;
int res; int res;
int attribs[256];
int nAttribs = 0;
unsigned int nFormats;
hdc = GetDC(win_handle); hdc = GetDC(win_handle);
if(hdc == NULL) { if(hdc == NULL) {
@ -217,36 +218,57 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
} }
/* PixelFormat selection */ /* PixelFormat selection */
/* TODO: fill cColorBits/cDepthBits with target->resource.format */ PUSH2(WGL_DRAW_TO_WINDOW_ARB, GL_TRUE); /* We want to draw to a window */
ZeroMemory(&pfd, sizeof(pfd)); PUSH2(WGL_DOUBLE_BUFFER_ARB, GL_TRUE);
pfd.nSize = sizeof(pfd); PUSH2(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); /* Make sure we don't get a float or color index format */
pfd.nVersion = 1; PUSH2(WGL_SUPPORT_OPENGL_ARB, GL_TRUE);
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/ PUSH2(WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB); /* Make sure we receive an accelerated format. On windows (at least on ATI) this is not always the case */
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 0;
pfd.cStencilBits = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
/* Try to match the colorBits of the d3d format */ if(!getColorBits(target->resource.format, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) {
if(getColorBits(target->resource.format, &red, &green, &blue, &alpha, &colorBits)) ERR("Unable to get color bits for format %#x!\n", target->resource.format);
pfd.cColorBits = colorBits; return FALSE;
}
PUSH2(WGL_COLOR_BITS_ARB, colorBits);
PUSH2(WGL_RED_BITS_ARB, redBits);
PUSH2(WGL_GREEN_BITS_ARB, greenBits);
PUSH2(WGL_BLUE_BITS_ARB, blueBits);
PUSH2(WGL_ALPHA_BITS_ARB, alphaBits);
/* Retrieve the depth stencil format from the present parameters. /* Retrieve the depth stencil format from the present parameters.
* The choice of the proper format can give a nice performance boost * The choice of the proper format can give a nice performance boost
* in case of GPU limited programs. */ * in case of GPU limited programs. */
if(pPresentParms->EnableAutoDepthStencil) { if(pPresentParms->EnableAutoDepthStencil) {
TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat)); TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat));
if(getDepthStencilBits(pPresentParms->AutoDepthStencilFormat, &depthBits, &stencilBits)) { if(!getDepthStencilBits(pPresentParms->AutoDepthStencilFormat, &depthBits, &stencilBits)) {
pfd.cDepthBits = depthBits; ERR("Unable to get depth / stencil bits for AutoDepthStencilFormat %#x!\n", pPresentParms->AutoDepthStencilFormat);
pfd.cStencilBits = stencilBits; return FALSE;
} }
PUSH2(WGL_DEPTH_BITS_ARB, depthBits);
PUSH2(WGL_STENCIL_BITS_ARB, stencilBits);
} }
iPixelFormat = ChoosePixelFormat(hdc, &pfd); PUSH1(0); /* end the list */
if(!iPixelFormat) {
/* If this happens something is very wrong as ChoosePixelFormat barely fails */ /* In case of failure hope that standard ChooosePixelFormat will find something suitable */
ERR("Can't find a suitable iPixelFormat\n"); if(!GL_EXTCALL(wglChoosePixelFormatARB(hdc, (const int*)&attribs, NULL, 1, &iPixelFormat, &nFormats)))
{
/* PixelFormat selection */
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cAlphaBits = alphaBits;
pfd.cColorBits = colorBits;
pfd.cDepthBits = depthBits;
pfd.cStencilBits = stencilBits;
pfd.iLayerType = PFD_MAIN_PLANE;
iPixelFormat = ChoosePixelFormat(hdc, &pfd);
if(!iPixelFormat) {
/* If this happens something is very wrong as ChoosePixelFormat barely fails */
ERR("Can't find a suitable iPixelFormat\n");
}
} }
DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd); DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
@ -265,6 +287,8 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
} }
} }
} }
#undef PUSH1
#undef PUSH2
ctx = pwglCreateContext(hdc); ctx = pwglCreateContext(hdc);
if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx); if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
@ -301,6 +325,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
goto out; goto out;
} }
ENTER_GL();
TRACE("Setting up the screen\n"); TRACE("Setting up the screen\n");
/* Clear the screen */ /* Clear the screen */
glClearColor(1.0, 0.0, 0.0, 0.0); glClearColor(1.0, 0.0, 0.0, 0.0);
@ -366,6 +391,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n"); checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
} }
} }
LEAVE_GL();
if(oldDrawable && oldCtx) { if(oldDrawable && oldCtx) {
pwglMakeCurrent(oldDrawable, oldCtx); pwglMakeCurrent(oldDrawable, oldCtx);
@ -568,6 +594,16 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE); glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
checkGLcall("glColorMask"); checkGLcall("glColorMask");
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING)); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING));
if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
glDisable(GL_COLOR_SUM_EXT);
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE));
checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
}
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE));
checkGLcall("glFinalCombinerInputNV");
}
/* Setup transforms */ /* Setup transforms */
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@ -638,7 +674,7 @@ static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchai
* Returns: The needed context * Returns: The needed context
* *
*****************************************************************************/ *****************************************************************************/
static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid) { static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid, GLint *buffer) {
IWineD3DSwapChain *swapchain = NULL; IWineD3DSwapChain *swapchain = NULL;
HRESULT hr; HRESULT hr;
BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen; BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
@ -657,15 +693,12 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
* rendering. No context change is needed in that case * rendering. No context change is needed in that case
*/ */
if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { if(((IWineD3DSwapChainImpl *) swapchain)->frontBuffer == target) {
if(((IWineD3DSwapChainImpl *) swapchain)->backBuffer) { *buffer = GL_FRONT;
glDrawBuffer(GL_BACK); } else {
checkGLcall("glDrawBuffer(GL_BACK)"); *buffer = GL_BACK;
} else { }
glDrawBuffer(GL_FRONT); if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
checkGLcall("glDrawBuffer(GL_FRONT)");
}
} else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
if(This->pbufferContext && tid == This->pbufferContext->tid) { if(This->pbufferContext && tid == This->pbufferContext->tid) {
This->pbufferContext->tid = 0; This->pbufferContext->tid = 0;
} }
@ -673,16 +706,17 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
IWineD3DSwapChain_Release(swapchain); IWineD3DSwapChain_Release(swapchain);
if(oldRenderOffscreen) { if(oldRenderOffscreen) {
Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
Context_MarkStateDirty(context, WINED3DTS_PROJECTION); Context_MarkStateDirty(context, WINED3DTS_PROJECTION);
Context_MarkStateDirty(context, STATE_VDECL); Context_MarkStateDirty(context, STATE_VDECL);
Context_MarkStateDirty(context, STATE_VIEWPORT); Context_MarkStateDirty(context, STATE_VIEWPORT);
Context_MarkStateDirty(context, STATE_SCISSORRECT); Context_MarkStateDirty(context, STATE_SCISSORRECT);
Context_MarkStateDirty(context, STATE_FRONTFACE);
} }
} else { } else {
TRACE("Rendering offscreen\n"); TRACE("Rendering offscreen\n");
This->render_offscreen = TRUE; This->render_offscreen = TRUE;
*buffer = This->offscreenBuffer;
switch(wined3d_settings.offscreen_rendering_mode) { switch(wined3d_settings.offscreen_rendering_mode) {
case ORM_FBO: case ORM_FBO:
@ -748,8 +782,6 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
*/ */
context = findThreadContextForSwapChain(This->swapchains[0], tid); context = findThreadContextForSwapChain(This->swapchains[0], tid);
} }
glDrawBuffer(This->offscreenBuffer);
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
break; break;
} }
@ -761,11 +793,11 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
} }
if(!oldRenderOffscreen) { if(!oldRenderOffscreen) {
Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
Context_MarkStateDirty(context, WINED3DTS_PROJECTION); Context_MarkStateDirty(context, WINED3DTS_PROJECTION);
Context_MarkStateDirty(context, STATE_VDECL); Context_MarkStateDirty(context, STATE_VDECL);
Context_MarkStateDirty(context, STATE_VIEWPORT); Context_MarkStateDirty(context, STATE_VIEWPORT);
Context_MarkStateDirty(context, STATE_SCISSORRECT); Context_MarkStateDirty(context, STATE_SCISSORRECT);
Context_MarkStateDirty(context, STATE_FRONTFACE);
} }
} }
if (readTexture) { if (readTexture) {
@ -783,7 +815,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
IWineD3DSurface_PreLoad(This->lastActiveRenderTarget); IWineD3DSurface_PreLoad(This->lastActiveRenderTarget);
/* Assume that the drawable will be modified by some other things now */ /* Assume that the drawable will be modified by some other things now */
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INDRAWABLE; IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, FALSE);
This->isInDraw = oldInDraw; This->isInDraw = oldInDraw;
} }
@ -813,12 +845,11 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
DWORD dirtyState, idx; DWORD dirtyState, idx;
BYTE shift; BYTE shift;
WineD3DContext *context; WineD3DContext *context;
GLint drawBuffer=0;
TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid); TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
ENTER_GL();
if(This->lastActiveRenderTarget != target || tid != This->lastThread) { if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
context = FindContext(This, target, tid); context = FindContext(This, target, tid, &drawBuffer);
This->lastActiveRenderTarget = target; This->lastActiveRenderTarget = target;
This->lastThread = tid; This->lastThread = tid;
} else { } else {
@ -830,15 +861,24 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
if(context != This->activeContext) { if(context != This->activeContext) {
BOOL ret; BOOL ret;
TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx); TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
LEAVE_GL();
ret = pwglMakeCurrent(context->hdc, context->glCtx); ret = pwglMakeCurrent(context->hdc, context->glCtx);
ENTER_GL();
if(ret == FALSE) { if(ret == FALSE) {
ERR("Failed to activate the new context\n"); ERR("Failed to activate the new context\n");
} }
This->activeContext = context; This->activeContext = context;
} }
/* We only need ENTER_GL for the gl calls made below and for the helper functions which make GL calls */
ENTER_GL();
/* Select the right draw buffer. It is selected in FindContext. */
if(drawBuffer && context->last_draw_buffer != drawBuffer) {
TRACE("Drawing to buffer: %#x\n", drawBuffer);
context->last_draw_buffer = drawBuffer;
glDrawBuffer(drawBuffer);
checkGLcall("glDrawBuffer");
}
switch(usage) { switch(usage) {
case CTXUSAGE_RESOURCELOAD: case CTXUSAGE_RESOURCELOAD:
/* This does not require any special states to be set up */ /* This does not require any special states to be set up */

View file

@ -148,7 +148,7 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) { for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[j][i], NULL); IWineD3DSurface_AddDirtyRect(This->surfaces[j][i], NULL);
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]); IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode); IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
} }
@ -272,7 +272,7 @@ static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture
******************************************* */ ******************************************* */
static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) { static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
int i,j; unsigned int i,j;
TRACE("(%p) : Cleaning up\n",This); TRACE("(%p) : Cleaning up\n",This);
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
for (j = 0; j < 6; j++) { for (j = 0; j < 6; j++) {

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,8 @@ static const struct {
/* APPLE */ /* APPLE */
{"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE}, {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE},
{"GL_APPLE_fence", APPLE_FENCE}, {"GL_APPLE_fence", APPLE_FENCE},
{"GL_APPLE_flush_render", APPLE_FLUSH_RENDER},
{"GL_APPLE_ycbcr_422", APPLE_YCBCR_422},
/* ATI */ /* ATI */
{"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL}, {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL},
@ -117,6 +119,10 @@ static const struct {
{"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1}, {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1},
{"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2}, {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2},
{"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3}, {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3},
{"GL_NV_depth_clamp", NV_DEPTH_CLAMP},
/* SGI */
{"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP},
}; };
/********************************************************** /**********************************************************
@ -188,13 +194,11 @@ static void WineD3D_ReleaseFakeGLContext(void) {
assert(wined3d_fake_gl_context_ref >= 0); assert(wined3d_fake_gl_context_ref >= 0);
LeaveCriticalSection(&wined3d_fake_gl_context_cs); LeaveCriticalSection(&wined3d_fake_gl_context_cs);
LEAVE_GL();
} }
static BOOL WineD3D_CreateFakeGLContext(void) { static BOOL WineD3D_CreateFakeGLContext(void) {
HGLRC glCtx = NULL; HGLRC glCtx = NULL;
ENTER_GL();
EnterCriticalSection(&wined3d_fake_gl_context_cs); EnterCriticalSection(&wined3d_fake_gl_context_cs);
TRACE("getting context...\n"); TRACE("getting context...\n");
@ -269,10 +273,17 @@ static BOOL WineD3D_CreateFakeGLContext(void) {
wined3d_fake_gl_context_hwnd = NULL; wined3d_fake_gl_context_hwnd = NULL;
if(glCtx) pwglDeleteContext(glCtx); if(glCtx) pwglDeleteContext(glCtx);
LeaveCriticalSection(&wined3d_fake_gl_context_cs); LeaveCriticalSection(&wined3d_fake_gl_context_cs);
LEAVE_GL();
return FALSE; return FALSE;
} }
/* Adjust the amount of used texture memory */
long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram){
UINT Adapter = D3DDevice->adapterNo;
Adapters[Adapter].UsedTextureRam += glram;
TRACE("Adjusted gl ram by %ld to %d\n", glram, Adapters[Adapter].UsedTextureRam);
return Adapters[Adapter].UsedTextureRam;
}
/********************************************************** /**********************************************************
* IUnknown parts follows * IUnknown parts follows
@ -326,7 +337,13 @@ static void select_shader_mode(
if (wined3d_settings.vs_mode == VS_NONE) { if (wined3d_settings.vs_mode == VS_NONE) {
*vs_selected = SHADER_NONE; *vs_selected = SHADER_NONE;
} else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) { } else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
*vs_selected = SHADER_GLSL; /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
* wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
* shaders only on this card. */
if(gl_info->vs_nv_version && gl_info->vs_nv_version < VS_VERSION_20)
*vs_selected = SHADER_ARB;
else
*vs_selected = SHADER_GLSL;
} else if (gl_info->supported[ARB_VERTEX_PROGRAM]) { } else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
*vs_selected = SHADER_ARB; *vs_selected = SHADER_ARB;
} else { } else {
@ -392,6 +409,38 @@ static void select_shader_max_constants(
**********************************************************/ **********************************************************/
#define GLINFO_LOCATION (*gl_info) #define GLINFO_LOCATION (*gl_info)
static inline BOOL test_arb_vs_offset_limit(WineD3D_GL_Info *gl_info) {
GLuint prog;
BOOL ret = FALSE;
const char *testcode =
"!!ARBvp1.0\n"
"PARAM C[66] = { program.env[0..65] };\n"
"ADDRESS A0;"
"ARL A0.x, 0.0;\n"
"MOV result.position, C[A0.x + 65];\n"
"END\n";
while(glGetError());
GL_EXTCALL(glGenProgramsARB(1, &prog));
if(!prog) {
ERR("Failed to create an ARB offset limit test program\n");
}
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
strlen(testcode), testcode));
if(glGetError() != 0) {
TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
ret = TRUE;
} else TRACE("OpenGL implementation allows offsets > 63\n");
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
GL_EXTCALL(glDeleteProgramsARB(1, &prog));
checkGLcall("ARB vp offset limit test cleanup\n");
return ret;
}
BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
const char *GL_Extensions = NULL; const char *GL_Extensions = NULL;
const char *WGL_Extensions = NULL; const char *WGL_Extensions = NULL;
@ -403,43 +452,12 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
BOOL return_value = TRUE; BOOL return_value = TRUE;
int i; int i;
HDC hdc; HDC hdc;
HMODULE mod_gl; unsigned int vidmem=0;
#ifdef USE_WIN32_OPENGL
#define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
mod_gl = LoadLibraryA("opengl32.dll");
if(!mod_gl) {
ERR("Can't load opengl32.dll!\n");
return FALSE;
}
#else
#define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
/* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
mod_gl = GetModuleHandleA("gdi32.dll");
#endif
/* Load WGL core functions from opengl32.dll */
#define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
WGL_FUNCS_GEN;
#undef USE_WGL_FUNC
if(!pwglGetProcAddress) {
ERR("Unable to load wglGetProcAddress!\n");
return FALSE;
}
/* Dynamicly load all GL core functions */
GL_FUNCS_GEN;
#undef USE_GL_FUNC
/* Make sure that we've got a context */
/* TODO: CreateFakeGLContext should really take a display as a parameter */
/* Only save the values obtained when a display is provided */
if (!WineD3D_CreateFakeGLContext() || wined3d_fake_gl_context_foreign)
return_value = FALSE;
TRACE_(d3d_caps)("(%p)\n", gl_info); TRACE_(d3d_caps)("(%p)\n", gl_info);
ENTER_GL();
gl_string = (const char *) glGetString(GL_RENDERER); gl_string = (const char *) glGetString(GL_RENDERER);
if (NULL == gl_string) if (NULL == gl_string)
gl_string = "None"; gl_string = "None";
@ -625,6 +643,7 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max); TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv); glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
gl_info->max_pointsizemin = gl_floatv[0];
gl_info->max_pointsize = gl_floatv[1]; gl_info->max_pointsize = gl_floatv[1];
TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]); TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
@ -707,7 +726,7 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
GLint tmp; GLint tmp;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp); gl_info->max_fragment_samplers = min(8, tmp);
} else { } else {
gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max); gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
} }
@ -719,6 +738,29 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
gl_info->max_vertex_samplers = tmp; gl_info->max_vertex_samplers = tmp;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp); glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
gl_info->max_combined_samplers = tmp; gl_info->max_combined_samplers = tmp;
/* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
* is known at shader link time. In a vertex shader + pixel shader combination this isn't
* an issue because then the sampler setup only depends on the two shaders. If a pixel
* shader is used with fixed function vertex processing we're fine too because fixed function
* vertex processing doesn't use any samplers. If fixed function fragment processing is
* used we have to make sure that all vertex sampler setups are valid together with all
* possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
* <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
* dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
* dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
* a fixed function pipeline anymore.
*
* So this is just a check to check that our assumption holds true. If not, write a warning
* and reduce the number of vertex samplers or propably disable vertex texture fetch.
*/
if(gl_info->max_vertex_samplers &&
MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) {
FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n",
gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n");
gl_info->max_vertex_samplers = max(0, gl_info->max_combined_samplers - MAX_TEXTURES);
}
} else { } else {
gl_info->max_combined_samplers = gl_info->max_fragment_samplers; gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
} }
@ -745,24 +787,26 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
gl_info->ps_arb_constantsF = gl_max; gl_info->ps_arb_constantsF = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF); TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max)); GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
gl_info->ps_arb_max_temps = gl_max; gl_info->ps_arb_max_temps = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM temporaries: %d\n", gl_info->ps_arb_max_temps); TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d\n", gl_info->ps_arb_max_temps);
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max)); GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
gl_info->ps_arb_max_instructions = gl_max; gl_info->ps_arb_max_instructions = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM instructions: %d\n", gl_info->ps_arb_max_instructions); TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d\n", gl_info->ps_arb_max_instructions);
} }
if (gl_info->supported[ARB_VERTEX_PROGRAM]) { if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
gl_info->vs_arb_version = VS_VERSION_11; gl_info->vs_arb_version = VS_VERSION_11;
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
gl_info->vs_arb_constantsF = gl_max; gl_info->vs_arb_constantsF = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF); TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max)); GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
gl_info->vs_arb_max_temps = gl_max; gl_info->vs_arb_max_temps = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM temporaries: %d\n", gl_info->vs_arb_max_temps); TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d\n", gl_info->vs_arb_max_temps);
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max)); GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
gl_info->vs_arb_max_instructions = gl_max; gl_info->vs_arb_max_instructions = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM instructions: %d\n", gl_info->vs_arb_max_instructions); TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d\n", gl_info->vs_arb_max_instructions);
gl_info->arb_vs_offset_limit = test_arb_vs_offset_limit(gl_info);
} }
if (gl_info->supported[ARB_VERTEX_SHADER]) { if (gl_info->supported[ARB_VERTEX_SHADER]) {
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max); glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
@ -773,6 +817,9 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
gl_info->ps_glsl_constantsF = gl_max / 4; gl_info->ps_glsl_constantsF = gl_max / 4;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF); TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
gl_info->max_glsl_varyings = gl_max;
TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings)\n", gl_max, gl_max / 4);
} }
if (gl_info->supported[EXT_VERTEX_SHADER]) { if (gl_info->supported[EXT_VERTEX_SHADER]) {
gl_info->vs_ati_version = VS_VERSION_11; gl_info->vs_ati_version = VS_VERSION_11;
@ -842,7 +889,16 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
* without a full database we can return a card with similar features. Second the size of the database * without a full database we can return a card with similar features. Second the size of the database
* can be made quite small because when you know what type of 3d functionality a card has, you know to which * can be made quite small because when you know what type of 3d functionality a card has, you know to which
* GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
* to distinguishes between different models from that family. * to distinguishes between different models from that family.
*
* The code also selects a default amount of video memory which we will use for an estimation of the amount
* of free texture memory. In case of real D3D the amount of texture memory includes video memory and system
* memory (to be specific AGP memory or in case of PCIE TurboCache/HyperMemory). We don't know how much
* system memory can be addressed by the system but we can make a reasonable estimation about the amount of
* video memory. If the value is slightly wrong it doesn't matter as we didn't include AGP-like memory which
* makes the amount of addressable memory higher and second OpenGL isn't that critical it moves to system
* memory behind our backs if really needed.
* Note that the amout of video memory can be overruled using a registry setting.
*/ */
switch (gl_info->gl_vendor) { switch (gl_info->gl_vendor) {
case VENDOR_NVIDIA: case VENDOR_NVIDIA:
@ -850,79 +906,173 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
* shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx. * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
*/ */
if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) { if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
if (strstr(gl_info->gl_renderer, "7800") || /* Geforce8 - highend */
strstr(gl_info->gl_renderer, "7900") || if (strstr(gl_info->gl_renderer, "8800")) {
strstr(gl_info->gl_renderer, "7950") || gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
strstr(gl_info->gl_renderer, "Quadro FX 4") || vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
strstr(gl_info->gl_renderer, "Quadro FX 5")) }
gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT; /* Geforce8 - midend */
else if(strstr(gl_info->gl_renderer, "8600") ||
strstr(gl_info->gl_renderer, "8700"))
{
gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600GT;
vidmem = 256;
}
/* Geforce8 - lowend */
else if(strstr(gl_info->gl_renderer, "8300") ||
strstr(gl_info->gl_renderer, "8400") ||
strstr(gl_info->gl_renderer, "8500"))
{
gl_info->gl_card = CARD_NVIDIA_GEFORCE_8300GS;
vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
}
/* Geforce7 - highend */
else if(strstr(gl_info->gl_renderer, "7800") ||
strstr(gl_info->gl_renderer, "7900") ||
strstr(gl_info->gl_renderer, "7950") ||
strstr(gl_info->gl_renderer, "Quadro FX 4") ||
strstr(gl_info->gl_renderer, "Quadro FX 5"))
{
gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
}
/* Geforce7 midend / Geforce6 highend */
else if(strstr(gl_info->gl_renderer, "6800") || else if(strstr(gl_info->gl_renderer, "6800") ||
strstr(gl_info->gl_renderer, "7600")) strstr(gl_info->gl_renderer, "7600") ||
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800; strstr(gl_info->gl_renderer, "7700"))
{
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
}
/* Geforce6 - midend */
else if(strstr(gl_info->gl_renderer, "6600") || else if(strstr(gl_info->gl_renderer, "6600") ||
strstr(gl_info->gl_renderer, "6610") || strstr(gl_info->gl_renderer, "6610") ||
strstr(gl_info->gl_renderer, "6700")) strstr(gl_info->gl_renderer, "6700"))
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT; {
else gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400 */ vidmem = 128; /* A 6600GT has 128-256MB */
}
/* Geforce6/7 lowend */
else {
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
vidmem = 64; /* */
}
} else if(WINE_D3D9_CAPABLE(gl_info)) { } else if(WINE_D3D9_CAPABLE(gl_info)) {
/* GeforceFX - highend */
if (strstr(gl_info->gl_renderer, "5800") || if (strstr(gl_info->gl_renderer, "5800") ||
strstr(gl_info->gl_renderer, "5900") || strstr(gl_info->gl_renderer, "5900") ||
strstr(gl_info->gl_renderer, "5950") || strstr(gl_info->gl_renderer, "5950") ||
strstr(gl_info->gl_renderer, "Quadro FX")) strstr(gl_info->gl_renderer, "Quadro FX"))
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800; {
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
vidmem = 256; /* 5800-5900 cards use 256MB */
}
/* GeforceFX - midend */
else if(strstr(gl_info->gl_renderer, "5600") || else if(strstr(gl_info->gl_renderer, "5600") ||
strstr(gl_info->gl_renderer, "5650") || strstr(gl_info->gl_renderer, "5650") ||
strstr(gl_info->gl_renderer, "5700") || strstr(gl_info->gl_renderer, "5700") ||
strstr(gl_info->gl_renderer, "5750")) strstr(gl_info->gl_renderer, "5750"))
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600; {
else gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
vidmem = 128; /* A 5600 uses 128-256MB */
}
/* GeforceFX - lowend */
else {
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */ gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
}
} else if(WINE_D3D8_CAPABLE(gl_info)) { } else if(WINE_D3D8_CAPABLE(gl_info)) {
if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4")) if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4")) {
gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */ gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
else vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
}
else {
gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */ gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
vidmem = 64; /* Geforce3 cards have 64-128MB */
}
} else if(WINE_D3D7_CAPABLE(gl_info)) { } else if(WINE_D3D7_CAPABLE(gl_info)) {
if (strstr(gl_info->gl_renderer, "GeForce4 MX")) if (strstr(gl_info->gl_renderer, "GeForce4 MX")) {
gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */ gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR")) vidmem = 64; /* Most Geforce4MX GPUs have at least 64MB of memory, some early models had 32MB but most have 64MB or even 128MB */
}
else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR")) {
gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */ gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2")) vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
}
else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2")) {
gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */ gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
else vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
}
else {
gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */ gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
vidmem = 32; /* Most Geforce1 cards have 32MB, there are also some rare 16 and 64MB (Dell) models */
}
} else { } else {
if (strstr(gl_info->gl_renderer, "TNT2")) if (strstr(gl_info->gl_renderer, "TNT2")) {
gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */ gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
else vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
}
else {
gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */ gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
}
} }
break; break;
case VENDOR_ATI: case VENDOR_ATI:
if(WINE_D3D9_CAPABLE(gl_info)) { if(WINE_D3D9_CAPABLE(gl_info)) {
/* Radeon R6xx HD2900 - highend */
if (strstr(gl_info->gl_renderer, "HD 2900")) {
gl_info->gl_card = CARD_ATI_RADEON_HD2900;
vidmem = 512; /* HD2900 uses 512-1024MB */
}
/* Radeon R6xx HD2600- midend */
else if (strstr(gl_info->gl_renderer, "HD 2600")) {
gl_info->gl_card = CARD_ATI_RADEON_HD2600;
vidmem = 256; /* HD2600 uses 256-512MB */
}
/* Radeon R6xx HD2300/HD2400 - lowend */
else if (strstr(gl_info->gl_renderer, "HD 2300") ||
strstr(gl_info->gl_renderer, "HD 2400"))
{
gl_info->gl_card = CARD_ATI_RADEON_HD2300;
vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
}
/* Radeon R5xx */ /* Radeon R5xx */
if (strstr(gl_info->gl_renderer, "X1600") || else if (strstr(gl_info->gl_renderer, "X1600") ||
strstr(gl_info->gl_renderer, "X1800") || strstr(gl_info->gl_renderer, "X1650") ||
strstr(gl_info->gl_renderer, "X1900") || strstr(gl_info->gl_renderer, "X1800") ||
strstr(gl_info->gl_renderer, "X1950")) strstr(gl_info->gl_renderer, "X1900") ||
gl_info->gl_card = CARD_ATI_RADEON_X1600; strstr(gl_info->gl_renderer, "X1950"))
/* Radeon R4xx + X1300/X1400 (lowend R5xx) */ {
gl_info->gl_card = CARD_ATI_RADEON_X1600;
vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
}
/* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
else if(strstr(gl_info->gl_renderer, "X700") || else if(strstr(gl_info->gl_renderer, "X700") ||
strstr(gl_info->gl_renderer, "X800") || strstr(gl_info->gl_renderer, "X800") ||
strstr(gl_info->gl_renderer, "X850") || strstr(gl_info->gl_renderer, "X850") ||
strstr(gl_info->gl_renderer, "X1300") || strstr(gl_info->gl_renderer, "X1300") ||
strstr(gl_info->gl_renderer, "X1400")) strstr(gl_info->gl_renderer, "X1400") ||
gl_info->gl_card = CARD_ATI_RADEON_X700; strstr(gl_info->gl_renderer, "X1450") ||
strstr(gl_info->gl_renderer, "X1550"))
{
gl_info->gl_card = CARD_ATI_RADEON_X700;
vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
}
/* Radeon R3xx */ /* Radeon R3xx */
else else {
gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */ gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
}
} else if(WINE_D3D8_CAPABLE(gl_info)) { } else if(WINE_D3D8_CAPABLE(gl_info)) {
gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */ gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
} else if(WINE_D3D7_CAPABLE(gl_info)) { } else if(WINE_D3D7_CAPABLE(gl_info)) {
gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */ gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
vidmem = 32; /* There are models with up to 64MB */
} else } else
gl_info->gl_card = CARD_ATI_RAGE_128PRO; gl_info->gl_card = CARD_ATI_RAGE_128PRO;
vidmem = 16; /* There are 16-32MB models */
break; break;
case VENDOR_INTEL: case VENDOR_INTEL:
if (strstr(gl_info->gl_renderer, "915GM")) { if (strstr(gl_info->gl_renderer, "915GM")) {
@ -950,7 +1100,7 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
if(WINE_D3D9_CAPABLE(gl_info)) if(WINE_D3D9_CAPABLE(gl_info))
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600; gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
else if(WINE_D3D8_CAPABLE(gl_info)) else if(WINE_D3D8_CAPABLE(gl_info))
gl_info->gl_card = CARD_NVIDIA_GEFORCE3; gl_info->gl_card = CARD_NVIDIA_GEFORCE3;
else if(WINE_D3D7_CAPABLE(gl_info)) else if(WINE_D3D7_CAPABLE(gl_info))
gl_info->gl_card = CARD_NVIDIA_GEFORCE; gl_info->gl_card = CARD_NVIDIA_GEFORCE;
else if(WINE_D3D6_CAPABLE(gl_info)) else if(WINE_D3D6_CAPABLE(gl_info))
@ -960,6 +1110,12 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
} }
TRACE("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card); TRACE("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
/* If we have an estimate use it, else default to 64MB; */
if(vidmem)
gl_info->vidmem = vidmem*1024*1024; /* convert from MBs to bytes */
else
gl_info->vidmem = WINE_DEFAULT_VIDMEM;
/* Load all the lookup tables /* Load all the lookup tables
TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */ TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP; minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
@ -1042,9 +1198,8 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
} }
} }
} }
LEAVE_GL();
WineD3D_ReleaseFakeGLContext();
return return_value; return return_value;
} }
#undef GLINFO_LOCATION #undef GLINFO_LOCATION
@ -1496,6 +1651,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
if (Usage & WINED3DUSAGE_QUERY_FILTER) { if (Usage & WINED3DUSAGE_QUERY_FILTER) {
switch (CheckFormat) { switch (CheckFormat) {
/* Filtering not supported */ /* Filtering not supported */
case WINED3DFMT_R32F:
case WINED3DFMT_A32B32G32R32F: case WINED3DFMT_A32B32G32R32F:
TRACE_(d3d_caps)("[FAILED]\n"); TRACE_(d3d_caps)("[FAILED]\n");
return WINED3DERR_NOTAVAILABLE; return WINED3DERR_NOTAVAILABLE;
@ -1504,6 +1660,67 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
} }
} }
if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
TRACE_(d3d_caps)("[FAILED] - No mipmap generation support\n");
return WINED3DERR_NOTAVAILABLE;
}
}
if(RType == WINED3DRTYPE_VOLUMETEXTURE) {
if(!GL_SUPPORT(EXT_TEXTURE3D)) {
TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
return WINED3DERR_NOTAVAILABLE;
}
/* Filter formats that need conversion; For one part, this conversion is unimplemented,
* and volume textures are huge, so it would be a big performance hit. Unless we hit an
* app needing one of those formats, don't advertize them to avoid leading apps into
* temptation. The windows drivers don't support most of those formats on volumes anyway,
* except of R32F.
*/
switch(CheckFormat) {
case WINED3DFMT_P8:
case WINED3DFMT_A4L4:
case WINED3DFMT_R32F:
case WINED3DFMT_R16F:
case WINED3DFMT_X8L8V8U8:
case WINED3DFMT_L6V5U5:
TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
return WINED3DERR_NOTAVAILABLE;
case WINED3DFMT_Q8W8V8U8:
case WINED3DFMT_V16U16:
if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
return WINED3DERR_NOTAVAILABLE;
}
break;
case WINED3DFMT_V8U8:
if(!GL_SUPPORT(NV_TEXTURE_SHADER) || !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
return WINED3DERR_NOTAVAILABLE;
}
break;
case WINED3DFMT_DXT1:
case WINED3DFMT_DXT2:
case WINED3DFMT_DXT3:
case WINED3DFMT_DXT4:
case WINED3DFMT_DXT5:
/* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
* compressed texture results in an error. While the D3D refrast does
* support s3tc volumes, at least the nvidia windows driver does not, so
* we're free not to support this format.
*/
TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
return WINED3DERR_NOTAVAILABLE;
default:
/* Do nothing, continue with checking the format below */
break;
}
}
/* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants
* See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3D9__CheckDeviceFormat.asp
* and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */ * and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/D3DUSAGE_QUERY.asp */
@ -1715,7 +1932,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
return WINED3D_OK; return WINED3D_OK;
/***** /*****
* Not supported for now: Bump mapping formats * Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
* GL_NV_texture_shader), but advertized to make apps happy.
* Enable some because games often fail when they are not available * Enable some because games often fail when they are not available
* and are still playable even without bump mapping * and are still playable even without bump mapping
*/ */
@ -1724,11 +1942,19 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
case WINED3DFMT_L6V5U5: case WINED3DFMT_L6V5U5:
case WINED3DFMT_X8L8V8U8: case WINED3DFMT_X8L8V8U8:
case WINED3DFMT_Q8W8V8U8: case WINED3DFMT_Q8W8V8U8:
case WINED3DFMT_W11V11U10:
case WINED3DFMT_A2W10V10U10:
WARN_(d3d_caps)("[Not supported, but pretended to do]\n"); WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
return WINED3D_OK; return WINED3D_OK;
/* Those are not advertized by the nvidia windows driver, and not
* supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
* WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
* ARGB format if needed
*/
case WINED3DFMT_W11V11U10:
case WINED3DFMT_A2W10V10U10:
WARN_(d3d_caps)("[FAILED]\n");
return WINED3DERR_NOTAVAILABLE;
/***** /*****
* DXTN Formats: Handled above * DXTN Formats: Handled above
* WINED3DFMT_DXT1 * WINED3DFMT_DXT1
@ -1836,8 +2062,12 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED | *pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
WINED3DCAPS2_FULLSCREENGAMMA | WINED3DCAPS2_FULLSCREENGAMMA |
WINED3DCAPS2_DYNAMICTEXTURES; WINED3DCAPS2_DYNAMICTEXTURES;
if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
*pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
}
*pCaps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD; *pCaps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;
*pCaps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE; *pCaps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
WINED3DPRESENT_INTERVAL_ONE;
*pCaps->CursorCaps = WINED3DCURSORCAPS_COLOR | *pCaps->CursorCaps = WINED3DCURSORCAPS_COLOR |
WINED3DCURSORCAPS_LOWRES; WINED3DCURSORCAPS_LOWRES;
@ -1889,7 +2119,6 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPRASTERCAPS_ZFOG | WINED3DPRASTERCAPS_ZFOG |
WINED3DPRASTERCAPS_FOGVERTEX | WINED3DPRASTERCAPS_FOGVERTEX |
WINED3DPRASTERCAPS_FOGTABLE | WINED3DPRASTERCAPS_FOGTABLE |
WINED3DPRASTERCAPS_FOGRANGE |
WINED3DPRASTERCAPS_STIPPLE | WINED3DPRASTERCAPS_STIPPLE |
WINED3DPRASTERCAPS_SUBPIXEL | WINED3DPRASTERCAPS_SUBPIXEL |
WINED3DPRASTERCAPS_ZTEST | WINED3DPRASTERCAPS_ZTEST |
@ -1901,6 +2130,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY | *pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
WINED3DPRASTERCAPS_ZBIAS | WINED3DPRASTERCAPS_ZBIAS |
WINED3DPRASTERCAPS_MIPMAPLODBIAS; WINED3DPRASTERCAPS_MIPMAPLODBIAS;
}
if(GL_SUPPORT(NV_FOG_DISTANCE)) {
*pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
} }
/* FIXME Add: /* FIXME Add:
WINED3DPRASTERCAPS_COLORPERSPECTIVE WINED3DPRASTERCAPS_COLORPERSPECTIVE
@ -1934,8 +2166,6 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPBLENDCAPS_ZERO; WINED3DPBLENDCAPS_ZERO;
*pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR | *pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR |
WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
WINED3DPBLENDCAPS_BOTHSRCALPHA |
WINED3DPBLENDCAPS_DESTALPHA | WINED3DPBLENDCAPS_DESTALPHA |
WINED3DPBLENDCAPS_DESTCOLOR | WINED3DPBLENDCAPS_DESTCOLOR |
WINED3DPBLENDCAPS_INVDESTALPHA | WINED3DPBLENDCAPS_INVDESTALPHA |
@ -1948,6 +2178,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPBLENDCAPS_ZERO; WINED3DPBLENDCAPS_ZERO;
/* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor, /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
* according to the glBlendFunc manpage * according to the glBlendFunc manpage
*
* WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
* legacy settings for srcblend only
*/ */
*pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS | *pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
@ -1973,8 +2206,12 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPTEXTURECAPS_BORDER | WINED3DPTEXTURECAPS_BORDER |
WINED3DPTEXTURECAPS_MIPMAP | WINED3DPTEXTURECAPS_MIPMAP |
WINED3DPTEXTURECAPS_PROJECTED | WINED3DPTEXTURECAPS_PROJECTED |
WINED3DPTEXTURECAPS_PERSPECTIVE | WINED3DPTEXTURECAPS_PERSPECTIVE;
WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
*pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
}
if( GL_SUPPORT(EXT_TEXTURE3D)) { if( GL_SUPPORT(EXT_TEXTURE3D)) {
*pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP | *pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
@ -2199,14 +2436,17 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
if (vs_selected_mode == SHADER_GLSL) { if (vs_selected_mode == SHADER_GLSL) {
/* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for * vs_nv_version which is based on NV_vertex_program.
now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */ * For Ati cards there's no way using glsl (it abstracts the lowlevel info away) and also not
if(GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) * using ARB_vertex_program. It is safe to assume that when a card supports pixel shader 2.0 it
* supports vertex shader 2.0 too and the way around. We can detect ps2.0 using the maximum number
* of native instructions, so use that here. For more info see the pixel shader versioning code below. */
if((GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
*pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0); *pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
else else
*pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0); *pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n"); TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (*pCaps->VertexShaderVersion >> 8) & 0xff, *pCaps->VertexShaderVersion & 0xff);
} else if (vs_selected_mode == SHADER_ARB) { } else if (vs_selected_mode == SHADER_ARB) {
*pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1); *pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n"); TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
@ -2218,18 +2458,38 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF); *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
if (ps_selected_mode == SHADER_GLSL) { if (ps_selected_mode == SHADER_GLSL) {
/* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
in case of GeforceFX cards. */ * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
if(GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) * to distinguish between 2.0 and 3.0 (and 2.0a/2.0b). In case of Nvidia we use their fragment
* program extensions. On other hardware including ATI GL_ARB_fragment_program offers the info
* in max native instructions. Intel and others also offer the info in this extension but they
* don't support GLSL (at least on Windows).
*
* PS2.0 requires at least 96 instructions, 2.0a/2.0b go upto 512. Assume that if the number
* of instructions is 512 or less we have to do with ps2.0 hardware.
* NOTE: ps3.0 hardware requires 512 or more instructions but ati and nvidia offer 'enough' (1024 vs 4096) on their most basic ps3.0 hardware.
*/
if((GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
*pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0); *pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
else else
*pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0); *pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
/* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */ /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
*pCaps->PixelShader1xMaxValue = 1.0; * Direct3D minimum requirement.
TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n"); *
* Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
* of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
*
* The problem is that the refrast clamps temporary results in the shader to
* [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
* then applications may miss the clamping behavior. On the other hand, if it is smaller,
* the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
* offer a way to query this.
*/
*pCaps->PixelShader1xMaxValue = 8.0;
TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (*pCaps->PixelShaderVersion >> 8) & 0xff, *pCaps->PixelShaderVersion & 0xff);
} else if (ps_selected_mode == SHADER_ARB) { } else if (ps_selected_mode == SHADER_ARB) {
*pCaps->PixelShaderVersion = WINED3DPS_VERSION(1,4); *pCaps->PixelShaderVersion = WINED3DPS_VERSION(1,4);
*pCaps->PixelShader1xMaxValue = 1.0; *pCaps->PixelShader1xMaxValue = 8.0;
TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n"); TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
} else { } else {
*pCaps->PixelShaderVersion = 0; *pCaps->PixelShaderVersion = 0;
@ -2408,6 +2668,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
} else { } else {
object->surface_alignment = 4; object->surface_alignment = 4;
} }
object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
/* Set the state up as invalid until the device is fully created */ /* Set the state up as invalid until the device is fully created */
object->state = WINED3DERR_DRIVERINTERNALERROR; object->state = WINED3DERR_DRIVERINTERNALERROR;
@ -2479,9 +2740,70 @@ ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
return IUnknown_Release(volumeParent); return IUnknown_Release(volumeParent);
} }
static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
/* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
* the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
* detect the Apple OpenGL implementation to apply some extension fixups afterwards.
*
* Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
* aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
* So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
* like client storage might be supported on other implementations too, but GL_APPLE_flush_render
* is specific to the MacOS window management, and GL_APPLE_ycbcr_422 is a Quicktime specific, so
* it the chance that other implementations support it is rather rare since Win32 Quicktime uses
* DirectDraw, not OpenGL.
*/
if(gl_info->supported[APPLE_FENCE] &&
gl_info->supported[APPLE_CLIENT_STORAGE] &&
gl_info->supported[APPLE_FLUSH_RENDER] &&
gl_info->supported[APPLE_YCBCR_422]) {
TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
TRACE_(d3d_caps)("Activating MacOS fixups\n");
return TRUE;
} else {
TRACE_(d3d_caps)("Apple extensions are not supported\n");
TRACE_(d3d_caps)("Not activating MacOS fixups\n");
return FALSE;
}
}
static void fixup_extensions(WineD3D_GL_Info *gl_info) {
if(implementation_is_apple(gl_info)) {
/* MacOS advertises more GLSL vertex shader uniforms than support on hardware, and if more are
* used it falls back to software. While the compiler can detect if the shader uses all declared
* uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
* using relative addressing falls back to software.
*
* ARB vp gives the correct amount of uniforms, so use it instead of GLSL
*/
if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
} else {
TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
}
/* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
* these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
* If real NP2 textures are used, the driver falls back to software. So remove the supported
* flag for this extension
*/
if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500 ||
gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
}
}
}
}
#define PUSH1(att) attribs[nAttribs++] = (att); #define PUSH1(att) attribs[nAttribs++] = (att);
#define GLINFO_LOCATION (Adapters[0].gl_info) #define GLINFO_LOCATION (Adapters[0].gl_info)
BOOL InitAdapters(void) { BOOL InitAdapters(void) {
static HMODULE mod_gl;
BOOL ret; BOOL ret;
int ps_selected_mode, vs_selected_mode; int ps_selected_mode, vs_selected_mode;
@ -2491,77 +2813,132 @@ BOOL InitAdapters(void) {
if(numAdapters > 0) return TRUE; if(numAdapters > 0) return TRUE;
TRACE("Initializing adapters\n"); TRACE("Initializing adapters\n");
if(!mod_gl) {
#ifdef USE_WIN32_OPENGL
#define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
mod_gl = LoadLibraryA("opengl32.dll");
if(!mod_gl) {
ERR("Can't load opengl32.dll!\n");
return FALSE;
}
#else
#define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
/* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
mod_gl = GetModuleHandleA("gdi32.dll");
#endif
}
/* Load WGL core functions from opengl32.dll */
#define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
WGL_FUNCS_GEN;
#undef USE_WGL_FUNC
if(!pwglGetProcAddress) {
ERR("Unable to load wglGetProcAddress!\n");
return FALSE;
}
/* Dynamically load all GL core functions */
GL_FUNCS_GEN;
#undef USE_GL_FUNC
/* For now only one default adapter */ /* For now only one default adapter */
{ {
int iPixelFormat;
int attribs[8];
int values[8];
int nAttribs = 0;
int res;
WineD3D_PixelFormat *cfgs;
int attribute; int attribute;
DISPLAY_DEVICEW DisplayDevice; DISPLAY_DEVICEW DisplayDevice;
HDC hdc;
TRACE("Initializing default adapter\n"); TRACE("Initializing default adapter\n");
Adapters[0].monitorPoint.x = -1; Adapters[0].monitorPoint.x = -1;
Adapters[0].monitorPoint.y = -1; Adapters[0].monitorPoint.y = -1;
if (!WineD3D_CreateFakeGLContext()) {
ERR("Failed to get a gl context for default adapter\n");
HeapFree(GetProcessHeap(), 0, Adapters);
WineD3D_ReleaseFakeGLContext();
return FALSE;
}
ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info); ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
if(!ret) { if(!ret) {
ERR("Failed to initialize gl caps for default adapter\n"); ERR("Failed to initialize gl caps for default adapter\n");
HeapFree(GetProcessHeap(), 0, Adapters); HeapFree(GetProcessHeap(), 0, Adapters);
WineD3D_ReleaseFakeGLContext();
return FALSE; return FALSE;
} }
ret = initPixelFormats(&Adapters[0].gl_info); ret = initPixelFormats(&Adapters[0].gl_info);
if(!ret) { if(!ret) {
ERR("Failed to init gl formats\n"); ERR("Failed to init gl formats\n");
HeapFree(GetProcessHeap(), 0, Adapters); HeapFree(GetProcessHeap(), 0, Adapters);
WineD3D_ReleaseFakeGLContext();
return FALSE;
}
hdc = pwglGetCurrentDC();
if(!hdc) {
ERR("Failed to get gl HDC\n");
HeapFree(GetProcessHeap(), 0, Adapters);
WineD3D_ReleaseFakeGLContext();
return FALSE; return FALSE;
} }
Adapters[0].driver = "Display"; Adapters[0].driver = "Display";
Adapters[0].description = "Direct3D HAL"; Adapters[0].description = "Direct3D HAL";
/* Use the VideoRamSize registry setting when set */
if(wined3d_settings.emulated_textureram)
Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
else
Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
Adapters[0].UsedTextureRam = 0;
TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
/* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */ /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
DisplayDevice.cb = sizeof(DisplayDevice); DisplayDevice.cb = sizeof(DisplayDevice);
EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0); EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName)); TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName); strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
if (WineD3D_CreateFakeGLContext()) { attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
int iPixelFormat; GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
int attribs[8];
int values[8];
int nAttribs = 0;
int res;
WineD3D_PixelFormat *cfgs;
attribute = WGL_NUMBER_PIXEL_FORMATS_ARB; Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
GL_EXTCALL(wglGetPixelFormatAttribivARB(wined3d_fake_gl_context_hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs)); cfgs = Adapters[0].cfgs;
PUSH1(WGL_RED_BITS_ARB)
PUSH1(WGL_GREEN_BITS_ARB)
PUSH1(WGL_BLUE_BITS_ARB)
PUSH1(WGL_ALPHA_BITS_ARB)
PUSH1(WGL_DEPTH_BITS_ARB)
PUSH1(WGL_STENCIL_BITS_ARB)
Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat)); for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
cfgs = Adapters[0].cfgs; res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
PUSH1(WGL_RED_BITS_ARB)
PUSH1(WGL_GREEN_BITS_ARB)
PUSH1(WGL_BLUE_BITS_ARB)
PUSH1(WGL_ALPHA_BITS_ARB)
PUSH1(WGL_DEPTH_BITS_ARB)
PUSH1(WGL_STENCIL_BITS_ARB)
for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) { if(!res)
res = GL_EXTCALL(wglGetPixelFormatAttribivARB(wined3d_fake_gl_context_hdc, iPixelFormat, 0, nAttribs, attribs, values)); continue;
if(!res) /* Cache the pixel format */
continue; cfgs->iPixelFormat = iPixelFormat;
cfgs->redSize = values[0];
cfgs->greenSize = values[1];
cfgs->blueSize = values[2];
cfgs->alphaSize = values[3];
cfgs->depthSize = values[4];
cfgs->stencilSize = values[5];
/* Cache the pixel format */ TRACE("iPixelFormat=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d\n", cfgs->iPixelFormat, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize);
cfgs->iPixelFormat = iPixelFormat; cfgs++;
cfgs->redSize = values[0];
cfgs->greenSize = values[1];
cfgs->blueSize = values[2];
cfgs->alphaSize = values[3];
cfgs->depthSize = values[4];
cfgs->stencilSize = values[5];
TRACE("iPixelFormat=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d\n", cfgs->iPixelFormat, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize);
cfgs++;
}
WineD3D_ReleaseFakeGLContext();
} }
WineD3D_ReleaseFakeGLContext();
fixup_extensions(&Adapters[0].gl_info);
select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode); select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info); select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);

View file

@ -178,6 +178,7 @@ void primitiveDeclarationConvertToStridedData(
if (This->stateBlock->streamSource[element->Stream] == NULL) if (This->stateBlock->streamSource[element->Stream] == NULL)
continue; continue;
stride = This->stateBlock->streamStride[element->Stream];
if (This->stateBlock->streamIsUP) { if (This->stateBlock->streamIsUP) {
TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
streamVBO = 0; streamVBO = 0;
@ -185,6 +186,22 @@ void primitiveDeclarationConvertToStridedData(
} else { } else {
TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO); data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
/* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets
* (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory
* sources. In most sane cases the pointer - offset will still be > 0, otherwise it will wrap
* around to some big value. Hope that with the indices, the driver wraps it back internally. If
* not, drawStridedSlow is needed, including a vertex buffer path.
*/
if(This->stateBlock->loadBaseVertexIndex < 0) {
WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
streamVBO = 0;
data = ((IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory;
if(data + This->stateBlock->loadBaseVertexIndex * stride < 0) {
FIXME("System memory vertex data load offset is negative!\n");
}
}
if(fixup) { if(fixup) {
if( streamVBO != 0) *fixup = TRUE; if( streamVBO != 0) *fixup = TRUE;
else if(*fixup && !useVertexShaderFunction && else if(*fixup && !useVertexShaderFunction &&
@ -195,7 +212,6 @@ void primitiveDeclarationConvertToStridedData(
} }
} }
} }
stride = This->stateBlock->streamStride[element->Stream];
data += element->Offset; data += element->Offset;
reg = element->Reg; reg = element->Reg;
@ -230,7 +246,10 @@ void primitiveDeclarationConvertToStridedData(
* once in there. * once in there.
*/ */
for(i=0; i < numPreloadStreams; i++) { for(i=0; i < numPreloadStreams; i++) {
IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[streams[i]]); IWineD3DVertexBuffer *vb = This->stateBlock->streamSource[streams[i]];
if(vb) {
IWineD3DVertexBuffer_PreLoad(vb);
}
} }
} }
@ -284,7 +303,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
DWORD specularColor = 0; /* Specular Color */ DWORD specularColor = 0; /* Specular Color */
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
UINT *streamOffset = This->stateBlock->streamOffset; UINT *streamOffset = This->stateBlock->streamOffset;
DWORD SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex; long SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
BOOL pixelShader = use_ps(This);
BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL; BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
@ -334,7 +354,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
/* Default settings for data that is not passed */ /* Default settings for data that is not passed */
if (sd->u.s.normal.lpData == NULL) { if (sd->u.s.normal.lpData == NULL) {
glNormal3f(0, 0, 1); glNormal3f(0, 0, 0);
} }
if(sd->u.s.diffuse.lpData == NULL) { if(sd->u.s.diffuse.lpData == NULL) {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
@ -381,9 +401,10 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
} }
/* Query tex coords */ /* Query tex coords */
if (This->stateBlock->textures[textureNo] != NULL) { if (This->stateBlock->textures[textureNo] != NULL || pixelShader) {
int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX]; int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
int texture_idx = This->texUnitMap[textureNo];
float *ptrToCoords = NULL; float *ptrToCoords = NULL;
float s = 0.0, t = 0.0, r = 0.0, q = 0.0; float s = 0.0, t = 0.0, r = 0.0, q = 0.0;
@ -398,9 +419,13 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
ptrToCoords = (float *)(texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride)); ptrToCoords = (float *)(texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
if (texCoords[coordIdx] == NULL) { if (texCoords[coordIdx] == NULL) {
TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo); TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
} else {
glTexCoord4f(0, 0, 0, 1);
}
continue; continue;
} else { } else {
int texture_idx = This->texUnitMap[textureNo];
int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == WINED3DDECLTYPE_FLOAT1 etc */ int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == WINED3DDECLTYPE_FLOAT1 etc */
if (texture_idx == -1) continue; if (texture_idx == -1) continue;
@ -413,36 +438,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
case 1: s = ptrToCoords[0]; case 1: s = ptrToCoords[0];
} }
/* Projected is more 'fun' - Move the last coord to the 'q'
parameter (see comments under WINED3DTSS_TEXTURETRANSFORMFLAGS */
if ((This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] != WINED3DTTFF_DISABLE) &&
(This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {
if (This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED) {
switch (coordsToUse) {
case 0: /* Drop Through */
case 1:
FIXME("WINED3DTTFF_PROJECTED but only zero or one coordinate?\n");
break;
case 2:
q = t;
t = 0.0;
coordsToUse = 4;
break;
case 3:
q = r;
r = 0.0;
coordsToUse = 4;
break;
case 4: /* Nop here */
break;
default:
FIXME("Unexpected WINED3DTSS_TEXTURETRANSFORMFLAGS value of %d\n",
This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED);
}
}
}
switch (coordsToUse) { /* Supply the provided texture coords */ switch (coordsToUse) { /* Supply the provided texture coords */
case WINED3DTTFF_COUNT1: case WINED3DTTFF_COUNT1:
VTRACE(("tex:%d, s=%f\n", textureNo, s)); VTRACE(("tex:%d, s=%f\n", textureNo, s));
@ -761,7 +756,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVerte
break; break;
case WINED3DDECLTYPE_UBYTE4: case WINED3DDECLTYPE_UBYTE4:
GL_EXTCALL(glVertexAttrib4NubvARB(instancedData[j], ptr)); GL_EXTCALL(glVertexAttrib4ubvARB(instancedData[j], ptr));
break; break;
case WINED3DDECLTYPE_UBYTE4N: case WINED3DDECLTYPE_UBYTE4N:
case WINED3DDECLTYPE_D3DCOLOR: case WINED3DDECLTYPE_D3DCOLOR:
@ -834,125 +829,92 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVerte
} }
} }
struct coords { static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStridedData *s) {
int x, y, z; unsigned char i;
}; IWineD3DVertexBufferImpl *vb;
void blt_to_drawable(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *surface) { if(s->u.s.position.VBO) {
struct coords coords[4]; vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position.streamNo];
int low_coord; s->u.s.position.VBO = 0;
s->u.s.position.lpData = (BYTE *) ((unsigned long) s->u.s.position.lpData + (unsigned long) vb->resource.allocatedMemory);
/* TODO: This could be supported for lazy unlocking */ }
if(!(surface->Flags & SFLAG_INTEXTURE)) { if(s->u.s.blendWeights.VBO) {
/* It is ok at init to be nowhere */ vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendWeights.streamNo];
if(!(surface->Flags & SFLAG_INSYSMEM)) { s->u.s.blendWeights.VBO = 0;
ERR("Blitting surfaces from sysmem not supported yet\n"); s->u.s.blendWeights.lpData = (BYTE *) ((unsigned long) s->u.s.blendWeights.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.blendMatrixIndices.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendMatrixIndices.streamNo];
s->u.s.blendMatrixIndices.VBO = 0;
s->u.s.blendMatrixIndices.lpData = (BYTE *) ((unsigned long) s->u.s.blendMatrixIndices.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.normal.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal.streamNo];
s->u.s.normal.VBO = 0;
s->u.s.normal.lpData = (BYTE *) ((unsigned long) s->u.s.normal.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.pSize.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.pSize.streamNo];
s->u.s.pSize.VBO = 0;
s->u.s.pSize.lpData = (BYTE *) ((unsigned long) s->u.s.pSize.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.diffuse.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.diffuse.streamNo];
s->u.s.diffuse.VBO = 0;
s->u.s.diffuse.lpData = (BYTE *) ((unsigned long) s->u.s.diffuse.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.specular.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.specular.streamNo];
s->u.s.specular.VBO = 0;
s->u.s.specular.lpData = (BYTE *) ((unsigned long) s->u.s.specular.lpData + (unsigned long) vb->resource.allocatedMemory);
}
for(i = 0; i < WINED3DDP_MAXTEXCOORD; i++) {
if(s->u.s.texCoords[i].VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.texCoords[i].streamNo];
s->u.s.texCoords[i].VBO = 0;
s->u.s.texCoords[i].lpData = (BYTE *) ((unsigned long) s->u.s.texCoords[i].lpData + (unsigned long) vb->resource.allocatedMemory);
} }
return;
} }
if(s->u.s.position2.VBO) {
ActivateContext(This, This->render_targets[0], CTXUSAGE_BLIT); vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position2.streamNo];
ENTER_GL(); s->u.s.position2.VBO = 0;
s->u.s.position2.lpData = (BYTE *) ((unsigned long) s->u.s.position2.lpData + (unsigned long) vb->resource.allocatedMemory);
if(surface->glDescription.target == GL_TEXTURE_2D) {
glBindTexture(GL_TEXTURE_2D, surface->glDescription.textureName);
checkGLcall("GL_TEXTURE_2D, This->glDescription.textureName)");
coords[0].x = 0; coords[0].y = 0; coords[0].z = 0;
coords[1].x = 0; coords[1].y = 1; coords[1].z = 0;
coords[2].x = 1; coords[2].y = 1; coords[2].z = 0;
coords[3].x = 1; coords[3].y = 0; coords[3].z = 0;
low_coord = 0;
} else {
/* Must be a cube map */
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glEnable(surface->glDescription.target)");
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, surface->glDescription.textureName);
checkGLcall("GL_TEXTURE_CUBE_MAP_ARB, This->glDescription.textureName)");
switch(surface->glDescription.target) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
coords[0].x = 1; coords[0].y = -1; coords[0].z = 1;
coords[1].x = 1; coords[1].y = 1; coords[1].z = 1;
coords[2].x = 1; coords[2].y = 1; coords[2].z = -1;
coords[3].x = 1; coords[3].y = -1; coords[3].z = -1;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
coords[0].x = -1; coords[0].y = -1; coords[0].z = 1;
coords[1].x = -1; coords[1].y = 1; coords[1].z = 1;
coords[2].x = -1; coords[2].y = 1; coords[2].z = -1;
coords[3].x = -1; coords[3].y = -1; coords[3].z = -1;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
coords[0].x = -1; coords[0].y = 1; coords[0].z = 1;
coords[1].x = 1; coords[1].y = 1; coords[1].z = 1;
coords[2].x = 1; coords[2].y = 1; coords[2].z = -1;
coords[3].x = -1; coords[3].y = 1; coords[3].z = -1;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
coords[0].x = -1; coords[0].y = -1; coords[0].z = 1;
coords[1].x = 1; coords[1].y = -1; coords[1].z = 1;
coords[2].x = 1; coords[2].y = -1; coords[2].z = -1;
coords[3].x = -1; coords[3].y = -1; coords[3].z = -1;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
coords[0].x = -1; coords[0].y = -1; coords[0].z = 1;
coords[1].x = 1; coords[1].y = -1; coords[1].z = 1;
coords[2].x = 1; coords[2].y = -1; coords[2].z = 1;
coords[3].x = -1; coords[3].y = -1; coords[3].z = 1;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
coords[0].x = -1; coords[0].y = -1; coords[0].z = -1;
coords[1].x = 1; coords[1].y = -1; coords[1].z = -1;
coords[2].x = 1; coords[2].y = -1; coords[2].z = -1;
coords[3].x = -1; coords[3].y = -1; coords[3].z = -1;
default:
ERR("Unexpected texture target\n");
LEAVE_GL();
return;
}
low_coord = -1;
} }
if(s->u.s.normal2.VBO) {
if(This->render_offscreen) { vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal2.streamNo];
coords[0].y = coords[0].y == 1 ? low_coord : 1; s->u.s.normal2.VBO = 0;
coords[1].y = coords[1].y == 1 ? low_coord : 1; s->u.s.normal2.lpData = (BYTE *) ((unsigned long) s->u.s.normal2.lpData + (unsigned long) vb->resource.allocatedMemory);
coords[2].y = coords[2].y == 1 ? low_coord : 1;
coords[3].y = coords[3].y == 1 ? low_coord : 1;
} }
if(s->u.s.tangent.VBO) {
glBegin(GL_QUADS); vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tangent.streamNo];
glTexCoord3iv((GLint *) &coords[0]); s->u.s.tangent.VBO = 0;
glVertex2i(0, 0); s->u.s.tangent.lpData = (BYTE *) ((unsigned long) s->u.s.tangent.lpData + (unsigned long) vb->resource.allocatedMemory);
}
glTexCoord3iv((GLint *) &coords[1]); if(s->u.s.binormal.VBO) {
glVertex2i(0, surface->pow2Height); vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.binormal.streamNo];
s->u.s.binormal.VBO = 0;
glTexCoord3iv((GLint *) &coords[2]); s->u.s.binormal.lpData = (BYTE *) ((unsigned long) s->u.s.binormal.lpData + (unsigned long) vb->resource.allocatedMemory);
glVertex2i(surface->pow2Width, surface->pow2Height); }
if(s->u.s.tessFactor.VBO) {
glTexCoord3iv((GLint *) &coords[3]); vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tessFactor.streamNo];
glVertex2i(surface->pow2Width, 0); s->u.s.tessFactor.VBO = 0;
glEnd(); s->u.s.tessFactor.lpData = (BYTE *) ((unsigned long) s->u.s.tessFactor.lpData + (unsigned long) vb->resource.allocatedMemory);
checkGLcall("glEnd"); }
if(s->u.s.fog.VBO) {
if(surface->glDescription.target != GL_TEXTURE_2D) { vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.fog.streamNo];
glEnable(GL_TEXTURE_2D); s->u.s.fog.VBO = 0;
checkGLcall("glEnable(GL_TEXTURE_2D)"); s->u.s.fog.lpData = (BYTE *) ((unsigned long) s->u.s.fog.lpData + (unsigned long) vb->resource.allocatedMemory);
glDisable(GL_TEXTURE_CUBE_MAP_ARB); }
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); if(s->u.s.depth.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.depth.streamNo];
s->u.s.depth.VBO = 0;
s->u.s.depth.lpData = (BYTE *) ((unsigned long) s->u.s.depth.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.sample.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.sample.streamNo];
s->u.s.sample.VBO = 0;
s->u.s.sample.lpData = (BYTE *) ((unsigned long) s->u.s.sample.lpData + (unsigned long) vb->resource.allocatedMemory);
} }
LEAVE_GL();
} }
/* Routine common to the draw primitive and draw indexed primitive routines */ /* Routine common to the draw primitive and draw indexed primitive routines */
@ -991,33 +953,29 @@ void drawPrimitive(IWineD3DDevice *iface,
IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DSwapChain, (void **)&swapchain); IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DSwapChain, (void **)&swapchain);
/* Need the surface in the drawable! */ /* Need the surface in the drawable! */
if(!(target->Flags & SFLAG_INDRAWABLE) && (swapchain || wined3d_settings.offscreen_rendering_mode != ORM_FBO)) { IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
blt_to_drawable(This, target);
}
/* TODO: Move fbo logic to ModifyLocation */
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE);
if(swapchain) { if(swapchain) {
/* Onscreen target. Invalidate system memory copy and texture copy */ /* Onscreen target. Invalidate system memory copy and texture copy */
target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE);
target->Flags |= SFLAG_INDRAWABLE;
IWineD3DSwapChain_Release(swapchain); IWineD3DSwapChain_Release(swapchain);
} else if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) { } else if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
/* Non-FBO target: Invalidate system copy, texture copy and dirtify the container */ /* Non-FBO target: Invalidate system copy, texture copy and dirtify the container */
/* TODO: Move container dirtification to ModifyLocation */
IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DBaseTexture, (void **)&texture); IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DBaseTexture, (void **)&texture);
if(texture) { if(texture) {
IWineD3DBaseTexture_SetDirty(texture, TRUE); IWineD3DBaseTexture_SetDirty(texture, TRUE);
IWineD3DTexture_Release(texture); IWineD3DTexture_Release(texture);
} }
target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE);
target->Flags |= SFLAG_INDRAWABLE;
} else { } else {
/* FBO offscreen target. Invalidate system memory copy */ /* FBO offscreen target. Texture == Drawable */
target->Flags &= ~SFLAG_INSYSMEM; target->Flags |= SFLAG_INTEXTURE;
} }
} else { } else {
/* Must be an fbo render target */ /* Must be an fbo render target */
target->Flags &= ~SFLAG_INSYSMEM; IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE);
target->Flags |= SFLAG_INTEXTURE; target->Flags |= SFLAG_INTEXTURE;
} }
} }
@ -1050,40 +1008,24 @@ void drawPrimitive(IWineD3DDevice *iface,
if (numberOfVertices == 0 ) if (numberOfVertices == 0 )
numberOfVertices = calculatedNumberOfindices; numberOfVertices = calculatedNumberOfindices;
if(!This->strided_streams.u.s.position_transformed && !use_vs(This)) { if(!use_vs(This)) {
if(This->activeContext->num_untracked_materials && if(!This->strided_streams.u.s.position_transformed && This->activeContext->num_untracked_materials &&
This->stateBlock->renderState[WINED3DRS_LIGHTING]) { This->stateBlock->renderState[WINED3DRS_LIGHTING]) {
IWineD3DVertexBufferImpl *vb;
FIXME("Using software emulation because not all material properties could be tracked\n"); FIXME("Using software emulation because not all material properties could be tracked\n");
emulation = TRUE; emulation = TRUE;
}
else if(This->activeContext->fog_coord && This->stateBlock->renderState[WINED3DRS_FOGENABLE]) {
/* Either write a pipeline replacement shader or convert the specular alpha from unsigned byte
* to a float in the vertex buffer
*/
FIXME("Using software emulation because manual fog coordinates are provided\n");
emulation = TRUE;
}
if(emulation) {
strided = &stridedlcl; strided = &stridedlcl;
memcpy(&stridedlcl, &This->strided_streams, sizeof(stridedlcl)); memcpy(&stridedlcl, &This->strided_streams, sizeof(stridedlcl));
remove_vbos(This, &stridedlcl);
#define FIXVBO(type) \
if(stridedlcl.u.s.type.VBO) { \
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[stridedlcl.u.s.type.streamNo]; \
stridedlcl.u.s.type.VBO = 0; \
stridedlcl.u.s.type.lpData = (BYTE *) ((unsigned long) stridedlcl.u.s.type.lpData + (unsigned long) vb->resource.allocatedMemory); \
}
FIXVBO(position);
FIXVBO(blendWeights);
FIXVBO(blendMatrixIndices);
FIXVBO(normal);
FIXVBO(pSize);
FIXVBO(diffuse);
FIXVBO(specular);
for(i = 0; i < WINED3DDP_MAXTEXCOORD; i++) FIXVBO(texCoords[i]);
FIXVBO(position2);
FIXVBO(normal2);
FIXVBO(tangent);
FIXVBO(binormal);
FIXVBO(tessFactor);
FIXVBO(fog);
FIXVBO(depth);
FIXVBO(sample);
#undef FIXVBO
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -67,38 +67,30 @@ static ULONG WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface)
return InterlockedIncrement(&This->ref); return InterlockedIncrement(&This->ref);
} }
static void destroy_glsl_pshader(IWineD3DPixelShaderImpl *This) {
struct list *linked_programs = &This->baseShader.linked_programs;
TRACE("Deleting linked programs\n");
if (linked_programs->next) {
struct glsl_shader_prog_link *entry, *entry2;
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
delete_glsl_program_entry(This->baseShader.device, entry);
}
}
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
checkGLcall("glDeleteObjectARB");
}
static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) { static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) {
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
ULONG ref; ULONG ref;
TRACE("(%p) : Releasing from %d\n", This, This->ref); TRACE("(%p) : Releasing from %d\n", This, This->ref);
ref = InterlockedDecrement(&This->ref); ref = InterlockedDecrement(&This->ref);
if (ref == 0) { if (ref == 0) {
/* SetPixelShader does not AddRef. If the bound pixel shader is destroyed, the pointer in the stateblock remains
* unchanged. Drawing again will most likely crash, even on windows. A problem can occur if the application creates
* a new pixel shader which resides at the same address. Then SetPixelShader will think it is a NOP change, and won't
* dirtify the state.
*
* Do NOT call GetPixelShader here. This will addRef and cause a recursion. And do NOT set the pixel shader to NULL,
* Windows does not do that(Although no test exists since they'd crash randomly)
*/
if(iface == ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->pixelShader) {
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *) This->baseShader.device, STATE_PIXELSHADER);
}
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) { if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
struct list *linked_programs = &This->baseShader.linked_programs; destroy_glsl_pshader(This);
TRACE("Deleting linked programs\n");
if (linked_programs->next) {
struct glsl_shader_prog_link *entry, *entry2;
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
delete_glsl_program_entry(This->baseShader.device, entry);
}
}
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
checkGLcall("glDeleteObjectARB");
} }
shader_delete_constant_list(&This->baseShader.constantsF); shader_delete_constant_list(&This->baseShader.constantsF);
shader_delete_constant_list(&This->baseShader.constantsB); shader_delete_constant_list(&This->baseShader.constantsB);
@ -175,7 +167,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{WINED3DSIO_SGE, "sge", "SGE", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0}, {WINED3DSIO_SGE, "sge", "SGE", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0},
{WINED3DSIO_ABS, "abs", "ABS", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_ABS, "abs", "ABS", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_EXP, "exp", "EX2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_EXP, "exp", "EX2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_LOG, "log", "LG2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_LOG, "log", "LG2", 1, 2, pshader_hw_map2gl, shader_glsl_log, 0, 0},
{WINED3DSIO_EXPP, "expp", "EXP", 1, 2, pshader_hw_map2gl, shader_glsl_expp, 0, 0}, {WINED3DSIO_EXPP, "expp", "EXP", 1, 2, pshader_hw_map2gl, shader_glsl_expp, 0, 0},
{WINED3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_DST, "dst", "DST", 1, 3, pshader_hw_map2gl, shader_glsl_dst, 0, 0}, {WINED3DSIO_DST, "dst", "DST", 1, 3, pshader_hw_map2gl, shader_glsl_dst, 0, 0},
@ -183,28 +175,18 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{WINED3DSIO_FRC, "frc", "FRC", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_FRC, "frc", "FRC", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_CND, "cnd", NULL, 1, 4, pshader_hw_cnd, shader_glsl_cnd, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)}, {WINED3DSIO_CND, "cnd", NULL, 1, 4, pshader_hw_cnd, shader_glsl_cnd, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_CMP, "cmp", NULL, 1, 4, pshader_hw_cmp, shader_glsl_cmp, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)}, {WINED3DSIO_CMP, "cmp", NULL, 1, 4, pshader_hw_cmp, shader_glsl_cmp, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
{WINED3DSIO_POW, "pow", "POW", 1, 3, NULL, shader_glsl_pow, 0, 0}, {WINED3DSIO_POW, "pow", "POW", 1, 3, pshader_hw_map2gl, shader_glsl_pow, 0, 0},
{WINED3DSIO_CRS, "crs", "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0}, {WINED3DSIO_CRS, "crs", "XPD", 1, 3, pshader_hw_map2gl, shader_glsl_cross, 0, 0},
/* TODO: xyz normalise can be performed as VS_ARB using one temporary register, {WINED3DSIO_NRM, "nrm", NULL, 1, 2, shader_hw_nrm, shader_glsl_map2gl, 0, 0},
DP3 tmp , vec, vec; {WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, shader_hw_sincos, shader_glsl_sincos, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
RSQ tmp, tmp.x; {WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, shader_hw_sincos, shader_glsl_sincos, WINED3DPS_VERSION(3,0), -1},
MUL vec.xyz, vec, tmp; {WINED3DSIO_DP2ADD, "dp2add", NULL, 1, 4, pshader_hw_dp2add, pshader_glsl_dp2add, WINED3DPS_VERSION(2,0), -1},
but I think this is better because it accounts for w properly.
DP3 tmp , vec, vec;
RSQ tmp, tmp.x;
MUL vec, vec, tmp;
*/
{WINED3DSIO_NRM, "nrm", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, NULL, shader_glsl_sincos, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 2, NULL, shader_glsl_sincos, WINED3DPS_VERSION(3,0), -1},
/* TODO: dp2add can be made out of multiple instuctions */
{WINED3DSIO_DP2ADD, "dp2add", GLNAME_REQUIRE_GLSL, 1, 4, NULL, pshader_glsl_dp2add, WINED3DPS_VERSION(2,0), -1},
/* Matrix */ /* Matrix */
{WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
/* Register declarations */ /* Register declarations */
{WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0}, {WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0},
/* Flow control - requires GLSL or software shaders */ /* Flow control - requires GLSL or software shaders */
@ -230,15 +212,15 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
/* Texture */ /* Texture */
{WINED3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_hw_texcoord, pshader_glsl_texcoord, 0, WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_hw_texcoord, pshader_glsl_texcoord, 0, WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXCOORD, "texcrd", "undefined", 1, 2, pshader_hw_texcoord, pshader_glsl_texcoord, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, {WINED3DSIO_TEXCOORD, "texcrd", "undefined", 1, 2, pshader_hw_texcoord, pshader_glsl_texcoord, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, pshader_hw_map2gl, pshader_glsl_texkill, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)}, {WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, pshader_hw_texkill, pshader_glsl_texkill, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
{WINED3DSIO_TEX, "tex", "undefined", 1, 1, pshader_hw_tex, pshader_glsl_tex, 0, WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEX, "tex", "undefined", 1, 1, pshader_hw_tex, pshader_glsl_tex, 0, WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEX, "texld", "undefined", 1, 2, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, {WINED3DSIO_TEX, "texld", "undefined", 1, 2, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_TEX, "texld", "undefined", 1, 3, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(2,0), -1}, {WINED3DSIO_TEX, "texld", "undefined", 1, 3, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(2,0), -1},
{WINED3DSIO_TEXBEM, "texbem", "undefined", 1, 2, pshader_hw_texbem, pshader_glsl_texbem, 0, WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXBEM, "texbem", "undefined", 1, 2, pshader_hw_texbem, pshader_glsl_texbem, 0, WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, pshader_hw_texbem, pshader_glsl_texbem, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_hw_texreg2ar, pshader_glsl_texreg2ar, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_hw_texreg2ar, pshader_glsl_texreg2ar, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_hw_texreg2gb, pshader_glsl_texreg2gb, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_hw_texreg2gb, pshader_glsl_texreg2gb, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXREG2RGB, "texreg2rgb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texreg2rgb, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXREG2RGB, "texreg2rgb", "undefined", 1, 2, pshader_hw_texreg2rgb, pshader_glsl_texreg2rgb, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x2PAD, "texm3x2pad", "undefined", 1, 2, pshader_hw_texm3x2pad, pshader_glsl_texm3x2pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x2PAD, "texm3x2pad", "undefined", 1, 2, pshader_hw_texm3x2pad, pshader_glsl_texm3x2pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x2TEX, "texm3x2tex", "undefined", 1, 2, pshader_hw_texm3x2tex, pshader_glsl_texm3x2tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x2TEX, "texm3x2tex", "undefined", 1, 2, pshader_hw_texm3x2tex, pshader_glsl_texm3x2tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x3PAD, "texm3x3pad", "undefined", 1, 2, pshader_hw_texm3x3pad, pshader_glsl_texm3x3pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3PAD, "texm3x3pad", "undefined", 1, 2, pshader_hw_texm3x3pad, pshader_glsl_texm3x3pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
@ -246,11 +228,11 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", "undefined", 1, 3, pshader_hw_texm3x3spec, pshader_glsl_texm3x3spec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", "undefined", 1, 3, pshader_hw_texm3x3spec, pshader_glsl_texm3x3spec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined", 1, 2, pshader_hw_texm3x3vspec, pshader_glsl_texm3x3vspec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined", 1, 2, pshader_hw_texm3x3vspec, pshader_glsl_texm3x3vspec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x3TEX, "texm3x3tex", "undefined", 1, 2, pshader_hw_texm3x3tex, pshader_glsl_texm3x3tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3TEX, "texm3x3tex", "undefined", 1, 2, pshader_hw_texm3x3tex, pshader_glsl_texm3x3tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXDP3TEX, "texdp3tex", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3tex, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXDP3TEX, "texdp3tex", NULL, 1, 2, pshader_hw_texdp3tex, pshader_glsl_texdp3tex, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, pshader_hw_texm3x2depth, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXDP3, "texdp3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXDP3, "texdp3", NULL, 1, 2, pshader_hw_texdp3, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x3, "texm3x3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3, "texm3x3", NULL, 1, 2, pshader_hw_texm3x3, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXDEPTH, "texdepth", GLNAME_REQUIRE_GLSL, 1, 1, NULL, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, {WINED3DSIO_TEXDEPTH, "texdepth", NULL, 1, 1, pshader_hw_texdepth, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_BEM, "bem", "undefined", 1, 3, pshader_hw_bem, pshader_glsl_bem, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, {WINED3DSIO_BEM, "bem", "undefined", 1, 3, pshader_hw_bem, pshader_glsl_bem, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_DSX, "dsx", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1}, {WINED3DSIO_DSX, "dsx", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1},
{WINED3DSIO_DSY, "dsy", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1}, {WINED3DSIO_DSY, "dsy", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1},
@ -379,8 +361,18 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION); shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
/* Pack 3.0 inputs */ /* Pack 3.0 inputs */
if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
pshader_glsl_input_pack(&buffer, This->semantics_in);
if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed) {
This->vertexprocessing = pretransformed;
pshader_glsl_input_pack(&buffer, This->semantics_in, iface);
} else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device)) {
This->vertexprocessing = fixedfunction;
pshader_glsl_input_pack(&buffer, This->semantics_in, iface);
} else {
This->vertexprocessing = vertexshader;
}
}
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
@ -407,6 +399,23 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
else else
shader_addline(&buffer, "gl_FragColor.xyz = mix(gl_Fog.color.xyz, gl_FragColor.xyz, Fog);\n"); shader_addline(&buffer, "gl_FragColor.xyz = mix(gl_Fog.color.xyz, gl_FragColor.xyz, Fog);\n");
} }
if(This->srgb_enabled) {
const char *fragcolor;
if(GL_SUPPORT(ARB_DRAW_BUFFERS)) {
fragcolor = "gl_FragData[0]";
} else {
fragcolor = "gl_FragColor";
}
shader_addline(&buffer, "tmp0.xyz = pow(%s.xyz, vec3(%f, %f, %f)) * vec3(%f, %f, %f) - vec3(%f, %f, %f);\n",
fragcolor, srgb_pow, srgb_pow, srgb_pow, srgb_mul_high, srgb_mul_high, srgb_mul_high,
srgb_sub_high, srgb_sub_high, srgb_sub_high);
shader_addline(&buffer, "tmp1.xyz = %s.xyz * srgb_mul_low.xyz;\n", fragcolor);
shader_addline(&buffer, "%s.x = %s.x < srgb_comparison.x ? tmp1.x : tmp0.x;\n", fragcolor, fragcolor);
shader_addline(&buffer, "%s.y = %s.y < srgb_comparison.y ? tmp1.y : tmp0.y;\n", fragcolor, fragcolor);
shader_addline(&buffer, "%s.z = %s.z < srgb_comparison.z ? tmp1.z : tmp0.z;\n", fragcolor, fragcolor);
shader_addline(&buffer, "%s = clamp(%s, 0.0, 1.0);\n", fragcolor, fragcolor);
}
shader_addline(&buffer, "}\n"); shader_addline(&buffer, "}\n");
@ -448,12 +457,41 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
* -1/(e-s) and e/(e-s) respectively. * -1/(e-s) and e/(e-s) respectively.
*/ */
shader_addline(&buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n"); shader_addline(&buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
shader_addline(&buffer, "LRP result.color.rgb, TMP_FOG.x, R0, state.fog.color;\n"); if(This->srgb_enabled) {
shader_addline(&buffer, "MOV result.color.a, R0.a;\n"); if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
shader_addline(&buffer, "LRP TMP_COLOR.rgb, TMP_FOG.x, R0, state.fog.color;\n");
shader_addline(&buffer, "MOV result.color.a, R0.a;\n");
} else {
shader_addline(&buffer, "LRP TMP_COLOR.rgb, TMP_FOG.x, TMP_COLOR, state.fog.color;\n");
shader_addline(&buffer, "MOV result.color.a, TMP_COLOR.a;\n");
}
/* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
/* Calculate the > 0.0031308 case */
shader_addline(&buffer, "POW TMP.x, TMP_COLOR.x, srgb_pow.x;\n");
shader_addline(&buffer, "POW TMP.y, TMP_COLOR.y, srgb_pow.y;\n");
shader_addline(&buffer, "POW TMP.z, TMP_COLOR.z, srgb_pow.z;\n");
shader_addline(&buffer, "MUL TMP, TMP, srgb_mul_hi;\n");
shader_addline(&buffer, "SUB TMP, TMP, srgb_sub_hi;\n");
/* Calculate the < case */
shader_addline(&buffer, "MUL TMP2, srgb_mul_low, TMP_COLOR;\n");
/* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
shader_addline(&buffer, "SLT TA, srgb_comparison, TMP_COLOR;\n");
shader_addline(&buffer, "SGE TB, srgb_comparison, TMP_COLOR;\n");
/* Store the components > 0.0031308 in the destination */
shader_addline(&buffer, "MUL TMP_COLOR, TMP, TA;\n");
/* Add the components that are < 0.0031308 */
shader_addline(&buffer, "MAD result.color.xyz, TMP2, TB, TMP_COLOR;\n");
/* [0.0;1.0] clamping. Not needed, this is done implicitly */
} else { } else {
shader_addline(&buffer, "LRP result.color.rgb, TMP_FOG.x, TMP_COLOR, state.fog.color;\n"); if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
shader_addline(&buffer, "MOV result.color.a, TMP_COLOR.a;\n"); shader_addline(&buffer, "LRP result.color.rgb, TMP_FOG.x, R0, state.fog.color;\n");
shader_addline(&buffer, "MOV result.color.a, R0.a;\n");
} else {
shader_addline(&buffer, "LRP result.color.rgb, TMP_FOG.x, TMP_COLOR, state.fog.color;\n");
shader_addline(&buffer, "MOV result.color.a, TMP_COLOR.a;\n");
}
} }
shader_addline(&buffer, "END\n"); shader_addline(&buffer, "END\n");
@ -504,6 +542,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) > 1) { if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) > 1) {
shader_reg_maps *reg_maps = &This->baseShader.reg_maps; shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
HRESULT hr; HRESULT hr;
unsigned int i, j, highest_reg_used = 0, num_regs_used = 0;
/* Second pass: figure out which registers are used, what the semantics are, etc.. */ /* Second pass: figure out which registers are used, what the semantics are, etc.. */
memset(reg_maps, 0, sizeof(shader_reg_maps)); memset(reg_maps, 0, sizeof(shader_reg_maps));
@ -511,6 +550,41 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
This->semantics_in, NULL, pFunction, NULL); This->semantics_in, NULL, pFunction, NULL);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
/* FIXME: validate reg_maps against OpenGL */ /* FIXME: validate reg_maps against OpenGL */
for(i = 0; i < MAX_REG_INPUT; i++) {
if(This->input_reg_used[i]) {
num_regs_used++;
highest_reg_used = i;
}
}
/* Don't do any register mapping magic if it is not needed, or if we can't
* achive anything anyway
*/
if(highest_reg_used < (GL_LIMITS(glsl_varyings) / 4) ||
num_regs_used > (GL_LIMITS(glsl_varyings) / 4) ) {
if(num_regs_used > (GL_LIMITS(glsl_varyings) / 4)) {
/* This happens with relative addressing. The input mapper function
* warns about this if the higher registers are declared too, so
* don't write a FIXME here
*/
WARN("More varying registers used than supported\n");
}
for(i = 0; i < MAX_REG_INPUT; i++) {
This->input_reg_map[i] = i;
}
} else {
j = 0;
for(i = 0; i < MAX_REG_INPUT; i++) {
if(This->input_reg_used[i]) {
This->input_reg_map[i] = j;
j++;
} else {
This->input_reg_map[i] = -1;
}
}
}
} }
This->baseShader.shader_mode = deviceImpl->ps_selected_mode; This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
@ -535,11 +609,76 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
CONST DWORD *function = This->baseShader.function; CONST DWORD *function = This->baseShader.function;
UINT i, sampler;
IWineD3DBaseTextureImpl *texture;
TRACE("(%p) : function %p\n", iface, function); TRACE("(%p) : function %p\n", iface, function);
/* We're already compiled. */ /* We're already compiled, but check if any of the hardcoded stateblock assumptions
if (This->baseShader.is_compiled) return WINED3D_OK; * changed.
*/
if (This->baseShader.is_compiled) {
char srgbenabled = deviceImpl->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
for(i = 0; i < This->baseShader.num_sampled_samplers; i++) {
sampler = This->baseShader.sampled_samplers[i];
texture = (IWineD3DBaseTextureImpl *) deviceImpl->stateBlock->textures[sampler];
if(texture && texture->baseTexture.shader_conversion_group != This->baseShader.sampled_format[sampler]) {
WARN("Recompiling shader %p due to format change on sampler %d\n", This, sampler);
WARN("Old format group %s, new is %s\n",
debug_d3dformat(This->baseShader.sampled_format[sampler]),
debug_d3dformat(texture->baseTexture.shader_conversion_group));
goto recompile;
}
}
/* TODO: Check projected textures */
/* TODO: Check texture types(2D, Cube, 3D) */
if(srgbenabled != This->srgb_enabled && This->srgb_mode_hardcoded) {
WARN("Recompiling shader because srgb correction is different and hardcoded\n");
goto recompile;
}
if(This->baseShader.reg_maps.vpos && !This->vpos_uniform) {
if(This->render_offscreen != deviceImpl->render_offscreen ||
This->height != ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height) {
WARN("Recompiling shader because vpos is used, hard compiled and changed\n");
goto recompile;
}
}
if(This->baseShader.reg_maps.usesdsy && !This->vpos_uniform) {
if(This->render_offscreen ? 0 : 1 != deviceImpl->render_offscreen ? 0 : 1) {
WARN("Recompiling shader because dsy is used, hard compiled and render_offscreen changed\n");
goto recompile;
}
}
if(This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed &&
This->vertexprocessing != pretransformed) {
WARN("Recompiling shader because pretransformed vertices are provided, which wasn't the case before\n");
goto recompile;
} else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device) &&
This->vertexprocessing != fixedfunction) {
WARN("Recompiling shader because fixed function vp is in use, which wasn't the case before\n");
goto recompile;
} else if(This->vertexprocessing != vertexshader) {
WARN("Recompiling shader because vertex shaders are in use, which wasn't the case before\n");
goto recompile;
}
}
return WINED3D_OK;
recompile:
if(This->baseShader.recompile_count > 50) {
FIXME("Shader %p recompiled more than 50 times\n", This);
} else {
This->baseShader.recompile_count++;
}
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
destroy_glsl_pshader(This);
}
}
/* We don't need to compile */ /* We don't need to compile */
if (!function) { if (!function) {
@ -559,6 +698,9 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader
/* FIXME: validate reg_maps against OpenGL */ /* FIXME: validate reg_maps against OpenGL */
} }
/* Reset fields tracking stateblock values being hardcoded in the shader */
This->baseShader.num_sampled_samplers = 0;
/* Generate the HW shader */ /* Generate the HW shader */
TRACE("(%p) : Generating hardware program\n", This); TRACE("(%p) : Generating hardware program\n", This);
IWineD3DPixelShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function); IWineD3DPixelShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);

View file

@ -167,7 +167,12 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
case WINED3DQUERYTYPE_EVENT: case WINED3DQUERYTYPE_EVENT:
{ {
BOOL* data = pData; BOOL* data = pData;
if(GL_SUPPORT(APPLE_FENCE)) { WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
/* See comment in IWineD3DQuery::Issue, event query codeblock */
WARN("Query context not active, reporting GPU idle\n");
*data = TRUE;
} else if(GL_SUPPORT(APPLE_FENCE)) {
*data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId)); *data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
checkGLcall("glTestFenceAPPLE"); checkGLcall("glTestFenceAPPLE");
} else if(GL_SUPPORT(NV_FENCE)) { } else if(GL_SUPPORT(NV_FENCE)) {
@ -182,7 +187,9 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
case WINED3DQUERYTYPE_OCCLUSION: case WINED3DQUERYTYPE_OCCLUSION:
{ {
DWORD* data = pData; DWORD* data = pData;
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) { if (GL_SUPPORT(ARB_OCCLUSION_QUERY) &&
((WineQueryOcclusionData *)This->extendedData)->ctx == This->wineD3DDevice->activeContext &&
This->wineD3DDevice->activeContext->tid == GetCurrentThreadId()) {
GLuint available; GLuint available;
GLuint samples; GLuint samples;
GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId; GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
@ -201,7 +208,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
res = S_FALSE; res = S_FALSE;
} }
} else { } else {
FIXME("(%p) : Occlusion queries not supported. Returning 1.\n", This); WARN("(%p) : Occlusion queries not supported, or wrong context. Returning 1.\n", This);
*data = 1; *data = 1;
res = S_OK; res = S_OK;
} }
@ -375,13 +382,19 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
switch (This->type) { switch (This->type) {
case WINED3DQUERYTYPE_OCCLUSION: case WINED3DQUERYTYPE_OCCLUSION:
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) { if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
if (dwIssueFlags & WINED3DISSUE_BEGIN) { WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, ((WineQueryOcclusionData *)This->extendedData)->queryId));
checkGLcall("glBeginQuery()"); if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
} WARN("Not the owning context, can't start query\n");
if (dwIssueFlags & WINED3DISSUE_END) { } else {
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); if (dwIssueFlags & WINED3DISSUE_BEGIN) {
checkGLcall("glEndQuery()"); GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, ((WineQueryOcclusionData *)This->extendedData)->queryId));
checkGLcall("glBeginQuery()");
}
if (dwIssueFlags & WINED3DISSUE_END) {
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
checkGLcall("glEndQuery()");
}
} }
} else { } else {
FIXME("(%p) : Occlusion queries not supported\n", This); FIXME("(%p) : Occlusion queries not supported\n", This);
@ -390,7 +403,17 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
case WINED3DQUERYTYPE_EVENT: { case WINED3DQUERYTYPE_EVENT: {
if (dwIssueFlags & WINED3DISSUE_END) { if (dwIssueFlags & WINED3DISSUE_END) {
if(GL_SUPPORT(APPLE_FENCE)) { WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
/* GL fences can be used only from the context that created them,
* so if a different context is active, don't bother setting the query. The penalty
* of a context switch is most likely higher than the gain of a correct query result
*
* If the query is used from a different thread, don't bother creating a multithread
* context - there's no point in doing that as the query would be unusable anyway
*/
WARN("Query context not active\n");
} else if(GL_SUPPORT(APPLE_FENCE)) {
GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId)); GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
checkGLcall("glSetFenceAPPLE"); checkGLcall("glSetFenceAPPLE");
} else if (GL_SUPPORT(NV_FENCE)) { } else if (GL_SUPPORT(NV_FENCE)) {

View file

@ -71,7 +71,7 @@ void IWineD3DResourceImpl_CleanUp(IWineD3DResource *iface){
TRACE("(%p) Cleaning up resource\n", This); TRACE("(%p) Cleaning up resource\n", This);
if (This->resource.pool == WINED3DPOOL_DEFAULT) { if (This->resource.pool == WINED3DPOOL_DEFAULT) {
TRACE("Decrementing device memory pool by %u\n", This->resource.size); TRACE("Decrementing device memory pool by %u\n", This->resource.size);
globalChangeGlRam(-This->resource.size); WineD3DAdapterChangeGLRam(This->resource.wineD3DDevice, -This->resource.size);
} }
LIST_FOR_EACH_SAFE(e1, e2, &This->resource.privateData) { LIST_FOR_EACH_SAFE(e1, e2, &This->resource.privateData) {
@ -82,8 +82,9 @@ void IWineD3DResourceImpl_CleanUp(IWineD3DResource *iface){
} }
} }
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory); HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
This->resource.allocatedMemory = 0; This->resource.allocatedMemory = 0;
This->resource.heapMemory = 0;
if (This->resource.wineD3DDevice != NULL) { if (This->resource.wineD3DDevice != NULL) {
IWineD3DDevice_ResourceReleased((IWineD3DDevice *)This->resource.wineD3DDevice, iface); IWineD3DDevice_ResourceReleased((IWineD3DDevice *)This->resource.wineD3DDevice, iface);
@ -137,6 +138,7 @@ HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData(IWineD3DResource *iface, REFG
if (Flags & WINED3DSPD_IUNKNOWN) { if (Flags & WINED3DSPD_IUNKNOWN) {
if(SizeOfData != sizeof(IUnknown *)) { if(SizeOfData != sizeof(IUnknown *)) {
WARN("IUnknown data with size %d, returning WINED3DERR_INVALIDCALL\n", SizeOfData); WARN("IUnknown data with size %d, returning WINED3DERR_INVALIDCALL\n", SizeOfData);
HeapFree(GetProcessHeap(), 0, data);
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
data->ptr.object = (LPUNKNOWN)pData; data->ptr.object = (LPUNKNOWN)pData;

View file

@ -132,11 +132,9 @@ static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
} }
static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
/* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */ /* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering
* switch
/* If we are culling "back faces with clockwise vertices" then */
set front faces to be counter clockwise and enable culling
of back faces */
switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) { switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
case WINED3DCULL_NONE: case WINED3DCULL_NONE:
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -145,26 +143,14 @@ static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
case WINED3DCULL_CW: case WINED3DCULL_CW:
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
checkGLcall("glEnable GL_CULL_FACE"); checkGLcall("glEnable GL_CULL_FACE");
if (stateblock->wineD3DDevice->render_offscreen) { glCullFace(GL_FRONT);
glFrontFace(GL_CW); checkGLcall("glCullFace(GL_FRONT)");
checkGLcall("glFrontFace GL_CW");
} else {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace GL_CCW");
}
glCullFace(GL_BACK);
break; break;
case WINED3DCULL_CCW: case WINED3DCULL_CCW:
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
checkGLcall("glEnable GL_CULL_FACE"); checkGLcall("glEnable GL_CULL_FACE");
if (stateblock->wineD3DDevice->render_offscreen) {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace GL_CCW");
} else {
glFrontFace(GL_CW);
checkGLcall("glFrontFace GL_CW");
}
glCullFace(GL_BACK); glCullFace(GL_BACK);
checkGLcall("glCullFace(GL_BACK)");
break; break;
default: default:
FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]); FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
@ -216,6 +202,20 @@ static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]); int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
if(glParm) { if(glParm) {
if(glParm == GL_EQUAL || glParm == GL_NOTEQUAL) {
static BOOL once = FALSE;
/* There are a few issues with this: First, our inability to
* select a proper Z depth, most of the time we're stuck with
* D24S8, even if the app selects D32 or D16. There seem to be
* some other precision problems which have to be debugged to
* make NOTEQUAL and EQUAL work properly
*/
if(!once) {
once = TRUE;
FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet\n");
}
}
glDepthFunc(glParm); glDepthFunc(glParm);
checkGLcall("glDepthFunc"); checkGLcall("glDepthFunc");
} }
@ -247,33 +247,6 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
return; return;
}; };
switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
case WINED3DBLEND_DESTALPHA : srcBlend = GL_DST_ALPHA; break;
case WINED3DBLEND_INVDESTALPHA : srcBlend = GL_ONE_MINUS_DST_ALPHA; break;
case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
dstBlend = GL_SRC_ALPHA;
break;
case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
dstBlend = GL_ONE_MINUS_SRC_ALPHA;
break;
case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
default:
FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
}
switch (stateblock->renderState[WINED3DRS_DESTBLEND]) { switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break; case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break;
case WINED3DBLEND_ONE : dstBlend = GL_ONE; break; case WINED3DBLEND_ONE : dstBlend = GL_ONE; break;
@ -291,12 +264,17 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n"); WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
break; break;
/* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
* values which are still valid up to d3d9. They should not occur as dest blend values
*/
case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA; case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
srcBlend = GL_SRC_ALPHA; srcBlend = GL_SRC_ALPHA;
FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
break; break;
case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
srcBlend = GL_ONE_MINUS_SRC_ALPHA; srcBlend = GL_ONE_MINUS_SRC_ALPHA;
FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
break; break;
case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break; case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
@ -305,6 +283,34 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]); FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
} }
switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
case WINED3DBLEND_DESTALPHA : srcBlend = GL_DST_ALPHA; break;
case WINED3DBLEND_INVDESTALPHA : srcBlend = GL_ONE_MINUS_DST_ALPHA; break;
case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
dstBlend = GL_ONE_MINUS_SRC_ALPHA;
break;
case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
dstBlend = GL_SRC_ALPHA;
break;
case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
default:
FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
}
if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] || if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) { stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
@ -330,7 +336,7 @@ static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, W
TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]); TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col); D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
GL_EXTCALL(glBlendColor (col[0],col[1],col[2],col[3])); GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
checkGLcall("glBlendColor"); checkGLcall("glBlendColor");
} }
@ -423,9 +429,17 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
if (stateblock->renderState[WINED3DRS_CLIPPING]) { if (stateblock->renderState[WINED3DRS_CLIPPING]) {
enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]; enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]; disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
glDisable(GL_DEPTH_CLAMP_NV);
checkGLcall("glDisable(GL_DEPTH_CLAMP_NV)");
}
} else { } else {
disable = 0xffffffff; disable = 0xffffffff;
enable = 0x00; enable = 0x00;
if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
glEnable(GL_DEPTH_CLAMP_NV);
checkGLcall("glEnable(GL_DEPTH_CLAMP_NV)");
}
} }
if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); } if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
@ -471,7 +485,7 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
} }
TRACE("glBlendEquation(%x)\n", glParm); TRACE("glBlendEquation(%x)\n", glParm);
GL_EXTCALL(glBlendEquation(glParm)); GL_EXTCALL(glBlendEquationEXT(glParm));
checkGLcall("glBlendEquation"); checkGLcall("glBlendEquation");
} }
@ -661,7 +675,7 @@ state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *c
if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) ) if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
func = GL_ALWAYS; func = GL_ALWAYS;
if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) ) if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
func = GL_ALWAYS; func_ccw = GL_ALWAYS;
ref = stateblock->renderState[WINED3DRS_STENCILREF]; ref = stateblock->renderState[WINED3DRS_STENCILREF];
mask = stateblock->renderState[WINED3DRS_STENCILMASK]; mask = stateblock->renderState[WINED3DRS_STENCILMASK];
stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]); stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
@ -678,29 +692,55 @@ state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *c
func, stencilFail, depthFail, stencilPass, func, stencilFail, depthFail, stencilPass,
func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw); func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
if (twosided_enable) { if (twosided_enable && onesided_enable) {
renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass); glEnable(GL_STENCIL_TEST);
checkGLcall("glEnable GL_STENCIL_TEST");
/* Apply back first, then front. This function calls glActiveStencilFaceEXT,
* which has an effect on the code below too. If we apply the front face
* afterwards, we are sure that the active stencil face is set to front,
* and other stencil functions which do not use two sided stencil do not have
* to set it back
*/
renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw); renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
} else { renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
if (onesided_enable) { } else if(onesided_enable) {
glEnable(GL_STENCIL_TEST); if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
checkGLcall("glEnable GL_STENCIL_TEST"); glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
glStencilFunc(func, ref, mask); checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
checkGLcall("glStencilFunc(...)");
glStencilOp(stencilFail, depthFail, stencilPass);
checkGLcall("glStencilOp(...)");
} else {
glDisable(GL_STENCIL_TEST);
checkGLcall("glDisable GL_STENCIL_TEST");
} }
glEnable(GL_STENCIL_TEST);
checkGLcall("glEnable GL_STENCIL_TEST");
glStencilFunc(func, ref, mask);
checkGLcall("glStencilFunc(...)");
glStencilOp(stencilFail, depthFail, stencilPass);
checkGLcall("glStencilOp(...)");
} else {
glDisable(GL_STENCIL_TEST);
checkGLcall("glDisable GL_STENCIL_TEST");
} }
} }
static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD mask;
if(stateblock->wineD3DDevice->stencilBufferTarget) { if(stateblock->wineD3DDevice->stencilBufferTarget) {
glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]); mask = stateblock->renderState[WINED3DRS_STENCILWRITEMASK];
} else { } else {
glStencilMask(0); mask = 0;
}
if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
glStencilMask(mask);
checkGLcall("glStencilMask");
GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
glStencilMask(mask);
} else {
glStencilMask(mask);
} }
checkGLcall("glStencilMask"); checkGLcall("glStencilMask");
} }
@ -796,6 +836,12 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
fogstart = 1.0; fogstart = 1.0;
fogend = 0.0; fogend = 0.0;
} }
if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
context->last_was_foggy_shader = TRUE; context->last_was_foggy_shader = TRUE;
} }
else if( use_ps(stateblock->wineD3DDevice) ) { else if( use_ps(stateblock->wineD3DDevice) ) {
@ -831,6 +877,12 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
break; break;
default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]); default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
} }
if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
} }
/* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes, /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
* the system will apply only pixel(=table) fog effects." * the system will apply only pixel(=table) fog effects."
@ -846,9 +898,10 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
if(!context->last_was_rhw) { if(!context->last_was_rhw) {
glFogi(GL_FOG_MODE, GL_EXP); glFogi(GL_FOG_MODE, GL_EXP);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT"); checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
} }
break; break;
} }
@ -857,9 +910,10 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
if(!context->last_was_rhw) { if(!context->last_was_rhw) {
glFogi(GL_FOG_MODE, GL_EXP2); glFogi(GL_FOG_MODE, GL_EXP2);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT"); checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
} }
break; break;
} }
@ -868,9 +922,10 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
if(!context->last_was_rhw) { if(!context->last_was_rhw) {
glFogi(GL_FOG_MODE, GL_LINEAR); glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT"); checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
} }
break; break;
} }
@ -881,8 +936,11 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
* Same happens with Vertexfog on transformed vertices * Same happens with Vertexfog on transformed vertices
*/ */
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD)) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); if(context->fog_coord == FALSE) {
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n"); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
context->fog_coord = TRUE;
}
glFogi(GL_FOG_MODE, GL_LINEAR); glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
fogstart = 0xff; fogstart = 0xff;
@ -904,27 +962,30 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
case WINED3DFOG_EXP: case WINED3DFOG_EXP:
glFogi(GL_FOG_MODE, GL_EXP); glFogi(GL_FOG_MODE, GL_EXP);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT"); checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
} }
break; break;
case WINED3DFOG_EXP2: case WINED3DFOG_EXP2:
glFogi(GL_FOG_MODE, GL_EXP2); glFogi(GL_FOG_MODE, GL_EXP2);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT"); checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
} }
break; break;
case WINED3DFOG_LINEAR: case WINED3DFOG_LINEAR:
glFogi(GL_FOG_MODE, GL_LINEAR); glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
if(GL_SUPPORT(EXT_FOG_COORD)) { if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT"); checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
} }
break; break;
@ -938,13 +999,26 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
glEnable(GL_FOG); glEnable(GL_FOG);
checkGLcall("glEnable GL_FOG"); checkGLcall("glEnable GL_FOG");
glFogfv(GL_FOG_START, &fogstart); if(fogstart != fogend)
checkGLcall("glFogf(GL_FOG_START, fogstart"); {
TRACE("Fog Start == %f\n", fogstart); glFogfv(GL_FOG_START, &fogstart);
checkGLcall("glFogf(GL_FOG_START, fogstart");
TRACE("Fog Start == %f\n", fogstart);
glFogfv(GL_FOG_END, &fogend); glFogfv(GL_FOG_END, &fogend);
checkGLcall("glFogf(GL_FOG_END, fogend"); checkGLcall("glFogf(GL_FOG_END, fogend");
TRACE("Fog End == %f\n", fogend); TRACE("Fog End == %f\n", fogend);
}
else
{
glFogf(GL_FOG_START, -1.0 / 0.0);
checkGLcall("glFogf(GL_FOG_START, fogstart");
TRACE("Fog Start == %f\n", fogstart);
glFogf(GL_FOG_END, 0.0);
checkGLcall("glFogf(GL_FOG_END, fogend");
TRACE("Fog End == %f\n", fogend);
}
} else { } else {
glDisable(GL_FOG); glDisable(GL_FOG);
checkGLcall("glDisable GL_FOG"); checkGLcall("glDisable GL_FOG");
@ -959,9 +1033,21 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
checkGLcall("glFogf(GL_FOG_END, fogend"); checkGLcall("glFogf(GL_FOG_END, fogend");
} }
} }
}
if (GL_SUPPORT(NV_FOG_DISTANCE)) { static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV); if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
if (GL_SUPPORT(NV_FOG_DISTANCE)) {
glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
} else {
WARN("Range fog enabled, but not supported by this opengl implementation\n");
}
} else {
if (GL_SUPPORT(NV_FOG_DISTANCE)) {
glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
}
} }
} }
@ -1144,7 +1230,16 @@ static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) { if(isStateDirty(context, STATE_VDECL)) {
return;
}
/* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
* from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
* by zero and is not properly defined in opengl, so avoid it
*/
if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS] && (
stateblock->wineD3DDevice->strided_streams.u.s.normal.lpData ||
stateblock->wineD3DDevice->strided_streams.u.s.normal.VBO)) {
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
checkGLcall("glEnable(GL_NORMALIZE);"); checkGLcall("glEnable(GL_NORMALIZE);");
} else { } else {
@ -1153,19 +1248,6 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
} }
} }
static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
union {
DWORD d;
float f;
} tmpvalue;
/* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
TRACE("Set point size to %f\n", tmpvalue.f);
glPointSize(tmpvalue.f);
checkGLcall("glPointSize(...);");
}
static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
union { union {
DWORD d; DWORD d;
@ -1216,31 +1298,49 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
/* Default values */ /* Default values */
GLfloat att[3] = {1.0f, 0.0f, 0.0f}; GLfloat att[3] = {1.0f, 0.0f, 0.0f};
union {
DWORD d;
float f;
} pointSize, A, B, C;
/* pointSize.d = stateblock->renderState[WINED3DRS_POINTSIZE];
* Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f. A.d = stateblock->renderState[WINED3DRS_POINTSCALE_A];
* This means that OpenGL will clamp really small point sizes to 1.0f. B.d = stateblock->renderState[WINED3DRS_POINTSCALE_B];
* To correct for this we need to multiply by the scale factor when sizes C.d = stateblock->renderState[WINED3DRS_POINTSCALE_C];
* are less than 1.0f. scale_factor = 1.0f / point_size.
*/ if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
if(pointSize > 0.0f) {
GLfloat scaleFactor; GLfloat scaleFactor;
float h = stateblock->viewport.Height;
if(pointSize < 1.0f) { if(pointSize.f < GL_LIMITS(pointsizemin)) {
scaleFactor = pointSize * pointSize; /*
* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
* 0.0f. This means that OpenGL will clamp really small point sizes to the
* driver minimum. To correct for this we need to multiply by the scale factor when sizes
* are less than 1.0f. scale_factor = 1.0f / point_size.
*/
scaleFactor = pointSize.f / GL_LIMITS(pointsizemin);
/* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
* is 1.0, but then accepts points below that and draws too small points
*/
pointSize.f = GL_LIMITS(pointsizemin);
} else if(pointSize.f > GL_LIMITS(pointsize)) {
/* gl already scales the input to glPointSize,
* d3d scales the result after the point size scale.
* If the point size is bigger than the max size, use the
* scaling to scale it bigger, and set the gl point size to max
*/
scaleFactor = pointSize.f / GL_LIMITS(pointsize);
TRACE("scale: %f\n", scaleFactor);
pointSize.f = GL_LIMITS(pointsize);
} else { } else {
scaleFactor = 1.0f; scaleFactor = 1.0f;
} }
scaleFactor = pow(h * scaleFactor, 2);
if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) { att[0] = A.f / scaleFactor;
att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) / att[1] = B.f / scaleFactor;
(stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor); att[2] = C.f / scaleFactor;
att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
(stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
(stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
}
} }
if(GL_SUPPORT(ARB_POINT_PARAMETERS)) { if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
@ -1250,9 +1350,12 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) { else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att); GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ..."); checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
} else { } else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
TRACE("POINT_PARAMETERS not supported in this version of opengl\n"); WARN("POINT_PARAMETERS not supported in this version of opengl\n");
} }
glPointSize(pointSize.f);
checkGLcall("glPointSize(...);");
} }
static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
@ -1468,12 +1571,6 @@ static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock,
FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]); FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
} }
static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
FIXME("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
}
static void state_separateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void state_separateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
TRACE("Stub\n"); TRACE("Stub\n");
if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
@ -1807,6 +1904,13 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0); DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit]; DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
/* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
if(use_vs(stateblock->wineD3DDevice) ||
isStateDirty(context, STATE_VDECL)) {
TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
return;
}
if (mapped_stage < 0) return; if (mapped_stage < 0) return;
if (GL_SUPPORT(ARB_MULTITEXTURE)) { if (GL_SUPPORT(ARB_MULTITEXTURE)) {
@ -1823,7 +1927,11 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU); (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU,
context->last_was_rhw,
stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ?
stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType:
WINED3DDECLTYPE_UNUSED);
} }
@ -2067,6 +2175,20 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
} }
} }
static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
/* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
* has an update pending
*/
if(isStateDirty(context, STATE_VDECL) ||
isStateDirty(context, STATE_PIXELSHADER)) {
return;
}
device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
}
static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE; DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
union { union {
@ -2074,6 +2196,17 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, W
float f; float f;
} tmpvalue; } tmpvalue;
if(stateblock->pixelShader && stage != 0 &&
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams == stage) {
/* The pixel shader has to know the luminance scale. Do a constants update if it
* isn't scheduled anyway
*/
if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
!isStateDirty(context, STATE_PIXELSHADER)) {
shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
}
}
tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE]; tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
if(tmpvalue.f != 0.0) { if(tmpvalue.f != 0.0) {
FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n"); FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
@ -2087,6 +2220,17 @@ static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock,
float f; float f;
} tmpvalue; } tmpvalue;
if(stateblock->pixelShader && stage != 0 &&
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams == stage) {
/* The pixel shader has to know the luminance offset. Do a constants update if it
* isn't scheduled anyway
*/
if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
!isStateDirty(context, STATE_PIXELSHADER)) {
shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
}
}
tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET]; tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
if(tmpvalue.f != 0.0) { if(tmpvalue.f != 0.0) {
FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n"); FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
@ -2206,20 +2350,6 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
} }
} }
static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
/* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
* has an update pending
*/
if(isStateDirty(context, STATE_VDECL) ||
isStateDirty(context, STATE_PIXELSHADER)) {
return;
}
device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
}
static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
BOOL use_pshader = use_ps(device); BOOL use_pshader = use_ps(device);
@ -2435,8 +2565,12 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, W
stateblock->wineD3DDevice->vertexBlendUsed = TRUE; stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
} }
} else { } else {
/* TODO: Implement vertex blending in drawStridedSlow */ static BOOL once = FALSE;
FIXME("Vertex blending enabled, but not supported by hardware\n"); if(!once) {
once = TRUE;
/* TODO: Implement vertex blending in drawStridedSlow */
FIXME("Vertex blending enabled, but not supported by hardware\n");
}
} }
break; break;
@ -2543,7 +2677,23 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
/* Transformed vertices are supposed to bypass the whole transform pipeline including /* Transformed vertices are supposed to bypass the whole transform pipeline including
* frustum clipping. This can't be done in opengl, so this code adjusts the Z range to * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
* suppress depth clipping. This can be done because it is an orthogonal projection and * suppress depth clipping. This can be done because it is an orthogonal projection and
* the Z coordinate does not affect the size of the primitives * the Z coordinate does not affect the size of the primitives. Half Life 1 and Prince of
* Persia 3D need this.
*
* Note that using minZ and maxZ here doesn't entirely fix the problem, since view frustum
* clipping is still enabled, but it seems to fix it for all apps tested so far. A minor
* problem can be witnessed in half-life 1 engine based games, the weapon is clipped close
* to the viewer.
*
* Also note that this breaks z comparison against z values filled in with clear,
* but no app depending on that and disabled clipping has been found yet. Comparing
* primitives against themselves works, so the Z buffer is still intact for normal hidden
* surface removal.
*
* We could disable clipping entirely by setting the near to infinity and far to -infinity,
* but this would break Z buffer operation. Raising the range to something less than
* infinity would help a bit at the cost of Z precision, but it wouldn't eliminate the
* problem either.
*/ */
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ); TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
if(stateblock->wineD3DDevice->render_offscreen) { if(stateblock->wineD3DDevice->render_offscreen) {
@ -2561,16 +2711,16 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
*/ */
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0); TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
if(stateblock->wineD3DDevice->render_offscreen) { if(stateblock->wineD3DDevice->render_offscreen) {
glOrtho(X, X + width, -Y, -Y - height, 1.0, -1.0); glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
} else { } else {
glOrtho(X, X + width, Y + height, Y, 1.0, -1.0); glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
} }
} }
checkGLcall("glOrtho"); checkGLcall("glOrtho");
/* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */ /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
glTranslatef(0.375, 0.375, 0); glTranslatef(0.5, 0.5, 0);
checkGLcall("glTranslatef(0.375, 0.375, 0)"); checkGLcall("glTranslatef(0.5, 0.5, 0)");
/* D3D texture coordinates are flipped compared to OpenGL ones, so /* D3D texture coordinates are flipped compared to OpenGL ones, so
* render everything upside down when rendering offscreen. */ * render everything upside down when rendering offscreen. */
if (stateblock->wineD3DDevice->render_offscreen) { if (stateblock->wineD3DDevice->render_offscreen) {
@ -2584,9 +2734,21 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
the left to the right end of the viewport (with all matrices set to the left to the right end of the viewport (with all matrices set to
be identity), the x coords of both ends of the line would be not be identity), the x coords of both ends of the line would be not
-1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width) -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
instead. */ instead.
glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)"); 1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
divide by the Width/Height, so we need the half range(1.0) to translate by
half a pixel.
The other fun is that d3d's output z range after the transformation is [0;1],
but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
of Z buffer precision and the clear values do not match in the z test. Thus scale
[0;1] to [-1;1], so when gl undoes that we utilize the full z range
*/
glTranslatef(1.0 / stateblock->viewport.Width, -1.0/ stateblock->viewport.Height, -1.0);
checkGLcall("glTranslatef (1.0 / width, -1.0 / height, -1.0)");
glScalef(1.0, 1.0, 2.0);
/* D3D texture coordinates are flipped compared to OpenGL ones, so /* D3D texture coordinates are flipped compared to OpenGL ones, so
* render everything upside down when rendering offscreen. */ * render everything upside down when rendering offscreen. */
@ -2963,8 +3125,8 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
} else { } else {
glNormal3f(0, 0, 1); glNormal3f(0, 0, 0);
checkGLcall("glNormal3f(0, 0, 1)"); checkGLcall("glNormal3f(0, 0, 0)");
} }
/* Diffuse Colour --------------------------------------------*/ /* Diffuse Colour --------------------------------------------*/
@ -3239,6 +3401,9 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) { if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context); state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
} }
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
}
} else { } else {
/* We compile the shader here because we need the vertex declaration /* We compile the shader here because we need the vertex declaration
* in order to determine if we need to do any swizzling for D3DCOLOR * in order to determine if we need to do any swizzling for D3DCOLOR
@ -3279,6 +3444,14 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
if(updateFog) { if(updateFog) {
state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context); state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
} }
if(!useVertexShaderFunction) {
int i;
for(i = 0; i < MAX_TEXTURES; i++) {
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i), stateblock, context);
}
}
}
} }
static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
@ -3298,12 +3471,14 @@ static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
checkGLcall("glViewport"); checkGLcall("glViewport");
stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width; stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height; stateblock->wineD3DDevice->posFixup[3] = -1.0 / stateblock->viewport.Height;
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) { if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context); transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
} }
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
}
} }
static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
@ -3454,6 +3629,16 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
} }
} }
static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
if(stateblock->wineD3DDevice->render_offscreen) {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace(GL_CCW)");
} else {
glFrontFace(GL_CW);
checkGLcall("glFrontFace(GL_CW)");
}
}
const struct StateEntry StateTable[] = const struct StateEntry StateTable[] =
{ {
/* State name representative, apply function */ /* State name representative, apply function */
@ -3505,7 +3690,7 @@ const struct StateEntry StateTable[] =
{ /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined }, { /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
{ /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias }, { /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
{ /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias }, { /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias },
{ /* 48, WINED3DRS_RANGEFOGENABLE */ 0, state_nogl }, { /* 48, WINED3DRS_RANGEFOGENABLE */ STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog },
{ /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy }, { /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy },
{ /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, { /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
{ /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
@ -3612,7 +3797,7 @@ const struct StateEntry StateTable[] =
{ /*151, WINED3DRS_VERTEXBLEND */ STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, { /*151, WINED3DRS_VERTEXBLEND */ STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend },
{ /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, { /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
{ /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl }, { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl },
{ /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSIZE), state_psize }, { /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
{ /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin }, { /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin },
{ /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, { /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
{ /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, { /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
@ -3654,7 +3839,7 @@ const struct StateEntry StateTable[] =
{ /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, { /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
{ /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, { /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
{ /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, { /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor },
{ /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), state_srgbwrite }, { /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_PIXELSHADER, pixelshader },
{ /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, { /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
{ /*196, undefined */ 0, state_undefined }, { /*196, undefined */ 0, state_undefined },
{ /*197, undefined */ 0, state_undefined }, { /*197, undefined */ 0, state_undefined },
@ -4525,4 +4710,5 @@ const struct StateEntry StateTable[] =
{ /* STATE_CLIPPLANE(31) */ STATE_CLIPPLANE(31), clipplane }, { /* STATE_CLIPPLANE(31) */ STATE_CLIPPLANE(31), clipplane },
{ /* STATE_MATERIAL */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, { /* STATE_MATERIAL */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
{ /* STATE_FRONTFACE */ STATE_FRONTFACE, frontface },
}; };

View file

@ -186,8 +186,8 @@ void stateblock_copy(
PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry), *light2; PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry), *light2;
light2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*light)); light2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*light));
memcpy(light2, light, sizeof(*light)); memcpy(light2, light, sizeof(*light));
list_add_tail(&This->lightMap[l], &light2->entry); list_add_tail(&Dest->lightMap[l], &light2->entry);
if(light2->glIndex != -1) This->activeLights[light2->glIndex] = light2; if(light2->glIndex != -1) Dest->activeLights[light2->glIndex] = light2;
} }
} }
@ -262,10 +262,19 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
} }
} }
} }
if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
} }
for (counter = 0; counter < MAX_STREAMS; counter++) {
if(This->streamSource[counter]) {
if(0 != IWineD3DVertexBuffer_Release(This->streamSource[counter])) {
TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]);
}
}
}
if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
for(counter = 0; counter < LIGHTMAP_SIZE; counter++) { for(counter = 0; counter < LIGHTMAP_SIZE; counter++) {
struct list *e1, *e2; struct list *e1, *e2;
LIST_FOR_EACH_SAFE(e1, e2, &This->lightMap[counter]) { LIST_FOR_EACH_SAFE(e1, e2, &This->lightMap[counter]) {
@ -379,9 +388,11 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
if (This->blockType == WINED3DSBT_RECORDED) { if (This->blockType == WINED3DSBT_RECORDED) {
/* Recorded => Only update 'changed' values */ /* Recorded => Only update 'changed' values */
if (This->vertexShader != targetStateBlock->vertexShader) { if (This->changed.vertexShader && This->vertexShader != targetStateBlock->vertexShader) {
TRACE("Updating vertex shader from %p to %p\n", This->vertexShader, targetStateBlock->vertexShader); TRACE("Updating vertex shader from %p to %p\n", This->vertexShader, targetStateBlock->vertexShader);
if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
This->vertexShader = targetStateBlock->vertexShader; This->vertexShader = targetStateBlock->vertexShader;
} }
@ -424,13 +435,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->vertexShaderConstantB[i] = targetStateBlock->vertexShaderConstantB[i]; This->vertexShaderConstantB[i] = targetStateBlock->vertexShaderConstantB[i];
} }
/* Recorded => Only update 'changed' values */
if (This->pixelShader != targetStateBlock->pixelShader) {
TRACE("Updating pixel shader from %p to %p\n", This->pixelShader, targetStateBlock->pixelShader);
This->pixelShader = targetStateBlock->pixelShader;
}
/* Pixel Shader Float Constants */ /* Pixel Shader Float Constants */
for (j = 0; j < This->num_contained_ps_consts_f; ++j) { for (j = 0; j < This->num_contained_ps_consts_f; ++j) {
i = This->contained_ps_consts_f[j]; i = This->contained_ps_consts_f[j];
@ -481,7 +485,9 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData) if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData)
|| (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) { || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
TRACE("Updating pindexData to %p, baseVertexIndex to %d\n", TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex); targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
This->pIndexData = targetStateBlock->pIndexData; This->pIndexData = targetStateBlock->pIndexData;
This->baseVertexIndex = targetStateBlock->baseVertexIndex; This->baseVertexIndex = targetStateBlock->baseVertexIndex;
} }
@ -525,6 +531,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
TRACE("Updating stream source %d to %p, stride to %d\n", i, targetStateBlock->streamSource[i], TRACE("Updating stream source %d to %p, stride to %d\n", i, targetStateBlock->streamSource[i],
targetStateBlock->streamStride[i]); targetStateBlock->streamStride[i]);
This->streamStride[i] = targetStateBlock->streamStride[i]; This->streamStride[i] = targetStateBlock->streamStride[i];
if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
This->streamSource[i] = targetStateBlock->streamSource[i]; This->streamSource[i] = targetStateBlock->streamSource[i];
} }
@ -583,20 +591,22 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->samplerState[stage][state]); This->samplerState[stage][state]);
This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state]; This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state];
} }
if(This->changed.pixelShader && This->pixelShader != targetStateBlock->pixelShader) {
if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
This->pixelShader = targetStateBlock->pixelShader;
}
record_lights(This, targetStateBlock); record_lights(This, targetStateBlock);
} else if(This->blockType == WINED3DSBT_ALL) { } else if(This->blockType == WINED3DSBT_ALL) {
This->vertexDecl = targetStateBlock->vertexDecl; This->vertexDecl = targetStateBlock->vertexDecl;
This->vertexShader = targetStateBlock->vertexShader;
memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI)); memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF)); memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4); memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride)); memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride));
memcpy(This->streamOffset, targetStateBlock->streamOffset, sizeof(This->streamOffset)); memcpy(This->streamOffset, targetStateBlock->streamOffset, sizeof(This->streamOffset));
memcpy(This->streamSource, targetStateBlock->streamSource, sizeof(This->streamSource));
memcpy(This->streamFreq, targetStateBlock->streamFreq, sizeof(This->streamFreq)); memcpy(This->streamFreq, targetStateBlock->streamFreq, sizeof(This->streamFreq));
memcpy(This->streamFlags, targetStateBlock->streamFlags, sizeof(This->streamFlags)); memcpy(This->streamFlags, targetStateBlock->streamFlags, sizeof(This->streamFlags));
This->pIndexData = targetStateBlock->pIndexData;
This->baseVertexIndex = targetStateBlock->baseVertexIndex; This->baseVertexIndex = targetStateBlock->baseVertexIndex;
memcpy(This->transforms, targetStateBlock->transforms, sizeof(This->transforms)); memcpy(This->transforms, targetStateBlock->transforms, sizeof(This->transforms));
record_lights(This, targetStateBlock); record_lights(This, targetStateBlock);
@ -604,7 +614,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->clip_status = targetStateBlock->clip_status; This->clip_status = targetStateBlock->clip_status;
This->viewport = targetStateBlock->viewport; This->viewport = targetStateBlock->viewport;
This->material = targetStateBlock->material; This->material = targetStateBlock->material;
This->pixelShader = targetStateBlock->pixelShader;
memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI)); memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF)); memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4); memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
@ -614,8 +623,30 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState)); memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState));
memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState)); memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
This->scissorRect = targetStateBlock->scissorRect; This->scissorRect = targetStateBlock->scissorRect;
if(targetStateBlock->pIndexData != This->pIndexData) {
if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
This->pIndexData = targetStateBlock->pIndexData;
}
for(i = 0; i < MAX_STREAMS; i++) {
if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
This->streamSource[i] = targetStateBlock->streamSource[i];
}
}
if(This->vertexShader != targetStateBlock->vertexShader) {
if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
This->vertexShader = targetStateBlock->vertexShader;
}
if(This->pixelShader != targetStateBlock->pixelShader) {
if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
This->pixelShader = targetStateBlock->pixelShader;
}
} else if(This->blockType == WINED3DSBT_VERTEXSTATE) { } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
This->vertexShader = targetStateBlock->vertexShader;
memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI)); memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF)); memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4); memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
@ -633,8 +664,19 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->textureState[j][SavedVertexStates_R[i]] = targetStateBlock->textureState[j][SavedVertexStates_R[i]]; This->textureState[j][SavedVertexStates_R[i]] = targetStateBlock->textureState[j][SavedVertexStates_R[i]];
} }
} }
for(i = 0; i < MAX_STREAMS; i++) {
if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
This->streamSource[i] = targetStateBlock->streamSource[i];
}
}
if(This->vertexShader != targetStateBlock->vertexShader) {
if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
This->vertexShader = targetStateBlock->vertexShader;
}
} else if(This->blockType == WINED3DSBT_PIXELSTATE) { } else if(This->blockType == WINED3DSBT_PIXELSTATE) {
This->pixelShader = targetStateBlock->pixelShader;
memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI)); memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF)); memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4); memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
@ -651,6 +693,11 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->textureState[j][SavedPixelStates_R[i]] = targetStateBlock->textureState[j][SavedPixelStates_R[i]]; This->textureState[j][SavedPixelStates_R[i]] = targetStateBlock->textureState[j][SavedPixelStates_R[i]];
} }
} }
if(This->pixelShader != targetStateBlock->pixelShader) {
if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
This->pixelShader = targetStateBlock->pixelShader;
}
} }
TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This); TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -103,6 +103,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
FIXME("(%p) Something's still holding the back buffer\n",This); FIXME("(%p) Something's still holding the back buffer\n",This);
} }
} }
HeapFree(GetProcessHeap(), 0, This->backBuffer);
} }
/* Restore the screen resolution if we rendered in fullscreen /* Restore the screen resolution if we rendered in fullscreen
@ -132,7 +133,6 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
ActivateContext(This->wineD3DDevice, This->backBuffer[0], CTXUSAGE_RESOURCELOAD); ActivateContext(This->wineD3DDevice, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
ENTER_GL();
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */ /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) { if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) {
@ -175,6 +175,10 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
} }
IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_NONE); IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_NONE);
} }
if(This->wineD3DDevice->logo_surface) {
/* Blit the logo into the upper left corner of the drawable */
IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->wineD3DDevice->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
}
if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect); if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
/* TODO: If only source rect or dest rect are supplied then clip the window to match */ /* TODO: If only source rect or dest rect are supplied then clip the window to match */
@ -240,7 +244,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
#if defined(SHOW_FRAME_MAKEUP) #if defined(SHOW_FRAME_MAKEUP)
FIXME("Singe Frame snapshots Starting\n"); FIXME("Singe Frame snapshots Starting\n");
isDumpingFrames = TRUE; isDumpingFrames = TRUE;
ENTER_GL();
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
LEAVE_GL();
#endif #endif
#if defined(SINGLE_FRAME_DEBUGGING) #if defined(SINGLE_FRAME_DEBUGGING)
@ -268,8 +274,6 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
} }
#endif #endif
LEAVE_GL();
if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) { if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
TRACE("Clearing the color buffer with pink color\n"); TRACE("Clearing the color buffer with pink color\n");
@ -319,6 +323,29 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
tmp = front->resource.allocatedMemory; tmp = front->resource.allocatedMemory;
front->resource.allocatedMemory = back->resource.allocatedMemory; front->resource.allocatedMemory = back->resource.allocatedMemory;
back->resource.allocatedMemory = tmp; back->resource.allocatedMemory = tmp;
tmp = front->resource.heapMemory;
front->resource.heapMemory = back->resource.heapMemory;
back->resource.heapMemory = tmp;
}
/* Flip the PBO */
{
DWORD tmp_flags = front->Flags;
GLuint tmp_pbo = front->pbo;
front->pbo = back->pbo;
back->pbo = tmp_pbo;
if(back->Flags & SFLAG_PBO)
front->Flags |= SFLAG_PBO;
else
front->Flags &= ~SFLAG_PBO;
if(tmp_flags & SFLAG_PBO)
back->Flags |= SFLAG_PBO;
else
back->Flags &= ~SFLAG_PBO;
} }
/* client_memory should not be different, but just in case */ /* client_memory should not be different, but just in case */
@ -333,8 +360,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
if(backuptodate) front->Flags |= SFLAG_INSYSMEM; if(backuptodate) front->Flags |= SFLAG_INSYSMEM;
else front->Flags &= ~SFLAG_INSYSMEM; else front->Flags &= ~SFLAG_INSYSMEM;
} else { } else {
back->Flags &= ~SFLAG_INSYSMEM; IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE);
front->Flags &= ~SFLAG_INSYSMEM; IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE);
} }
} }

View file

@ -132,7 +132,7 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This); FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[i], NULL); IWineD3DSurface_AddDirtyRect(This->surfaces[i], NULL);
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface)); IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode); IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
} }

View file

@ -27,8 +27,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION This->adapter->gl_info
/***************************************************************************** /*****************************************************************************
* Pixel format array * Pixel format array
*/ */
@ -150,14 +148,14 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
{WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV }, {WINED3DFMT_A8R8G8B8 ,GL_RGBA8 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
{WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV }, {WINED3DFMT_X8R8G8B8 ,GL_RGB8 ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV },
{WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 }, {WINED3DFMT_R5G6B5 ,GL_RGB5 ,GL_RGB5 ,GL_RGB ,GL_UNSIGNED_SHORT_5_6_5 },
{WINED3DFMT_X1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV }, {WINED3DFMT_X1R5G5B5 ,GL_RGB5 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
{WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV }, {WINED3DFMT_A1R5G5B5 ,GL_RGB5_A1 ,GL_RGB5_A1 ,GL_BGRA ,GL_UNSIGNED_SHORT_1_5_5_5_REV },
{WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV }, {WINED3DFMT_A4R4G4B4 ,GL_RGBA4 ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
{WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 ,GL_RGB ,GL_UNSIGNED_BYTE_3_3_2 }, {WINED3DFMT_R3G3B2 ,GL_R3_G3_B2 ,GL_R3_G3_B2 ,GL_RGB ,GL_UNSIGNED_BYTE_3_3_2 },
{WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE }, {WINED3DFMT_A8 ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE },
{WINED3DFMT_A8R3G3B2 ,0 ,0 ,0 ,0 }, {WINED3DFMT_A8R3G3B2 ,0 ,0 ,0 ,0 },
{WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV }, {WINED3DFMT_X4R4G4B4 ,GL_RGB4 ,GL_RGB4 ,GL_BGRA ,GL_UNSIGNED_SHORT_4_4_4_4_REV },
{WINED3DFMT_A2B10G10R10 ,GL_RGB ,GL_RGB ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV }, {WINED3DFMT_A2B10G10R10 ,GL_RGBA ,GL_RGBA ,GL_RGBA ,GL_UNSIGNED_INT_2_10_10_10_REV },
{WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV }, {WINED3DFMT_A8B8G8R8 ,GL_RGBA8 ,GL_RGBA8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
{WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV }, {WINED3DFMT_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
{WINED3DFMT_G16R16 ,0 ,0 ,0 ,0 }, {WINED3DFMT_G16R16 ,0 ,0 ,0 ,0 },
@ -169,8 +167,8 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
{WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE }, {WINED3DFMT_A4L4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE4_ALPHA4 ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE },
/* Bump mapping stuff */ /* Bump mapping stuff */
{WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE }, {WINED3DFMT_V8U8 ,GL_DSDT8_NV ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE },
{WINED3DFMT_L6V5U5 ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT_5_5_5_1 }, {WINED3DFMT_L6V5U5 ,GL_DSDT8_MAG8_NV ,GL_DSDT8_MAG8_NV ,GL_DSDT_MAG_NV ,GL_BYTE },
{WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT_MAG_INTENSITY_NV ,GL_BYTE }, {WINED3DFMT_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT_MAG_VIB_NV ,GL_UNSIGNED_INT_8_8_S8_S8_REV_NV},
{WINED3DFMT_Q8W8V8U8 ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE }, {WINED3DFMT_Q8W8V8U8 ,GL_SIGNED_RGBA8_NV ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
{WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT }, {WINED3DFMT_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
{WINED3DFMT_W11V11U10 ,0 ,0 ,0 ,0 }, {WINED3DFMT_W11V11U10 ,0 ,0 ,0 ,0 },
@ -210,9 +208,11 @@ static inline int getFmtIdx(WINED3DFORMAT fmt) {
return -1; return -1;
} }
#define GLINFO_LOCATION (*gl_info)
BOOL initPixelFormats(WineD3D_GL_Info *gl_info) BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
{ {
unsigned int src; unsigned int src;
int dst;
gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0])); sizeof(formats) / sizeof(formats[0]) * sizeof(gl_info->gl_formats[0]));
@ -222,15 +222,66 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
* after this loop * after this loop
*/ */
for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) { for(src = 0; src < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); src++) {
int dst = getFmtIdx(gl_formats_template[src].fmt); dst = getFmtIdx(gl_formats_template[src].fmt);
gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal; gl_info->gl_formats[dst].glInternal = gl_formats_template[src].glInternal;
gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal; gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat; gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
gl_info->gl_formats[dst].glType = gl_formats_template[src].glType; gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
gl_info->gl_formats[dst].conversion_group= WINED3DFMT_UNKNOWN;
}
/* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
* V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
* their extensions are not available.
*
* In theory, V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
* returns 0.0 when sampling from it, DirectX 1.0. This is disabled until we find
* an application that needs this because it causes performance problems due to
* shader recompiling in some games.
*/
if(!GL_SUPPORT(ATI_ENVMAP_BUMPMAP) && !GL_SUPPORT(NV_TEXTURE_SHADER2)) {
/* signed -> unsigned fixup */
dst = getFmtIdx(WINED3DFMT_V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
dst = getFmtIdx(WINED3DFMT_V16U16);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
} else if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
/* signed -> unsigned fixup */
dst = getFmtIdx(WINED3DFMT_V16U16);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V16U16;
} else {
/* Blue = 1.0 fixup, disabled for now */
#if 0
dst = getFmtIdx(WINED3DFMT_V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
dst = getFmtIdx(WINED3DFMT_V16U16);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
#endif
}
if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
/* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
* with each other
*/
dst = getFmtIdx(WINED3DFMT_L6V5U5);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_L6V5U5;
dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_X8L8V8U8;
dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_Q8W8V8U8;
} else {
/* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
* are converted at surface loading time, but they do not need any modification in
* the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
* WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
*/
} }
return TRUE; return TRUE;
} }
#undef GLINFO_LOCATION
#define GLINFO_LOCATION This->adapter->gl_info
const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, WineD3D_GL_Info *gl_info, const GlPixelFormatDesc **glDesc) const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, WineD3D_GL_Info *gl_info, const GlPixelFormatDesc **glDesc)
{ {
@ -2418,14 +2469,14 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
#endif #endif
/* Setup this textures matrix according to the texture flags*/ /* Setup this textures matrix according to the texture flags*/
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords) void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
{ {
float mat[16]; float mat[16];
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
checkGLcall("glMatrixMode(GL_TEXTURE)"); checkGLcall("glMatrixMode(GL_TEXTURE)");
if (flags == WINED3DTTFF_DISABLE) { if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
glLoadIdentity(); glLoadIdentity();
checkGLcall("glLoadIdentity()"); checkGLcall("glLoadIdentity()");
return; return;
@ -2438,12 +2489,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
memcpy(mat, smat, 16 * sizeof(float)); memcpy(mat, smat, 16 * sizeof(float));
switch (flags & ~WINED3DTTFF_PROJECTED) {
case WINED3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
}
if (flags & WINED3DTTFF_PROJECTED) { if (flags & WINED3DTTFF_PROJECTED) {
switch (flags & ~WINED3DTTFF_PROJECTED) { switch (flags & ~WINED3DTTFF_PROJECTED) {
case WINED3DTTFF_COUNT2: case WINED3DTTFF_COUNT2:
@ -2455,9 +2500,58 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
mat[2] = mat[6] = mat[10] = mat[14] = 0; mat[2] = mat[6] = mat[10] = mat[14] = 0;
break; break;
} }
} else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */ } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
mat[12] = mat[8]; if(!calculatedCoords) {
mat[13] = mat[9]; switch(coordtype) {
case WINED3DDECLTYPE_FLOAT1:
/* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
* swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
* the input value to the transformation will be 0, so the matrix value is irrelevant
*/
mat[12] = mat[4];
mat[13] = mat[5];
mat[14] = mat[6];
mat[15] = mat[7];
break;
case WINED3DDECLTYPE_FLOAT2:
/* See above, just 3rd and 4th coord
*/
mat[12] = mat[8];
mat[13] = mat[9];
mat[14] = mat[10];
mat[15] = mat[11];
break;
case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
/* This is to prevent swaping the matrix lines and put the default 4th coord = 1.0
* into a bad place. The division elimination below will apply to make sure the
* 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
*/
case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
break;
default:
FIXME("Unexpected fixed function texture coord input\n");
}
}
switch (flags & ~WINED3DTTFF_PROJECTED) {
/* case WINED3DTTFF_COUNT1: Won't ever get here */
case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
/* OpenGL divides the first 3 vertex coord by the 4th by default,
* which is essentially the same as D3DTTFF_PROJECTED. Make sure that
* the 4th coord evaluates to 1.0 to eliminate that.
*
* If the fixed function pipeline is used, the 4th value remains unused,
* so there is no danger in doing this. With vertex shaders we have a
* problem. Should an app hit that problem, the code here would have to
* check for pixel shaders, and the shader has to undo the default gl divide.
*
* A more serious problem occurs if the app passes 4 coordinates in, and the
* 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
* or a replacement shader
*/
default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
}
} }
glLoadMatrixf(mat); glLoadMatrixf(mat);
@ -2493,6 +2587,8 @@ BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *bl
case WINED3DFMT_X1R5G5B5: case WINED3DFMT_X1R5G5B5:
case WINED3DFMT_A1R5G5B5: case WINED3DFMT_A1R5G5B5:
case WINED3DFMT_R5G6B5: case WINED3DFMT_R5G6B5:
case WINED3DFMT_X4R4G4B4:
case WINED3DFMT_A4R4G4B4:
case WINED3DFMT_R3G3B2: case WINED3DFMT_R3G3B2:
case WINED3DFMT_A8P8: case WINED3DFMT_A8P8:
case WINED3DFMT_P8: case WINED3DFMT_P8:

View file

@ -136,7 +136,7 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte
This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count); This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count);
if (!This->pDeclarationWine) { if (!This->pDeclarationWine) {
ERR("Memory allocation failed\n"); ERR("Memory allocation failed\n");
hr = WINED3DERR_OUTOFVIDEOMEMORY; return WINED3DERR_OUTOFVIDEOMEMORY;
} else { } else {
CopyMemory(This->pDeclarationWine, elements, sizeof(WINED3DVERTEXELEMENT) * element_count); CopyMemory(This->pDeclarationWine, elements, sizeof(WINED3DVERTEXELEMENT) * element_count);
} }

View file

@ -108,30 +108,21 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
{WINED3DSIO_DST, "dst", "DST", 1, 3, vshader_hw_map2gl, shader_glsl_dst, 0, 0}, {WINED3DSIO_DST, "dst", "DST", 1, 3, vshader_hw_map2gl, shader_glsl_dst, 0, 0},
{WINED3DSIO_LRP, "lrp", "LRP", 1, 4, NULL, shader_glsl_lrp, 0, 0}, {WINED3DSIO_LRP, "lrp", "LRP", 1, 4, NULL, shader_glsl_lrp, 0, 0},
{WINED3DSIO_FRC, "frc", "FRC", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_FRC, "frc", "FRC", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_POW, "pow", "POW", 1, 3, NULL, shader_glsl_pow, 0, 0}, {WINED3DSIO_POW, "pow", "POW", 1, 3, vshader_hw_map2gl, shader_glsl_pow, 0, 0},
{WINED3DSIO_CRS, "crs", "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0}, {WINED3DSIO_CRS, "crs", "XPD", 1, 3, vshader_hw_map2gl, shader_glsl_cross, 0, 0},
/* TODO: sng can possibly be performed a s /* TODO: sng can possibly be performed a s
RCP tmp, vec RCP tmp, vec
MUL out, tmp, vec*/ MUL out, tmp, vec*/
{WINED3DSIO_SGN, "sgn", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_SGN, "sgn", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0},
/* TODO: xyz normalise can be performed as VS_ARB using one temporary register, {WINED3DSIO_NRM, "nrm", NULL, 1, 2, shader_hw_nrm, shader_glsl_map2gl, 0, 0},
DP3 tmp , vec, vec; {WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, shader_hw_sincos, shader_glsl_sincos, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
RSQ tmp, tmp.x; {WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, shader_hw_sincos, shader_glsl_sincos, WINED3DVS_VERSION(3,0), -1},
MUL vec.xyz, vec, tmp;
but I think this is better because it accounts for w properly.
DP3 tmp , vec, vec;
RSQ tmp, tmp.x;
MUL vec, vec, tmp;
*/
{WINED3DSIO_NRM, "nrm", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, NULL, shader_glsl_sincos, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 2, NULL, shader_glsl_sincos, WINED3DVS_VERSION(3,0), -1},
/* Matrix */ /* Matrix */
{WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0}, {WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
/* Declare registers */ /* Declare registers */
{WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0}, {WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0},
/* Constant definitions */ /* Constant definitions */
@ -333,26 +324,34 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
/* Unpack 3.0 outputs */ /* Unpack 3.0 outputs */
if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0)) if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0)) {
vshader_glsl_output_unpack(&buffer, This->semantics_out); shader_addline(&buffer, "order_ps_input(OUT);\n");
} else {
shader_addline(&buffer, "order_ps_input();\n");
}
/* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */ /* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
if (!reg_maps->fog) if (!reg_maps->fog)
shader_addline(&buffer, "gl_FogFragCoord = gl_Position.z;\n"); shader_addline(&buffer, "gl_FogFragCoord = gl_Position.z;\n");
/* Write the final position. /* Write the final position.
* *
* OpenGL coordinates specify the center of the pixel while d3d coords specify * OpenGL coordinates specify the center of the pixel while d3d coords specify
* the corner. The offsets are stored in z and w in the 2nd row of the projection * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
* matrix to avoid wasting a free shader constant. Add them to the w and z coord * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
* of the 2nd row * contains 1.0 to allow a mad.
*/ */
shader_addline(&buffer, "gl_Position.x = gl_Position.x + posFixup[2];\n"); shader_addline(&buffer, "gl_Position.xy = gl_Position.xy * posFixup.xy + posFixup.zw;\n");
shader_addline(&buffer, "gl_Position.y = gl_Position.y + posFixup[3];\n");
/* Account for any inverted textures (render to texture case) by reversing the y coordinate /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
* (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) *
* Basically we want(in homogenous coordinates) z = z * 2 - 1. However, shaders are run
* before the homogenous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w,
* which is the same as z = z / 2 - w.
*/ */
shader_addline(&buffer, "gl_Position.y = gl_Position.y * posFixup[1];\n"); shader_addline(&buffer, "tmp0 = gl_Position;\n");
shader_addline(&buffer, "gl_Position.z = tmp0.z * 2.0;\n");
shader_addline(&buffer, "gl_Position.z = gl_Position.z - gl_Position.w;\n");
shader_addline(&buffer, "}\n"); shader_addline(&buffer, "}\n");
@ -368,12 +367,18 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* Create the hw ARB shader */ /* Create the hw ARB shader */
shader_addline(&buffer, "!!ARBvp1.0\n"); shader_addline(&buffer, "!!ARBvp1.0\n");
shader_addline(&buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset);
/* Mesa supports only 95 constants */ /* Mesa supports only 95 constants */
if (GL_VEND(MESA) || GL_VEND(WINE)) if (GL_VEND(MESA) || GL_VEND(WINE))
This->baseShader.limits.constant_float = This->baseShader.limits.constant_float =
min(95, This->baseShader.limits.constant_float); min(95, This->baseShader.limits.constant_float);
/* Some instructions need a temporary register. Add it if needed, but only if it is really needed */
if(reg_maps->usesnrm || This->rel_offset) {
shader_addline(&buffer, "TEMP TMP;\n");
}
/* Base Declarations */ /* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION); shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
@ -390,15 +395,17 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* Write the final position. /* Write the final position.
* *
* OpenGL coordinates specify the center of the pixel while d3d coords specify * OpenGL coordinates specify the center of the pixel while d3d coords specify
* the corner. The offsets are stored in the 2nd row of the projection matrix, * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
* the x offset in z and the y offset in w. Add them to the resulting position * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
* contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
*/ */
shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;\n"); shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;");
shader_addline(&buffer, "ADD TMP_OUT.y, TMP_OUT.y, posFixup.w;\n"); shader_addline(&buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, posFixup.w;");
/* Account for any inverted textures (render to texture case) by reversing the y coordinate
* (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
* and the glsl equivalent
*/ */
shader_addline(&buffer, "MUL TMP_OUT.y, TMP_OUT.y, posFixup.y;\n"); shader_addline(&buffer, "MAD TMP_OUT.z, TMP_OUT.z, helper_const.x, -TMP_OUT.w;\n");
shader_addline(&buffer, "MOV result.position, TMP_OUT;\n"); shader_addline(&buffer, "MOV result.position, TMP_OUT;\n");
@ -460,11 +467,6 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
TRACE("(%p) : Releasing from %d\n", This, This->ref); TRACE("(%p) : Releasing from %d\n", This, This->ref);
ref = InterlockedDecrement(&This->ref); ref = InterlockedDecrement(&This->ref);
if (ref == 0) { if (ref == 0) {
if(iface == ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->vertexShader) {
/* See comment in PixelShader::Release */
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *) This->baseShader.device, STATE_VSHADER);
}
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) { if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
struct list *linked_programs = &This->baseShader.linked_programs; struct list *linked_programs = &This->baseShader.linked_programs;
@ -560,6 +562,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
list_init(&This->baseShader.constantsI); list_init(&This->baseShader.constantsI);
/* Second pass: figure out registers used, semantics, etc.. */ /* Second pass: figure out registers used, semantics, etc.. */
This->min_rel_offset = GL_LIMITS(vshader_constantsF);
This->max_rel_offset = 0;
memset(reg_maps, 0, sizeof(shader_reg_maps)); memset(reg_maps, 0, sizeof(shader_reg_maps));
hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps, hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
This->semantics_in, This->semantics_out, pFunction, NULL); This->semantics_in, This->semantics_out, pFunction, NULL);
@ -567,6 +571,23 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
This->baseShader.shader_mode = deviceImpl->vs_selected_mode; This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
if(deviceImpl->vs_selected_mode == SHADER_ARB &&
(GLINFO_LOCATION).arb_vs_offset_limit &&
This->min_rel_offset <= This->max_rel_offset) {
if(This->max_rel_offset - This->min_rel_offset > 127) {
FIXME("The difference between the minimum and maximum relative offset is > 127\n");
FIXME("Which this OpenGL implementation does not support. Try using GLSL\n");
FIXME("Min: %d, Max: %d\n", This->min_rel_offset, This->max_rel_offset);
} else if(This->max_rel_offset - This->min_rel_offset > 63) {
This->rel_offset = This->min_rel_offset + 63;
} else if(This->max_rel_offset > 63) {
This->rel_offset = This->min_rel_offset;
} else {
This->rel_offset = 0;
}
}
/* copy the function ... because it will certainly be released by application */ /* copy the function ... because it will certainly be released by application */
if (NULL != pFunction) { if (NULL != pFunction) {
void *function; void *function;

View file

@ -270,9 +270,18 @@ static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int
TRACE("(%p) : level %u, format %s (0x%08x)\n", This, gl_level, debug_d3dformat(format), format); TRACE("(%p) : level %u, format %s (0x%08x)\n", This, gl_level, debug_d3dformat(format), format);
if(GL_SUPPORT(EXT_TEXTURE3D)) { TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n",
TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", GL_TEXTURE_3D,
GL_TEXTURE_3D, gl_level,
glDesc->glInternal,
This->currentDesc.Width,
This->currentDesc.Height,
This->currentDesc.Depth,
0,
glDesc->glFormat,
glDesc->glType,
This->resource.allocatedMemory);
GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D,
gl_level, gl_level,
glDesc->glInternal, glDesc->glInternal,
This->currentDesc.Width, This->currentDesc.Width,
@ -281,20 +290,8 @@ static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int
0, 0,
glDesc->glFormat, glDesc->glFormat,
glDesc->glType, glDesc->glType,
This->resource.allocatedMemory); This->resource.allocatedMemory));
GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, checkGLcall("glTexImage3D");
gl_level,
glDesc->glInternal,
This->currentDesc.Width,
This->currentDesc.Height,
This->currentDesc.Depth,
0,
glDesc->glFormat,
glDesc->glType,
This->resource.allocatedMemory));
checkGLcall("glTexImage3D");
} else
WARN("This OpenGL implementation doesn't support 3D textures\n");
/* When adding code releasing This->resource.allocatedMemory to save data keep in mind that /* When adding code releasing This->resource.allocatedMemory to save data keep in mind that
* GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by default if supported(GL_APPLE_client_storage). * GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by default if supported(GL_APPLE_client_storage).

View file

@ -1,6 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd"> <!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
<module name="wined3d" type="win32dll" installbase="system32" installname="wined3d.dll" allowwarnings ="true"> <module name="wined3d" type="win32dll" installbase="system32" installname="wined3d.dll" allowwarnings ="true">
<importlibrary definition="wined3d.def" /> <importlibrary definition="wined3d.def" />
<include base="wined3d">.</include> <include base="wined3d">.</include>
<include base="ReactOS">include/reactos/wine</include> <include base="ReactOS">include/reactos/wine</include>
@ -36,6 +36,7 @@
<file>resource.c</file> <file>resource.c</file>
<file>state.c</file> <file>state.c</file>
<file>stateblock.c</file> <file>stateblock.c</file>
<file>surface_base.c</file>
<file>surface.c</file> <file>surface.c</file>
<file>surface_gdi.c </file> <file>surface_gdi.c </file>
<file>swapchain.c</file> <file>swapchain.c</file>

View file

@ -39,25 +39,13 @@ wined3d_settings_t wined3d_settings =
VS_HW, /* Hardware by default */ VS_HW, /* Hardware by default */
PS_HW, /* Hardware by default */ PS_HW, /* Hardware by default */
VBO_HW, /* Hardware by default */ VBO_HW, /* Hardware by default */
FALSE, /* Use of GLSL disabled by default */ TRUE, /* Use of GLSL enabled by default */
ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */ ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */
RTL_AUTO, /* Automatically determine best locking method */ RTL_AUTO, /* Automatically determine best locking method */
64*1024*1024 /* 64MB texture memory by default */ 0, /* The default of memory is set in FillGLCaps */
NULL /* No wine logo by default */
}; };
WineD3DGlobalStatistics *wineD3DGlobalStatistics = NULL;
long globalChangeGlRam(long glram){
/* FIXME: replace this function with object tracking */
int result;
wineD3DGlobalStatistics->glsurfaceram += glram;
TRACE("Adjusted gl ram by %ld to %d\n", glram, wineD3DGlobalStatistics->glsurfaceram);
result = wineD3DGlobalStatistics->glsurfaceram;
return result;
}
IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent) { IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent) {
IWineD3DImpl* object; IWineD3DImpl* object;
@ -75,13 +63,6 @@ IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *p
object->ref = 1; object->ref = 1;
object->parent = parent; object->parent = parent;
/*Create a structure for storing global data in*/
if(wineD3DGlobalStatistics == NULL){
TRACE("Creating global statistics store\n");
wineD3DGlobalStatistics = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wineD3DGlobalStatistics));
}
TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion); TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion);
return (IWineD3D *)object; return (IWineD3D *)object;
@ -112,8 +93,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
DWORD len; DWORD len;
WNDCLASSA wc; WNDCLASSA wc;
wined3d_settings.emulated_textureram = 64*1024*1024;
/* We need our own window class for a fake window which we use to retrieve GL capabilities */ /* We need our own window class for a fake window which we use to retrieve GL capabilities */
/* We might need CS_OWNDC in the future if we notice strange things on Windows. /* We might need CS_OWNDC in the future if we notice strange things on Windows.
* Various articles/posts about OpenGL problems on Windows recommend this. */ * Various articles/posts about OpenGL problems on Windows recommend this. */
@ -205,14 +184,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
} }
if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) ) if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
{ {
if (!strcmp(buffer,"enabled")) if (!strcmp(buffer,"disabled"))
{
TRACE("Use of GL Shading Language enabled for systems that support it\n");
wined3d_settings.glslRequested = TRUE;
}
else
{ {
TRACE("Use of GL Shading Language disabled\n"); TRACE("Use of GL Shading Language disabled\n");
wined3d_settings.glslRequested = FALSE;
} }
} }
if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) ) if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) )
@ -274,6 +249,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
else else
ERR("VideoMemorySize is %i but must be >0\n", TmpVideoMemorySize); ERR("VideoMemorySize is %i but must be >0\n", TmpVideoMemorySize);
} }
if ( !get_config_key( hkey, appkey, "WineLogo", buffer, size) )
{
wined3d_settings.logo = HeapAlloc(GetProcessHeap(), 0, strlen(buffer) + 1);
if(wined3d_settings.logo) strcpy(wined3d_settings.logo, buffer);
}
} }
if (wined3d_settings.vs_mode == VS_HW) if (wined3d_settings.vs_mode == VS_HW)
TRACE("Allow HW vertex shaders\n"); TRACE("Allow HW vertex shaders\n");

View file

@ -97,7 +97,7 @@ void hash_table_remove(hash_table_t *table, void *key);
#define NUM_SAVEDPIXELSTATES_R 35 #define NUM_SAVEDPIXELSTATES_R 35
#define NUM_SAVEDPIXELSTATES_T 18 #define NUM_SAVEDPIXELSTATES_T 18
#define NUM_SAVEDPIXELSTATES_S 12 #define NUM_SAVEDPIXELSTATES_S 12
#define NUM_SAVEDVERTEXSTATES_R 31 #define NUM_SAVEDVERTEXSTATES_R 34
#define NUM_SAVEDVERTEXSTATES_T 2 #define NUM_SAVEDVERTEXSTATES_T 2
#define NUM_SAVEDVERTEXSTATES_S 1 #define NUM_SAVEDVERTEXSTATES_S 1
@ -203,17 +203,20 @@ typedef struct wined3d_settings_s {
int rendertargetlock_mode; int rendertargetlock_mode;
/* Memory tracking and object counting */ /* Memory tracking and object counting */
unsigned int emulated_textureram; unsigned int emulated_textureram;
char *logo;
} wined3d_settings_t; } wined3d_settings_t;
extern wined3d_settings_t wined3d_settings; extern wined3d_settings_t wined3d_settings;
/* Shader backends */ /* Shader backends */
struct SHADER_OPCODE_ARG;
typedef struct { typedef struct {
void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS); void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
void (*shader_select_depth_blt)(IWineD3DDevice *iface); void (*shader_select_depth_blt)(IWineD3DDevice *iface);
void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS); void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
void (*shader_cleanup)(IWineD3DDevice *iface); void (*shader_cleanup)(IWineD3DDevice *iface);
void (*shader_color_correction)(struct SHADER_OPCODE_ARG *arg);
} shader_backend_t; } shader_backend_t;
extern const shader_backend_t glsl_shader_backend; extern const shader_backend_t glsl_shader_backend;
@ -329,23 +332,6 @@ typedef struct IWineD3DSurfaceImpl IWineD3DSurfaceImpl;
typedef struct IWineD3DPaletteImpl IWineD3DPaletteImpl; typedef struct IWineD3DPaletteImpl IWineD3DPaletteImpl;
typedef struct IWineD3DDeviceImpl IWineD3DDeviceImpl; typedef struct IWineD3DDeviceImpl IWineD3DDeviceImpl;
/* Tracking */
/* TODO: Move some of this to the device */
long globalChangeGlRam(long glram);
/* Memory and object tracking */
/*Structure for holding information on all direct3d objects
useful for making sure tracking is ok and when release is called on a device!
and probably quite handy for debugging and dumping states out
*/
typedef struct WineD3DGlobalStatistics {
int glsurfaceram; /* The aproximate amount of glTexture memory allocated for textures */
} WineD3DGlobalStatistics;
extern WineD3DGlobalStatistics* wineD3DGlobalStatistics;
/* Global variables */ /* Global variables */
extern const float identity[16]; extern const float identity[16];
@ -429,8 +415,6 @@ void primitiveDeclarationConvertToStridedData(
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
void blt_to_drawable(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *surface);
#define eps 1e-8 #define eps 1e-8
#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ #define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
@ -486,7 +470,9 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock,
#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES)) #define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES))
#define STATE_HIGHEST (STATE_MATERIAL) #define STATE_FRONTFACE (STATE_MATERIAL + 1)
#define STATE_HIGHEST (STATE_FRONTFACE)
struct StateEntry struct StateEntry
{ {
@ -513,6 +499,7 @@ struct WineD3DContext {
DWORD tid; /* Thread ID which owns this context at the moment */ DWORD tid; /* Thread ID which owns this context at the moment */
/* Stores some inforation about the context state for optimization */ /* Stores some inforation about the context state for optimization */
GLint last_draw_buffer;
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */ BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
BOOL last_was_pshader; BOOL last_was_pshader;
BOOL last_was_vshader; BOOL last_was_vshader;
@ -524,6 +511,7 @@ struct WineD3DContext {
GLenum untracked_materials[2]; GLenum untracked_materials[2];
BOOL last_was_blit, last_was_ckey; BOOL last_was_blit, last_was_ckey;
char texShaderBumpMap; char texShaderBumpMap;
BOOL fog_coord;
/* The actual opengl context */ /* The actual opengl context */
HGLRC glCtx; HGLRC glCtx;
@ -597,10 +585,13 @@ struct WineD3DAdapter
WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */ WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
int nCfgs; int nCfgs;
WineD3D_PixelFormat *cfgs; WineD3D_PixelFormat *cfgs;
unsigned int TextureRam; /* Amount of texture memory both video ram + AGP/TurboCache/HyperMemory/.. */
unsigned int UsedTextureRam;
}; };
extern BOOL InitAdapters(void); extern BOOL InitAdapters(void);
extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info); extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info);
extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
/***************************************************************************** /*****************************************************************************
* High order patch management * High order patch management
@ -713,6 +704,7 @@ struct IWineD3DDeviceImpl
/* palettes texture management */ /* palettes texture management */
PALETTEENTRY palettes[MAX_PALETTES][256]; PALETTEENTRY palettes[MAX_PALETTES][256];
UINT currentPalette; UINT currentPalette;
UINT paletteConversionShader;
/* For rendering to a texture using glCopyTexImage */ /* For rendering to a texture using glCopyTexImage */
BOOL render_offscreen; BOOL render_offscreen;
@ -733,6 +725,9 @@ struct IWineD3DDeviceImpl
BOOL haveHardwareCursor; BOOL haveHardwareCursor;
HCURSOR hardwareCursor; HCURSOR hardwareCursor;
/* The Wine logo surface */
IWineD3DSurface *logo_surface;
/* Textures for when no other textures are mapped */ /* Textures for when no other textures are mapped */
UINT dummyTextureName[MAX_TEXTURES]; UINT dummyTextureName[MAX_TEXTURES];
@ -829,7 +824,8 @@ typedef struct IWineD3DResourceClass
UINT size; UINT size;
DWORD usage; DWORD usage;
WINED3DFORMAT format; WINED3DFORMAT format;
BYTE *allocatedMemory; BYTE *allocatedMemory; /* Pointer to the real data location */
BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */
struct list privateData; struct list privateData;
} IWineD3DResourceClass; } IWineD3DResourceClass;
@ -841,6 +837,8 @@ typedef struct IWineD3DResourceImpl
IWineD3DResourceClass resource; IWineD3DResourceClass resource;
} IWineD3DResourceImpl; } IWineD3DResourceImpl;
/* Tests show that the start address of resources is 32 byte aligned */
#define RESOURCE_ALIGNMENT 32
/***************************************************************************** /*****************************************************************************
* IWineD3DVertexBuffer implementation structure (extends IWineD3DResourceImpl) * IWineD3DVertexBuffer implementation structure (extends IWineD3DResourceImpl)
@ -931,6 +929,7 @@ typedef struct IWineD3DBaseTextureClass
DWORD sampler; DWORD sampler;
BOOL is_srgb; BOOL is_srgb;
UINT srgb_mode_change_count; UINT srgb_mode_change_count;
WINED3DFORMAT shader_conversion_group;
} IWineD3DBaseTextureClass; } IWineD3DBaseTextureClass;
typedef struct IWineD3DBaseTextureImpl typedef struct IWineD3DBaseTextureImpl
@ -1050,6 +1049,7 @@ typedef struct _WINED3DSURFACET_DESC
typedef struct wineD3DSurface_DIB { typedef struct wineD3DSurface_DIB {
HBITMAP DIBsection; HBITMAP DIBsection;
void* bitmap_data; void* bitmap_data;
UINT bitmap_size;
HGDIOBJ holdbitmap; HGDIOBJ holdbitmap;
BOOL client_memory; BOOL client_memory;
} wineD3DSurface_DIB; } wineD3DSurface_DIB;
@ -1100,6 +1100,9 @@ struct IWineD3DSurfaceImpl
/* Oversized texture */ /* Oversized texture */
RECT glRect; RECT glRect;
/* PBO */
GLuint pbo;
#if 0 #if 0
/* precalculated x and y scalings for texture coords */ /* precalculated x and y scalings for texture coords */
float pow2scalingFactorX; /* = (Width / pow2Width ) */ float pow2scalingFactorX; /* = (Width / pow2Width ) */
@ -1112,6 +1115,7 @@ struct IWineD3DSurfaceImpl
#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */ #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */
glDescriptor glDescription; glDescriptor glDescription;
BOOL srgb;
/* For GetDC */ /* For GetDC */
wineD3DSurface_DIB dib; wineD3DSurface_DIB dib;
@ -1137,49 +1141,41 @@ extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl; extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl;
/* Predeclare the shared Surface functions */ /* Predeclare the shared Surface functions */
HRESULT WINAPI IWineD3DSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj); HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
ULONG WINAPI IWineD3DSurfaceImpl_AddRef(IWineD3DSurface *iface); ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface);
ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent);
HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice);
HRESULT WINAPI IWineD3DSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice); HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData);
HRESULT WINAPI IWineD3DSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData); HRESULT WINAPI IWineD3DBaseSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid);
HRESULT WINAPI IWineD3DSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid); DWORD WINAPI IWineD3DBaseSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew);
DWORD WINAPI IWineD3DSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew); DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPriority(IWineD3DSurface *iface);
DWORD WINAPI IWineD3DSurfaceImpl_GetPriority(IWineD3DSurface *iface); WINED3DRESOURCETYPE WINAPI IWineD3DBaseSurfaceImpl_GetType(IWineD3DSurface *iface);
void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer);
WINED3DRESOURCETYPE WINAPI IWineD3DSurfaceImpl_GetType(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc);
HRESULT WINAPI IWineD3DSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags); HRESULT WINAPI IWineD3DBaseSurfaceImpl_IsLost(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD Flags); HRESULT WINAPI IWineD3DBaseSurfaceImpl_Restore(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_IsLost(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD3DPalette **Pal);
HRESULT WINAPI IWineD3DSurfaceImpl_Restore(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPixelFormat(IWineD3DSurface *iface, WINED3DFORMAT Format, BYTE *Surface, DWORD Size); HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, WINEDDCOLORKEY *CKey);
HRESULT WINAPI IWineD3DSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD3DPalette **Pal); HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal); DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, WINEDDCOLORKEY *CKey); HRESULT WINAPI IWineD3DBaseSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_CleanDirtyRect(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetOverlayPosition(IWineD3DSurface *iface, LONG X, LONG Y);
extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, CONST RECT* pDirtyRect); HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetOverlayPosition(IWineD3DSurface *iface, LONG *X, LONG *Y);
HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container); HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlayZOrder(IWineD3DSurface *iface, DWORD Flags, IWineD3DSurface *Ref);
void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT textureName, int target); HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *SrcRect, IWineD3DSurface *DstSurface, RECT *DstRect, DWORD Flags, WINEDDOVERLAYFX *FX);
void WINAPI IWineD3DSurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription); HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetClipper(IWineD3DSurface *iface, IWineD3DClipper *clipper);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DClipper **clipper);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format);
HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags);
const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface); const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format);
HRESULT WINAPI IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter);
HRESULT WINAPI IWineGDISurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal);
HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC);
HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC);
DWORD WINAPI IWineD3DSurfaceImpl_GetPitch(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem);
HRESULT WINAPI IWineD3DSurfaceImpl_SetOverlayPosition(IWineD3DSurface *iface, LONG X, LONG Y);
HRESULT WINAPI IWineD3DSurfaceImpl_GetOverlayPosition(IWineD3DSurface *iface, LONG *X, LONG *Y);
HRESULT WINAPI IWineD3DSurfaceImpl_UpdateOverlayZOrder(IWineD3DSurface *iface, DWORD Flags, IWineD3DSurface *Ref);
HRESULT WINAPI IWineD3DSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *SrcRect, IWineD3DSurface *DstSurface, RECT *DstRect, DWORD Flags, WINEDDOVERLAYFX *FX);
HRESULT WINAPI IWineD3DSurfaceImpl_SetClipper(IWineD3DSurface *iface, IWineD3DClipper *clipper);
HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DClipper **clipper);
/* Surface flags: */ /* Surface flags: */
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */ #define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
@ -1200,6 +1196,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
#define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a color key */ #define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a color key */
#define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on that texture */ #define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on that texture */
#define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this surface */ #define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this surface */
#define SFLAG_PBO 0x00040000 /* Has a PBO attached for speeding up data transfers for dynamically locked surfaces */
/* In some conditions the surface memory must not be freed: /* In some conditions the surface memory must not be freed:
* SFLAG_OVERSIZE: Not all data can be kept in GL * SFLAG_OVERSIZE: Not all data can be kept in GL
@ -1208,6 +1205,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
* SFLAG_LOCKED: The app requires access to the surface data * SFLAG_LOCKED: The app requires access to the surface data
* SFLAG_DYNLOCK: Avoid freeing the data for performance * SFLAG_DYNLOCK: Avoid freeing the data for performance
* SFLAG_DYNCHANGE: Same reason as DYNLOCK * SFLAG_DYNCHANGE: Same reason as DYNLOCK
* SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
* SFLAG_CLIENT: OpenGL uses our memory as backup * SFLAG_CLIENT: OpenGL uses our memory as backup
*/ */
#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \ #define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \
@ -1217,8 +1215,12 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
SFLAG_DYNLOCK | \ SFLAG_DYNLOCK | \
SFLAG_DYNCHANGE | \ SFLAG_DYNCHANGE | \
SFLAG_USERPTR | \ SFLAG_USERPTR | \
SFLAG_PBO | \
SFLAG_CLIENT) SFLAG_CLIENT)
#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \
SFLAG_INTEXTURE | \
SFLAG_INDRAWABLE)
BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]); BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]);
typedef enum { typedef enum {
@ -1236,6 +1238,7 @@ typedef enum {
CONVERT_CK_8888_ARGB, CONVERT_CK_8888_ARGB,
CONVERT_RGB32_888, CONVERT_RGB32_888,
CONVERT_V8U8, CONVERT_V8U8,
CONVERT_L6V5U5,
CONVERT_X8L8V8U8, CONVERT_X8L8V8U8,
CONVERT_Q8W8V8U8, CONVERT_Q8W8V8U8,
CONVERT_V16U16, CONVERT_V16U16,
@ -1348,8 +1351,8 @@ struct IWineD3DStateBlockImpl
/* Indices */ /* Indices */
IWineD3DIndexBuffer* pIndexData; IWineD3DIndexBuffer* pIndexData;
UINT baseVertexIndex; INT baseVertexIndex;
UINT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */ INT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
/* Transform */ /* Transform */
WINED3DMATRIX transforms[HIGHEST_TRANSFORMSTATE + 1]; WINED3DMATRIX transforms[HIGHEST_TRANSFORMSTATE + 1];
@ -1465,10 +1468,12 @@ extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
/* Datastructures for IWineD3DQueryImpl.extendedData */ /* Datastructures for IWineD3DQueryImpl.extendedData */
typedef struct WineQueryOcclusionData { typedef struct WineQueryOcclusionData {
GLuint queryId; GLuint queryId;
WineD3DContext *ctx;
} WineQueryOcclusionData; } WineQueryOcclusionData;
typedef struct WineQueryEventData { typedef struct WineQueryEventData {
GLuint fenceId; GLuint fenceId;
WineD3DContext *ctx;
} WineQueryEventData; } WineQueryEventData;
/***************************************************************************** /*****************************************************************************
@ -1535,7 +1540,7 @@ GLenum StencilOp(DWORD op);
GLenum CompareFunc(DWORD func); GLenum CompareFunc(DWORD func);
void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3); void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx); void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx);
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords); void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype);
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height); void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain); GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
@ -1545,6 +1550,7 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize
/* Math utils */ /* Math utils */
void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2); void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
unsigned int count_bits(unsigned int mask);
/***************************************************************************** /*****************************************************************************
* To enable calling of inherited functions, requires prototypes * To enable calling of inherited functions, requires prototypes
@ -1600,7 +1606,6 @@ void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED
/*** class static members ***/ /*** class static members ***/
void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface); void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface);
struct SHADER_OPCODE_ARG;
typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*); typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*);
/* Struct to maintain a list of GLSL shader programs and their associated pixel and /* Struct to maintain a list of GLSL shader programs and their associated pixel and
@ -1612,6 +1617,15 @@ struct glsl_shader_prog_link {
GLhandleARB programId; GLhandleARB programId;
GLhandleARB *vuniformF_locations; GLhandleARB *vuniformF_locations;
GLhandleARB *puniformF_locations; GLhandleARB *puniformF_locations;
GLhandleARB vuniformI_locations[MAX_CONST_I];
GLhandleARB puniformI_locations[MAX_CONST_I];
GLhandleARB posFixup_location;
GLhandleARB bumpenvmat_location;
GLhandleARB luminancescale_location;
GLhandleARB luminanceoffset_location;
GLhandleARB srgb_comparison_location;
GLhandleARB srgb_mul_low_location;
GLhandleARB ycorrection_location;
GLhandleARB vshader; GLhandleARB vshader;
GLhandleARB pshader; GLhandleARB pshader;
}; };
@ -1659,10 +1673,11 @@ typedef struct shader_reg_maps {
/* Sampler usage tokens /* Sampler usage tokens
* Use 0 as default (bit 31 is always 1 on a valid token) */ * Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
char bumpmat; char bumpmat, luminanceparams;
char usesnrm, vpos, usesdsy;
/* Whether or not a loop is used in this shader */ /* Whether or not loops are used in this shader, and nesting depth */
char loop; unsigned loop_depth;
/* Whether or not this shader uses fog */ /* Whether or not this shader uses fog */
char fog; char fog;
@ -1788,10 +1803,22 @@ extern void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg); extern void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg); extern void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg); extern void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texkill(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg);
/* ARB vertex / pixel shader common prototypes */
extern void shader_hw_nrm(SHADER_OPCODE_ARG* arg);
extern void shader_hw_sincos(SHADER_OPCODE_ARG* arg);
extern void shader_hw_mnxn(SHADER_OPCODE_ARG* arg);
/* ARB vertex shader prototypes */ /* ARB vertex shader prototypes */
extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg); extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg);
extern void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg);
extern void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg); extern void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg);
/* GLSL helper functions */ /* GLSL helper functions */
@ -1834,6 +1861,7 @@ extern void shader_glsl_call(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg); extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_label(SHADER_OPCODE_ARG* arg); extern void shader_glsl_label(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg); extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_log(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_texldl(SHADER_OPCODE_ARG* arg); extern void shader_glsl_texldl(SHADER_OPCODE_ARG* arg);
/** GLSL Pixel Shader Prototypes */ /** GLSL Pixel Shader Prototypes */
@ -1859,12 +1887,8 @@ extern void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg); extern void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_input_pack( extern void pshader_glsl_input_pack(
SHADER_BUFFER* buffer, SHADER_BUFFER* buffer,
semantic* semantics_out); semantic* semantics_out,
IWineD3DPixelShader *iface);
/** GLSL Vertex Shader Prototypes */
extern void vshader_glsl_output_unpack(
SHADER_BUFFER* buffer,
semantic* semantics_out);
/***************************************************************************** /*****************************************************************************
* IDirect3DBaseShader implementation structure * IDirect3DBaseShader implementation structure
@ -1879,6 +1903,7 @@ typedef struct IWineD3DBaseShaderClass
UINT functionLength; UINT functionLength;
GLuint prgId; GLuint prgId;
BOOL is_compiled; BOOL is_compiled;
UINT cur_loop_depth, cur_loop_regno;
/* Type of shader backend */ /* Type of shader backend */
int shader_mode; int shader_mode;
@ -1892,6 +1917,17 @@ typedef struct IWineD3DBaseShaderClass
struct list constantsI; struct list constantsI;
shader_reg_maps reg_maps; shader_reg_maps reg_maps;
/* Pixel formats of sampled textures, for format conversion. This
* represents the formats found during compilation, it is not initialized
* on the first parser pass. It is needed to check if the shader
* needs recompilation to adjust the format conversion
*/
WINED3DFORMAT sampled_format[MAX_COMBINED_SAMPLERS];
UINT sampled_samplers[MAX_COMBINED_SAMPLERS];
UINT num_sampled_samplers;
UINT recompile_count;
/* Pointer to the parent device */ /* Pointer to the parent device */
IWineD3DDevice *device; IWineD3DDevice *device;
@ -2030,6 +2066,9 @@ typedef struct IWineD3DVertexShaderImpl {
/* run time datas... */ /* run time datas... */
VSHADERDATA *data; VSHADERDATA *data;
UINT min_rel_offset, max_rel_offset;
UINT rel_offset;
#if 0 /* needs reworking */ #if 0 /* needs reworking */
/* run time datas */ /* run time datas */
VSHADERINPUTDATA input; VSHADERINPUTDATA input;
@ -2042,6 +2081,13 @@ extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
/***************************************************************************** /*****************************************************************************
* IDirect3DPixelShader implementation structure * IDirect3DPixelShader implementation structure
*/ */
enum vertexprocessing_mode {
fixedfunction,
vertexshader,
pretransformed
};
typedef struct IWineD3DPixelShaderImpl { typedef struct IWineD3DPixelShaderImpl {
/* IUnknown parts */ /* IUnknown parts */
const IWineD3DPixelShaderVtbl *lpVtbl; const IWineD3DPixelShaderVtbl *lpVtbl;
@ -2055,6 +2101,8 @@ typedef struct IWineD3DPixelShaderImpl {
/* Pixel shader input semantics */ /* Pixel shader input semantics */
semantic semantics_in [MAX_REG_INPUT]; semantic semantics_in [MAX_REG_INPUT];
DWORD input_reg_map[MAX_REG_INPUT];
BOOL input_reg_used[MAX_REG_INPUT];
/* run time data */ /* run time data */
PSHADERDATA *data; PSHADERDATA *data;
@ -2062,6 +2110,15 @@ typedef struct IWineD3DPixelShaderImpl {
/* Some information about the shader behavior */ /* Some information about the shader behavior */
char needsbumpmat; char needsbumpmat;
UINT bumpenvmatconst; UINT bumpenvmatconst;
UINT luminanceconst;
char srgb_enabled;
char srgb_mode_hardcoded;
UINT srgb_low_const;
UINT srgb_cmp_const;
char vpos_uniform;
BOOL render_offscreen;
UINT height;
enum vertexprocessing_mode vertexprocessing;
#if 0 /* needs reworking */ #if 0 /* needs reworking */
PSHADERINPUTDATA input; PSHADERINPUTDATA input;
@ -2072,6 +2129,13 @@ typedef struct IWineD3DPixelShaderImpl {
extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[]; extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl; extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
/* sRGB correction constants */
static const float srgb_cmp = 0.0031308;
static const float srgb_mul_low = 12.92;
static const float srgb_pow = 0.41666;
static const float srgb_mul_high = 1.055;
static const float srgb_sub_high = 0.055;
/***************************************************************************** /*****************************************************************************
* IWineD3DPalette implementation structure * IWineD3DPalette implementation structure
*/ */

View file

@ -293,6 +293,7 @@ typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE {
/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */ /* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
#define WINED3DSI_TEXLD_PROJECT 0x00010000 #define WINED3DSI_TEXLD_PROJECT 0x00010000
#define WINED3DSI_TEXLD_BIAS 0x00020000
/** Shader version tokens, and shader end tokens **/ /** Shader version tokens, and shader end tokens **/

View file

@ -1137,6 +1137,7 @@ void (WINE_GLAPI *glVertex4s) (GLshort x, GLshort y, GLshort z, GLshort w);
void (WINE_GLAPI *glVertex4sv) (const GLshort* v); void (WINE_GLAPI *glVertex4sv) (const GLshort* v);
void (WINE_GLAPI *glVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); void (WINE_GLAPI *glVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
void (WINE_GLAPI *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height); void (WINE_GLAPI *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
void (WINE_GLAPI *glPointParameterfv) (GLenum pname, const GLfloat *params);
/* WGL functions */ /* WGL functions */
HGLRC (WINAPI *pwglCreateContext)(HDC); HGLRC (WINAPI *pwglCreateContext)(HDC);
@ -1483,7 +1484,8 @@ BOOL (WINAPI *pwglShareLists)(HGLRC,HGLRC);
USE_GL_FUNC(glVertex4s) \ USE_GL_FUNC(glVertex4s) \
USE_GL_FUNC(glVertex4sv) \ USE_GL_FUNC(glVertex4sv) \
USE_GL_FUNC(glVertexPointer) \ USE_GL_FUNC(glVertexPointer) \
USE_GL_FUNC(glViewport) USE_GL_FUNC(glViewport) \
USE_GL_FUNC(glPointParameterfv) \
#define WGL_FUNCS_GEN \ #define WGL_FUNCS_GEN \
USE_WGL_FUNC(wglCreateContext) \ USE_WGL_FUNC(wglCreateContext) \
@ -2353,6 +2355,13 @@ typedef GLhandleARB (WINE_GLAPI * WINED3D_PFNGLGETHANDLEARBPROC) (GLenum pname);
typedef void (WINE_GLAPI * WINED3D_PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); typedef void (WINE_GLAPI * WINED3D_PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
typedef void (WINE_GLAPI * WINED3D_PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (WINE_GLAPI * WINED3D_PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
typedef GLint (WINE_GLAPI * WINED3D_PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef GLint (WINE_GLAPI * WINED3D_PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
/* GL_ARB_pixel_buffer_object */
#ifndef GL_ARB_pixel_buffer_object
#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
#endif
/* GL_EXT_texture */ /* GL_EXT_texture */
#ifndef GL_EXT_texture #ifndef GL_EXT_texture
#define GL_EXT_texture 1 #define GL_EXT_texture 1
@ -2709,7 +2718,7 @@ typedef void (WINE_GLAPI * PGLFNGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage
#endif #endif
/** /**
* Point sprites * Point sprites
*/ */
/* GL_ARB_point_sprite */ /* GL_ARB_point_sprite */
#ifndef GL_ARB_point_sprite #ifndef GL_ARB_point_sprite
@ -2718,11 +2727,11 @@ typedef void (WINE_GLAPI * PGLFNGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage
#define GL_COORD_REPLACE_ARB 0x8862 #define GL_COORD_REPLACE_ARB 0x8862
#endif #endif
/** /**
* @TODO: GL_NV_point_sprite * @TODO: GL_NV_point_sprite
*/ */
/** /**
* Occlusion Queries * Occlusion Queries
*/ */
/* GL_ARB_occlusion_query */ /* GL_ARB_occlusion_query */
#ifndef GL_ARB_occlusion_query #ifndef GL_ARB_occlusion_query
@ -2833,6 +2842,30 @@ typedef void (WINE_GLAPI * PGLFNGETTEXBUMPPARAMETERFVATIPROC) (GLenum, GLfloat *
typedef int (WINE_GLAPI * PGLXFNGETVIDEOSYNCSGIPROC) (unsigned int *); typedef int (WINE_GLAPI * PGLXFNGETVIDEOSYNCSGIPROC) (unsigned int *);
typedef int (WINE_GLAPI * PGLXFNWAITVIDEOSYNCSGIPROC) (int, int, unsigned int *); typedef int (WINE_GLAPI * PGLXFNWAITVIDEOSYNCSGIPROC) (int, int, unsigned int *);
/* GL_SGIS_generate_mipmap */
#ifndef GLX_SGIS_generate_mipmap
#define GL_GENERATE_MIPMAP_SGIS 0x8191
#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
#define GLX_SGIS_generate_mipmap
#endif
/* GL_NV_depth_clamp */
#ifndef GL_NV_depth_clamp
#define GL_DEPTH_CLAMP_NV 0x864F
#endif
/* GL_APPLE_flush_render */
typedef void (WINE_GLAPI * PGLFNFLUSHRENDERAPPLEPROC) (void);
typedef void (WINE_GLAPI * PGLFNFINISHRENDERAPPLEPROC) (void);
/* GL_APPLE_ycbcr_422 */
#ifndef GL_APPLE_ycbcr_422
#define GL_APPLE_ycbcr_422
#define GL_YCBCR_422_APPLE 0x85B9
#define UNSIGNED_SHORT_8_8_APPLE 0x85BA
#define UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
#endif
/* GL_VERSION_2_0 */ /* GL_VERSION_2_0 */
#ifndef GL_VERSION_2_0 #ifndef GL_VERSION_2_0
#define GL_VERSION_2_0 1 #define GL_VERSION_2_0 1
@ -3018,8 +3051,8 @@ typedef void (WINE_GLAPI * PGLFNVERTEXATTRIBPOINTERPROC) (GLuint index, GLint si
/**************************************************** /****************************************************
* OpenGL Official Version * OpenGL Official Version
* defines * defines
****************************************************/ ****************************************************/
/* GL_VERSION_1_3 */ /* GL_VERSION_1_3 */
#if !defined(GL_DOT3_RGBA) #if !defined(GL_DOT3_RGBA)
@ -3050,6 +3083,9 @@ typedef enum _GL_Cards {
CARD_ATI_RADEON_9500 = 0x4144, CARD_ATI_RADEON_9500 = 0x4144,
CARD_ATI_RADEON_X700 = 0x5e4c, CARD_ATI_RADEON_X700 = 0x5e4c,
CARD_ATI_RADEON_X1600 = 0x71c2, CARD_ATI_RADEON_X1600 = 0x71c2,
CARD_ATI_RADEON_HD2300 = 0x7210,
CARD_ATI_RADEON_HD2600 = 0x9581,
CARD_ATI_RADEON_HD2900 = 0x9400,
CARD_NVIDIA_RIVA_128 = 0x0018, CARD_NVIDIA_RIVA_128 = 0x0018,
CARD_NVIDIA_RIVA_TNT = 0x0020, CARD_NVIDIA_RIVA_TNT = 0x0020,
@ -3067,6 +3103,9 @@ typedef enum _GL_Cards {
CARD_NVIDIA_GEFORCE_6600GT = 0x0140, CARD_NVIDIA_GEFORCE_6600GT = 0x0140,
CARD_NVIDIA_GEFORCE_6800 = 0x0041, CARD_NVIDIA_GEFORCE_6800 = 0x0041,
CARD_NVIDIA_GEFORCE_7800GT = 0x0092, CARD_NVIDIA_GEFORCE_7800GT = 0x0092,
CARD_NVIDIA_GEFORCE_8300GS = 0x0423,
CARD_NVIDIA_GEFORCE_8600GT = 0x0402,
CARD_NVIDIA_GEFORCE_8800GTS = 0x0193,
CARD_INTEL_845G = 0x2562, CARD_INTEL_845G = 0x2562,
CARD_INTEL_I830G = 0x3577, CARD_INTEL_I830G = 0x3577,
@ -3076,6 +3115,8 @@ typedef enum _GL_Cards {
CARD_INTEL_I915GM = 0x2592 CARD_INTEL_I915GM = 0x2592
} GL_Cards; } GL_Cards;
#define WINE_DEFAULT_VIDMEM 64*1024*1024
typedef enum _GL_VSVersion { typedef enum _GL_VSVersion {
VS_VERSION_NOT_SUPPORTED = 0x0, VS_VERSION_NOT_SUPPORTED = 0x0,
VS_VERSION_10 = 0x10, VS_VERSION_10 = 0x10,
@ -3167,6 +3208,7 @@ typedef enum _GL_SupportedExt {
NV_VERTEX_PROGRAM2, NV_VERTEX_PROGRAM2,
NV_VERTEX_PROGRAM3, NV_VERTEX_PROGRAM3,
NV_FENCE, NV_FENCE,
NV_DEPTH_CLAMP,
/* ATI */ /* ATI */
ATI_SEPARATE_STENCIL, ATI_SEPARATE_STENCIL,
ATI_TEXTURE_ENV_COMBINE3, ATI_TEXTURE_ENV_COMBINE3,
@ -3176,8 +3218,11 @@ typedef enum _GL_SupportedExt {
/* APPLE */ /* APPLE */
APPLE_FENCE, APPLE_FENCE,
APPLE_CLIENT_STORAGE, APPLE_CLIENT_STORAGE,
APPLE_FLUSH_RENDER,
APPLE_YCBCR_422,
/* SGI */ /* SGI */
SGI_VIDEO_SYNC, SGI_VIDEO_SYNC,
SGIS_GENERATE_MIPMAP,
/* WGL extensions */ /* WGL extensions */
WGL_ARB_PBUFFER, WGL_ARB_PBUFFER,
@ -3187,15 +3232,15 @@ typedef enum _GL_SupportedExt {
/**************************************************** /****************************************************
* #Defines * #Defines
****************************************************/ ****************************************************/
#define GL_EXT_FUNCS_GEN \ #define GL_EXT_FUNCS_GEN \
/** ARB Extensions **/ \ /** ARB Extensions **/ \
/* GL_ARB_draw_buffers */ \ /* GL_ARB_draw_buffers */ \
USE_GL_FUNC(PGLFNDRAWBUFFERSARBPROC, glDrawBuffersARB); \ USE_GL_FUNC(PGLFNDRAWBUFFERSARBPROC, glDrawBuffersARB); \
/* GL_ARB_imaging */ \ /* GL_ARB_imaging, GL_EXT_blend_minmax */ \
USE_GL_FUNC(PGLFNBLENDCOLORPROC, glBlendColor); \ USE_GL_FUNC(PGLFNBLENDCOLORPROC, glBlendColorEXT); \
USE_GL_FUNC(PGLFNBLENDEQUATIONPROC, glBlendEquation); \ USE_GL_FUNC(PGLFNBLENDEQUATIONPROC, glBlendEquationEXT); \
/* GL_ARB_multisample */ \ /* GL_ARB_multisample */ \
USE_GL_FUNC(WINED3D_PFNGLSAMPLECOVERAGEARBPROC, glSampleCoverageARB); \ USE_GL_FUNC(WINED3D_PFNGLSAMPLECOVERAGEARBPROC, glSampleCoverageARB); \
/* GL_ARB_multitexture */ \ /* GL_ARB_multitexture */ \
@ -3343,9 +3388,9 @@ typedef enum _GL_SupportedExt {
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, glUniform2fARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, glUniform2fARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FARBPROC, glUniform3fARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FARBPROC, glUniform3fARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FARBPROC, glUniform4fARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FARBPROC, glUniform4fARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1fvARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM1FVARBPROC, glUniform1fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2fvARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FVARBPROC, glUniform2fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3IVARBPROC, glUniform3fvARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FVARBPROC, glUniform3fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FVARBPROC, glUniform4fvARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FVARBPROC, glUniform4fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1ivARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1ivARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2ivARB); \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2ivARB); \
@ -3457,6 +3502,9 @@ typedef enum _GL_SupportedExt {
/* GLX_SGI_video_sync */ \ /* GLX_SGI_video_sync */ \
USE_GL_FUNC(PGLXFNGETVIDEOSYNCSGIPROC, glXGetVideoSyncSGI); \ USE_GL_FUNC(PGLXFNGETVIDEOSYNCSGIPROC, glXGetVideoSyncSGI); \
USE_GL_FUNC(PGLXFNWAITVIDEOSYNCSGIPROC, glXWaitVideoSyncSGI); \ USE_GL_FUNC(PGLXFNWAITVIDEOSYNCSGIPROC, glXWaitVideoSyncSGI); \
/* GL_APPLE_flush_render */ \
USE_GL_FUNC(PGLFNFLUSHRENDERAPPLEPROC, glFlushRenderApple); \
USE_GL_FUNC(PGLFNFINISHRENDERAPPLEPROC, glFinishRenderApple); \
/* OpenGL 2.0 functions */ /* OpenGL 2.0 functions */
#define GL2_FUNCS_GEN \ #define GL2_FUNCS_GEN \
@ -3657,11 +3705,12 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer,
/**************************************************** /****************************************************
* Structures * Structures
****************************************************/ ****************************************************/
typedef struct { typedef struct {
GLint glInternal, glGammaInternal, glFormat, glType; GLint glInternal, glGammaInternal, glFormat, glType;
WINED3DFORMAT conversion_group;
} GlPixelFormatDesc; } GlPixelFormatDesc;
#define USE_GL_FUNC(type, pfn) type pfn; #define USE_GL_FUNC(type, pfn) type pfn;
@ -3672,10 +3721,11 @@ typedef struct _WineD3D_GL_Info {
GL_Vendors gl_vendor; GL_Vendors gl_vendor;
GL_Cards gl_card; GL_Cards gl_card;
UINT vidmem;
DWORD gl_driver_version; DWORD gl_driver_version;
CHAR gl_renderer[255]; CHAR gl_renderer[255];
/** /**
* CAPS Constants * CAPS Constants
*/ */
UINT max_buffers; UINT max_buffers;
UINT max_lights; UINT max_lights;
@ -3688,10 +3738,11 @@ typedef struct _WineD3D_GL_Info {
UINT max_clipplanes; UINT max_clipplanes;
UINT max_texture_size; UINT max_texture_size;
UINT max_texture3d_size; UINT max_texture3d_size;
float max_pointsize; float max_pointsize, max_pointsizemin;
UINT max_blends; UINT max_blends;
UINT max_anisotropy; UINT max_anisotropy;
UINT max_aux_buffers; UINT max_aux_buffers;
UINT max_glsl_varyings;
unsigned max_vshader_constantsF; unsigned max_vshader_constantsF;
unsigned max_pshader_constantsF; unsigned max_pshader_constantsF;
@ -3712,6 +3763,8 @@ typedef struct _WineD3D_GL_Info {
GL_VSVersion vs_nv_version; GL_VSVersion vs_nv_version;
GL_VSVersion vs_ati_version; GL_VSVersion vs_ati_version;
BOOL arb_vs_offset_limit;
BOOL supported[OPENGL_SUPPORTED_EXT_END + 1]; BOOL supported[OPENGL_SUPPORTED_EXT_END + 1];
/** OpenGL EXT and ARB functions ptr */ /** OpenGL EXT and ARB functions ptr */

View file

@ -36,7 +36,7 @@ struct IWineD3DSurface;
#include "wined3d_types.h" #include "wined3d_types.h"
/***************************************************************** /*****************************************************************
* THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES * THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES
* PLEASE USE wine/wined3d_gl.h INSTEAD * PLEASE USE wine/wined3d_gl.h INSTEAD
*/ */
@ -109,14 +109,14 @@ struct IWineD3DClipper;
/* {108F9C44-6F30-11d9-C687-00046142C14F} */ /* {108F9C44-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3D, DEFINE_GUID(IID_IWineD3D,
0x108f9c44, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x108f9c44, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
DEFINE_GUID(IID_IWineD3DBase, DEFINE_GUID(IID_IWineD3DBase,
0x46799311, 0x8e0e, 0x40ce, 0xb2, 0xec, 0xdd, 0xb9, 0x9f, 0x18, 0xfc, 0xb4); 0x46799311, 0x8e0e, 0x40ce, 0xb2, 0xec, 0xdd, 0xb9, 0x9f, 0x18, 0xfc, 0xb4);
/* {108F9C44-6F30-11d9-C687-00046142C14F} */ /* {108F9C44-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DDevice, DEFINE_GUID(IID_IWineD3DDevice,
0x108f9c44, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x108f9c44, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {f756720c-32b9-4439-b5a3-1d6c97037d9e} */ /* {f756720c-32b9-4439-b5a3-1d6c97037d9e} */
@ -124,49 +124,49 @@ DEFINE_GUID(IID_IWineD3DPalette,
0xf756720c, 0x32b9, 0x4439, 0xb5, 0xa3, 0x1d, 0x6c, 0x97, 0x03, 0x7d, 0x9e); 0xf756720c, 0x32b9, 0x4439, 0xb5, 0xa3, 0x1d, 0x6c, 0x97, 0x03, 0x7d, 0x9e);
/* {1F3BFB34-6F30-11d9-C687-00046142C14F} */ /* {1F3BFB34-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DResource, DEFINE_GUID(IID_IWineD3DResource,
0x1f3bfb34, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x1f3bfb34, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {217F671E-6F30-11d9-C687-00046142C14F} */ /* {217F671E-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DVertexBuffer, DEFINE_GUID(IID_IWineD3DVertexBuffer,
0x217f671e, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x217f671e, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {24769ED8-6F30-11d9-C687-00046142C14F} */ /* {24769ED8-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DVolume, DEFINE_GUID(IID_IWineD3DVolume,
0x24769ed8, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x24769ed8, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {34D01B10-6F30-11d9-C687-00046142C14F} */ /* {34D01B10-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DSwapChain, DEFINE_GUID(IID_IWineD3DSwapChain,
0x34d01b10, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x34d01b10, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {37CD5526-6F30-11d9-C687-00046142C14F} */ /* {37CD5526-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DSurface, DEFINE_GUID(IID_IWineD3DSurface,
0x37cd5526, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x37cd5526, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {3A02A54E-6F30-11d9-C687-00046142C14F} */ /* {3A02A54E-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DIndexBuffer, DEFINE_GUID(IID_IWineD3DIndexBuffer,
0x3a02a54e, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x3a02a54e, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {3C2AEBF6-6F30-11d9-C687-00046142C14F} */ /* {3C2AEBF6-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DBaseTexture, DEFINE_GUID(IID_IWineD3DBaseTexture,
0x3c2aebf6, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x3c2aebf6, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {3E72CC1C-6F30-11d9-C687-00046142C14F} */ /* {3E72CC1C-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DTexture, DEFINE_GUID(IID_IWineD3DTexture,
0x3e72cc1c, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x3e72cc1c, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {41752900-6F30-11d9-C687-00046142C14F} */ /* {41752900-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DCubeTexture, DEFINE_GUID(IID_IWineD3DCubeTexture,
0x41752900, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x41752900, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {7B39470C-6F30-11d9-C687-00046142C14F} */ /* {7B39470C-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DVolumeTexture, DEFINE_GUID(IID_IWineD3DVolumeTexture,
0x7b39470c, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x7b39470c, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {7CD55BE6-6F30-11d9-C687-00046142C14F} */ /* {7CD55BE6-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DVertexDeclaration, DEFINE_GUID(IID_IWineD3DVertexDeclaration,
0x7cd55be6, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x7cd55be6, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {EAC93065-A4DF-446F-86A1-9EF2BCA40A3C} */ /* {EAC93065-A4DF-446F-86A1-9EF2BCA40A3C} */
@ -174,19 +174,19 @@ DEFINE_GUID(IID_IWineD3DBaseShader,
0xeac93065, 0xa4df, 0x446f, 0x86, 0xa1, 0x9e, 0xf2, 0xbc, 0xa4, 0x0a, 0x3c); 0xeac93065, 0xa4df, 0x446f, 0x86, 0xa1, 0x9e, 0xf2, 0xbc, 0xa4, 0x0a, 0x3c);
/* {7F7A2B60-6F30-11d9-C687-00046142C14F} */ /* {7F7A2B60-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DVertexShader, DEFINE_GUID(IID_IWineD3DVertexShader,
0x7f7a2b60, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x7f7a2b60, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {818503DA-6F30-11d9-C687-00046142C14F} */ /* {818503DA-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DPixelShader, DEFINE_GUID(IID_IWineD3DPixelShader,
0x818503da, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x818503da, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {83B073CE-6F30-11d9-C687-00046142C14F} */ /* {83B073CE-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DStateBlock, DEFINE_GUID(IID_IWineD3DStateBlock,
0x83b073ce, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x83b073ce, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {905DDBAC-6F30-11d9-C687-00046142C14F} */ /* {905DDBAC-6F30-11d9-C687-00046142C14F} */
DEFINE_GUID(IID_IWineD3DQuery, DEFINE_GUID(IID_IWineD3DQuery,
0x905ddbac, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); 0x905ddbac, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
/* {8f2bceb1-d338-488c-ab7f-0ec980bf5d2d} */ /* {8f2bceb1-d338-488c-ab7f-0ec980bf5d2d} */
@ -196,53 +196,53 @@ DEFINE_GUID(IID_IWineD3DClipper,
/***************************************************************************** /*****************************************************************************
* Callback functions required for predefining surfaces / stencils * Callback functions required for predefining surfaces / stencils
*/ */
typedef HRESULT WINAPI (*D3DCB_CREATERENDERTARGETFN) (IUnknown *pDevice, typedef HRESULT (WINAPI *D3DCB_CREATERENDERTARGETFN) (IUnknown *pDevice,
IUnknown *pSuperior, IUnknown *pSuperior,
UINT Width, UINT Width,
UINT Height, UINT Height,
WINED3DFORMAT Format, WINED3DFORMAT Format,
WINED3DMULTISAMPLE_TYPE MultiSample, WINED3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality, DWORD MultisampleQuality,
BOOL Lockable, BOOL Lockable,
struct IWineD3DSurface **ppSurface, struct IWineD3DSurface **ppSurface,
HANDLE *pSharedHandle); HANDLE *pSharedHandle);
typedef HRESULT WINAPI (*D3DCB_CREATESURFACEFN) (IUnknown *pDevice, typedef HRESULT (WINAPI *D3DCB_CREATESURFACEFN) (IUnknown *pDevice,
IUnknown *pSuperior, IUnknown *pSuperior,
UINT Width, UINT Width,
UINT Height, UINT Height,
WINED3DFORMAT Format, WINED3DFORMAT Format,
DWORD Usage, DWORD Usage,
WINED3DPOOL Pool, WINED3DPOOL Pool,
UINT Level, UINT Level,
WINED3DCUBEMAP_FACES Face, WINED3DCUBEMAP_FACES Face,
struct IWineD3DSurface **ppSurface, struct IWineD3DSurface **ppSurface,
HANDLE *pSharedHandle); HANDLE *pSharedHandle);
typedef HRESULT WINAPI (*D3DCB_CREATEDEPTHSTENCILSURFACEFN) (IUnknown *pDevice, typedef HRESULT (WINAPI *D3DCB_CREATEDEPTHSTENCILSURFACEFN) (IUnknown *pDevice,
IUnknown *pSuperior, IUnknown *pSuperior,
UINT Width, UINT Width,
UINT Height, UINT Height,
WINED3DFORMAT Format, WINED3DFORMAT Format,
WINED3DMULTISAMPLE_TYPE MultiSample, WINED3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality, DWORD MultisampleQuality,
BOOL Discard, BOOL Discard,
struct IWineD3DSurface **ppSurface, struct IWineD3DSurface **ppSurface,
HANDLE *pSharedHandle); HANDLE *pSharedHandle);
typedef HRESULT WINAPI (*D3DCB_CREATEVOLUMEFN) (IUnknown *pDevice, typedef HRESULT (WINAPI *D3DCB_CREATEVOLUMEFN) (IUnknown *pDevice,
IUnknown *pSuperior, IUnknown *pSuperior,
UINT Width, UINT Width,
UINT Height, UINT Height,
UINT Depth, UINT Depth,
WINED3DFORMAT Format, WINED3DFORMAT Format,
WINED3DPOOL Pool, WINED3DPOOL Pool,
DWORD Usage, DWORD Usage,
struct IWineD3DVolume **ppVolume, struct IWineD3DVolume **ppVolume,
HANDLE *pSharedHandle); HANDLE *pSharedHandle);
typedef HRESULT WINAPI (*D3DCB_CREATEADDITIONALSWAPCHAIN) (IUnknown *pDevice, typedef HRESULT (WINAPI *D3DCB_CREATEADDITIONALSWAPCHAIN) (IUnknown *pDevice,
WINED3DPRESENT_PARAMETERS *pPresentationParameters, WINED3DPRESENT_PARAMETERS *pPresentationParameters,
struct IWineD3DSwapChain **pSwapChain struct IWineD3DSwapChain **pSwapChain
); );
@ -250,11 +250,11 @@ typedef HRESULT WINAPI (*D3DCB_CREATEADDITIONALSWAPCHAIN) (IUnknown *pDevice,
/***************************************************************************** /*****************************************************************************
* Callback functions for custom implicit object destruction. * Callback functions for custom implicit object destruction.
*/ */
typedef ULONG WINAPI (*D3DCB_DESTROYSWAPCHAINFN) (struct IWineD3DSwapChain *pSwapChain); typedef ULONG (WINAPI *D3DCB_DESTROYSWAPCHAINFN) (struct IWineD3DSwapChain *pSwapChain);
typedef ULONG WINAPI (*D3DCB_DESTROYSURFACEFN) (struct IWineD3DSurface *pSurface); typedef ULONG (WINAPI *D3DCB_DESTROYSURFACEFN) (struct IWineD3DSurface *pSurface);
typedef ULONG WINAPI (*D3DCB_DESTROYVOLUMEFN) (struct IWineD3DVolume *pVolume); typedef ULONG (WINAPI *D3DCB_DESTROYVOLUMEFN) (struct IWineD3DVolume *pVolume);
/***************************************************************************** /*****************************************************************************
* IWineD3DBase interface * IWineD3DBase interface
@ -282,7 +282,7 @@ DECLARE_INTERFACE_(IWineD3DBase, IUnknown)
#endif #endif
/***************************************************************************** /*****************************************************************************
* IWineD3D interface * IWineD3D interface
*/ */
#define INTERFACE IWineD3D #define INTERFACE IWineD3D
@ -341,11 +341,11 @@ DECLARE_INTERFACE_(IWineD3D, IWineD3DBase)
IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent); IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent);
/***************************************************************************** /*****************************************************************************
* IWineD3DDevice interface * IWineD3DDevice interface
*/ */
#define INTERFACE IWineD3DDevice #define INTERFACE IWineD3DDevice
DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
{ {
/*** IUnknown methods ***/ /*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE; STDMETHOD_(ULONG,AddRef)(THIS) PURE;
@ -356,7 +356,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,WINED3DPOOL Pool,struct IWineD3DVertexBuffer **ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent) PURE; STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,WINED3DPOOL Pool,struct IWineD3DVertexBuffer **ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent) PURE;
STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DIndexBuffer** ppIndexBuffer, HANDLE* pSharedHandle, IUnknown *parent) PURE; STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DIndexBuffer** ppIndexBuffer, HANDLE* pSharedHandle, IUnknown *parent) PURE;
STDMETHOD(CreateStateBlock)(THIS_ WINED3DSTATEBLOCKTYPE Type, struct IWineD3DStateBlock **ppStateBlock, IUnknown *parent) PURE; STDMETHOD(CreateStateBlock)(THIS_ WINED3DSTATEBLOCKTYPE Type, struct IWineD3DStateBlock **ppStateBlock, IUnknown *parent) PURE;
STDMETHOD(CreateSurface)(THIS_ UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, struct IWineD3DSurface** ppSurface, WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample ,DWORD MultisampleQuality, HANDLE* pSharedHandle, WINED3DSURFTYPE Impl, IUnknown *parent) PURE; STDMETHOD(CreateSurface)(THIS_ UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, struct IWineD3DSurface** ppSurface, WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample ,DWORD MultisampleQuality, HANDLE* pSharedHandle, WINED3DSURFTYPE Impl, IUnknown *parent) PURE;
STDMETHOD(CreateTexture)(THIS_ UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DTexture** ppTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATESURFACEFN pFn) PURE; STDMETHOD(CreateTexture)(THIS_ UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DTexture** ppTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATESURFACEFN pFn) PURE;
STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DVolumeTexture** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATEVOLUMEFN pFn) PURE; STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DVolumeTexture** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATEVOLUMEFN pFn) PURE;
STDMETHOD(CreateVolume)(THIS_ UINT Width, UINT Height, UINT Depth, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DVolume** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown *parent) PURE; STDMETHOD(CreateVolume)(THIS_ UINT Width, UINT Height, UINT Depth, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DVolume** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown *parent) PURE;
@ -405,8 +405,8 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, WINED3DGAMMARAMP* pRamp) PURE; STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, WINED3DGAMMARAMP* pRamp) PURE;
STDMETHOD(SetIndices)(THIS_ struct IWineD3DIndexBuffer * pIndexData) PURE; STDMETHOD(SetIndices)(THIS_ struct IWineD3DIndexBuffer * pIndexData) PURE;
STDMETHOD(GetIndices)(THIS_ struct IWineD3DIndexBuffer ** ppIndexData) PURE; STDMETHOD(GetIndices)(THIS_ struct IWineD3DIndexBuffer ** ppIndexData) PURE;
STDMETHOD(SetBaseVertexIndex)(THIS_ UINT baseIndex); STDMETHOD(SetBaseVertexIndex)(THIS_ INT baseIndex);
STDMETHOD(GetBaseVertexIndex)(THIS_ UINT *baseIndex); STDMETHOD(GetBaseVertexIndex)(THIS_ INT *baseIndex);
STDMETHOD(SetLight)(THIS_ DWORD Index,CONST WINED3DLIGHT * pLight) PURE; STDMETHOD(SetLight)(THIS_ DWORD Index,CONST WINED3DLIGHT * pLight) PURE;
STDMETHOD(GetLight)(THIS_ DWORD Index,WINED3DLIGHT * pLight) PURE; STDMETHOD(GetLight)(THIS_ DWORD Index,WINED3DLIGHT * pLight) PURE;
STDMETHOD(SetLightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; STDMETHOD(SetLightEnable)(THIS_ DWORD Index,BOOL Enable) PURE;
@ -624,7 +624,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
#endif #endif
/***************************************************************************** /*****************************************************************************
* WineD3DResource interface * WineD3DResource interface
*/ */
#define INTERFACE IWineD3DResource #define INTERFACE IWineD3DResource
DECLARE_INTERFACE_(IWineD3DResource,IWineD3DBase) DECLARE_INTERFACE_(IWineD3DResource,IWineD3DBase)
@ -666,7 +666,7 @@ DECLARE_INTERFACE_(IWineD3DResource,IWineD3DBase)
#endif #endif
/***************************************************************************** /*****************************************************************************
* WineD3DVertexBuffer interface * WineD3DVertexBuffer interface
*/ */
#define INTERFACE IWineD3DVertexBuffer #define INTERFACE IWineD3DVertexBuffer
DECLARE_INTERFACE_(IWineD3DVertexBuffer,IWineD3DResource) DECLARE_INTERFACE_(IWineD3DVertexBuffer,IWineD3DResource)
@ -716,7 +716,7 @@ DECLARE_INTERFACE_(IWineD3DVertexBuffer,IWineD3DResource)
#endif #endif
/***************************************************************************** /*****************************************************************************
* WineD3DIndexBuffer interface * WineD3DIndexBuffer interface
*/ */
#define INTERFACE IWineD3DIndexBuffer #define INTERFACE IWineD3DIndexBuffer
DECLARE_INTERFACE_(IWineD3DIndexBuffer,IWineD3DResource) DECLARE_INTERFACE_(IWineD3DIndexBuffer,IWineD3DResource)
@ -1141,6 +1141,8 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
STDMETHOD_(CONST void *, GetData)(THIS) PURE; STDMETHOD_(CONST void *, GetData)(THIS) PURE;
STDMETHOD(SetFormat)(THIS_ WINED3DFORMAT format) PURE; STDMETHOD(SetFormat)(THIS_ WINED3DFORMAT format) PURE;
STDMETHOD(PrivateSetup)(THIS) PURE; STDMETHOD(PrivateSetup)(THIS) PURE;
STDMETHOD_(void,ModifyLocation)(THIS_ DWORD flag, BOOL persistent);
STDMETHOD(LoadLocation)(THIS_ DWORD flag, const RECT *rect);
}; };
#undef INTERFACE #undef INTERFACE
@ -1196,6 +1198,8 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
#define IWineD3DSurface_GetData(p) (p)->lpVtbl->GetData(p) #define IWineD3DSurface_GetData(p) (p)->lpVtbl->GetData(p)
#define IWineD3DSurface_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) #define IWineD3DSurface_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a)
#define IWineD3DSurface_PrivateSetup(p) (p)->lpVtbl->PrivateSetup(p) #define IWineD3DSurface_PrivateSetup(p) (p)->lpVtbl->PrivateSetup(p)
#define IWineD3DSurface_ModifyLocation(p,a,b) (p)->lpVtbl->ModifyLocation(p,a,b)
#define IWineD3DSurface_LoadLocation(p,a,b) (p)->lpVtbl->LoadLocation(p,a,b)
#endif #endif
/***************************************************************************** /*****************************************************************************
@ -1210,7 +1214,7 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD3DResource)
STDMETHOD_(ULONG,Release)(THIS) PURE; STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IWineD3DBase methods ***/ /*** IWineD3DBase methods ***/
STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE; STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE;
/*** IWineD3DResource methods ***/ /*** IWineD3DResource methods ***/
STDMETHOD(GetDevice)(THIS_ IWineD3DDevice ** ppDevice) PURE; STDMETHOD(GetDevice)(THIS_ IWineD3DDevice ** ppDevice) PURE;
STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE; STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE; STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
@ -1218,8 +1222,8 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD3DResource)
STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE; STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
STDMETHOD_(DWORD,GetPriority)(THIS) PURE; STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
STDMETHOD_(void,PreLoad)(THIS) PURE; STDMETHOD_(void,PreLoad)(THIS) PURE;
STDMETHOD_(WINED3DRESOURCETYPE, GetType)(THIS) PURE; STDMETHOD_(WINED3DRESOURCETYPE, GetType)(THIS) PURE;
/*** IWineD3DVolume methods ***/ /*** IWineD3DVolume methods ***/
STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE; STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE;
STDMETHOD(GetDesc)(THIS_ WINED3DVOLUME_DESC * pDesc) PURE; STDMETHOD(GetDesc)(THIS_ WINED3DVOLUME_DESC * pDesc) PURE;
STDMETHOD(LockBox)(THIS_ WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) PURE; STDMETHOD(LockBox)(THIS_ WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) PURE;
@ -1291,7 +1295,7 @@ DECLARE_INTERFACE_(IWineD3DVertexDeclaration,IWineD3DBase)
#endif #endif
/***************************************************************************** /*****************************************************************************
* IWineD3DStateBlock interface * IWineD3DStateBlock interface
*/ */
#define INTERFACE IWineD3DStateBlock #define INTERFACE IWineD3DStateBlock
DECLARE_INTERFACE_(IWineD3DStateBlock,IWineD3DBase) DECLARE_INTERFACE_(IWineD3DStateBlock,IWineD3DBase)
@ -1325,7 +1329,7 @@ DECLARE_INTERFACE_(IWineD3DStateBlock,IWineD3DBase)
#endif #endif
/***************************************************************************** /*****************************************************************************
* WineD3DQuery interface * WineD3DQuery interface
*/ */
#define INTERFACE IWineD3DQuery #define INTERFACE IWineD3DQuery
DECLARE_INTERFACE_(IWineD3DQuery,IWineD3DBase) DECLARE_INTERFACE_(IWineD3DQuery,IWineD3DBase)
@ -1342,7 +1346,7 @@ DECLARE_INTERFACE_(IWineD3DQuery,IWineD3DBase)
STDMETHOD_(DWORD,GetDataSize)(THIS) PURE; STDMETHOD_(DWORD,GetDataSize)(THIS) PURE;
STDMETHOD_(WINED3DQUERYTYPE, GetType)(THIS) PURE; STDMETHOD_(WINED3DQUERYTYPE, GetType)(THIS) PURE;
STDMETHOD(Issue)(THIS_ DWORD dwIssueFlags) PURE; STDMETHOD(Issue)(THIS_ DWORD dwIssueFlags) PURE;
}; };
#undef INTERFACE #undef INTERFACE
@ -1441,7 +1445,7 @@ DECLARE_INTERFACE_(IWineD3DBaseShader,IWineD3DBase)
#endif #endif
/***************************************************************************** /*****************************************************************************
* IWineD3DVertexShader interface * IWineD3DVertexShader interface
*/ */
#define INTERFACE IWineD3DVertexShader #define INTERFACE IWineD3DVertexShader
DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader) DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader)

View file

@ -219,7 +219,7 @@ typedef enum _WINED3DDEGREETYPE {
WINED3DDEGREE_QUADRATIC = 2, WINED3DDEGREE_QUADRATIC = 2,
WINED3DDEGREE_CUBIC = 3, WINED3DDEGREE_CUBIC = 3,
WINED3DDEGREE_QUINTIC = 5, WINED3DDEGREE_QUINTIC = 5,
WINED3DDEGREE_FORCE_DWORD = 0x7fffffff WINED3DDEGREE_FORCE_DWORD = 0x7fffffff
} WINED3DDEGREETYPE; } WINED3DDEGREETYPE;
@ -247,7 +247,7 @@ typedef enum _WINED3DFORMAT {
WINED3DFMT_G16R16 = 34, WINED3DFMT_G16R16 = 34,
WINED3DFMT_A2R10G10B10 = 35, WINED3DFMT_A2R10G10B10 = 35,
WINED3DFMT_A16B16G16R16 = 36, WINED3DFMT_A16B16G16R16 = 36,
WINED3DFMT_A8P8 = 40, WINED3DFMT_A8P8 = 40,
WINED3DFMT_P8 = 41, WINED3DFMT_P8 = 41,
@ -294,12 +294,12 @@ typedef enum _WINED3DFORMAT {
WINED3DFMT_R16F = 111, WINED3DFMT_R16F = 111,
WINED3DFMT_G16R16F = 112, WINED3DFMT_G16R16F = 112,
WINED3DFMT_A16B16G16R16F = 113, WINED3DFMT_A16B16G16R16F = 113,
/* IEEE formats */ /* IEEE formats */
WINED3DFMT_R32F = 114, WINED3DFMT_R32F = 114,
WINED3DFMT_G32R32F = 115, WINED3DFMT_G32R32F = 115,
WINED3DFMT_A32B32G32R32F = 116, WINED3DFMT_A32B32G32R32F = 116,
WINED3DFMT_CxV8U8 = 117, WINED3DFMT_CxV8U8 = 117,
@ -422,7 +422,7 @@ typedef enum _WINED3DRENDERSTATETYPE {
WINED3DRS_AMBIENTMATERIALSOURCE = 147, WINED3DRS_AMBIENTMATERIALSOURCE = 147,
WINED3DRS_EMISSIVEMATERIALSOURCE = 148, WINED3DRS_EMISSIVEMATERIALSOURCE = 148,
WINED3DRS_VERTEXBLEND = 151, WINED3DRS_VERTEXBLEND = 151,
WINED3DRS_CLIPPLANEENABLE = 152, WINED3DRS_CLIPPLANEENABLE = 152,
WINED3DRS_SOFTWAREVERTEXPROCESSING = 153, /* d3d8 */ WINED3DRS_SOFTWAREVERTEXPROCESSING = 153, /* d3d8 */
WINED3DRS_POINTSIZE = 154, WINED3DRS_POINTSIZE = 154,
WINED3DRS_POINTSIZE_MIN = 155, WINED3DRS_POINTSIZE_MIN = 155,
@ -857,7 +857,7 @@ typedef struct _WINED3DADAPTER_IDENTIFIER {
char *Driver; char *Driver;
char *Description; char *Description;
char *DeviceName; char *DeviceName;
LARGE_INTEGER *DriverVersion; LARGE_INTEGER *DriverVersion;
DWORD *VendorId; DWORD *VendorId;
DWORD *DeviceId; DWORD *DeviceId;
DWORD *SubSysId; DWORD *SubSysId;
@ -1064,13 +1064,13 @@ typedef struct _WINED3DBOX {
/*Vertex cache optimization hints.*/ /*Vertex cache optimization hints.*/
typedef struct WINED3DDEVINFO_VCACHE { typedef struct WINED3DDEVINFO_VCACHE {
/*Must be a 4 char code FOURCC (e.g. CACH)*/ /*Must be a 4 char code FOURCC (e.g. CACH)*/
DWORD Pattern; DWORD Pattern;
/*0 to get the longest strips, 1 vertex cache*/ /*0 to get the longest strips, 1 vertex cache*/
DWORD OptMethod; DWORD OptMethod;
/*Cache size to use (only valid if OptMethod==1) */ /*Cache size to use (only valid if OptMethod==1) */
DWORD CacheSize; DWORD CacheSize;
/*internal for deciding when to restart strips, non user modifyable (only valid if OptMethod==1)*/ /*internal for deciding when to restart strips, non user modifyable (only valid if OptMethod==1)*/
DWORD MagicNumber; DWORD MagicNumber;
} WINED3DDEVINFO_VCACHE; } WINED3DDEVINFO_VCACHE;
typedef struct _WINED3DVERTEXBUFFER_DESC { typedef struct _WINED3DVERTEXBUFFER_DESC {
@ -1196,7 +1196,7 @@ typedef struct _WINED3DCAPS {
DWORD *VertexTextureFilterCaps; DWORD *VertexTextureFilterCaps;
DWORD *MaxVShaderInstructionsExecuted; DWORD *MaxVShaderInstructionsExecuted;
DWORD *MaxPShaderInstructionsExecuted; DWORD *MaxPShaderInstructionsExecuted;
DWORD *MaxVertexShader30InstructionSlots; DWORD *MaxVertexShader30InstructionSlots;
DWORD *MaxPixelShader30InstructionSlots; DWORD *MaxPixelShader30InstructionSlots;
DWORD *Reserved2;/* Not in the microsoft headers but documented */ DWORD *Reserved2;/* Not in the microsoft headers but documented */
DWORD *Reserved3; DWORD *Reserved3;
@ -1267,6 +1267,13 @@ typedef struct WineDirect3DStridedData {
} WineDirect3DStridedData; } WineDirect3DStridedData;
typedef struct WineDirect3DVertexStridedData { typedef struct WineDirect3DVertexStridedData {
/* IMPORTANT:
*
* This structure can be accessed in two ways: Named access, and array
* access. Please note that named access is only valid with the fixed
* function vertex pipeline, and the arrays are only valid with the
* programmable vertex pipeline(vertex shaders)
*/
union { union {
struct { struct {
@ -1323,7 +1330,7 @@ typedef enum {
#define WINED3DUSAGE_RTPATCHES 0x00000080L #define WINED3DUSAGE_RTPATCHES 0x00000080L
#define WINED3DUSAGE_NPATCHES 0x00000100L #define WINED3DUSAGE_NPATCHES 0x00000100L
#define WINED3DUSAGE_DYNAMIC 0x00000200L #define WINED3DUSAGE_DYNAMIC 0x00000200L
#define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400L #define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400L
#define WINED3DUSAGE_DMAP 0x00004000L #define WINED3DUSAGE_DMAP 0x00004000L
#define WINED3DUSAGE_MASK 0x00004FFFL #define WINED3DUSAGE_MASK 0x00004FFFL
#define WINED3DUSAGE_OVERLAY 0x00010000L #define WINED3DUSAGE_OVERLAY 0x00010000L
@ -1378,7 +1385,7 @@ typedef enum _WINED3DSURFTYPE {
#define WINED3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000L #define WINED3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000L
#define WINED3DPRASTERCAPS_SCISSORTEST 0x01000000L #define WINED3DPRASTERCAPS_SCISSORTEST 0x01000000L
#define WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L #define WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L
#define WINED3DPRASTERCAPS_DEPTHBIAS 0x04000000L #define WINED3DPRASTERCAPS_DEPTHBIAS 0x04000000L
#define WINED3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000L #define WINED3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000L
#define WINED3DPSHADECAPS_COLORFLATMONO 0x000001 #define WINED3DPSHADECAPS_COLORFLATMONO 0x000001