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 \
state.c \
stateblock.c \
surface_base.c \
surface.c \
surface_gdi.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) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
/* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
reg_maps->bumpmat = -1;
reg_maps->luminanceparams = -1;
if (pToken == NULL)
return WINED3D_OK;
@ -266,6 +268,20 @@ HRESULT shader_get_registers_used(
if (!lconst) return E_OUTOFMEMORY;
lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
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);
pToken += curOpcode->num_params;
@ -290,9 +306,15 @@ HRESULT shader_get_registers_used(
/* If there's a loop in the shader */
} else if (WINED3DSIO_LOOP == 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;
} else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
WINED3DSIO_ENDREP == curOpcode->opcode) {
cur_loop_depth--;
/* For subroutine prototypes */
} else if (WINED3DSIO_LABEL == curOpcode->opcode) {
@ -300,14 +322,6 @@ HRESULT shader_get_registers_used(
reg_maps->labels[snum] = 1;
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 */
} else {
int i, limit;
@ -354,14 +368,30 @@ HRESULT shader_get_registers_used(
}
/* 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) {
FIXME("Pixel shader uses texbem instruction on more than 1 sampler\n");
} else {
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
* make a bitmask of the ones we're interested in.
@ -392,14 +422,43 @@ HRESULT shader_get_registers_used(
else if (WINED3DSPR_TEMP == regtype)
reg_maps->temporary[reg] = 1;
else if (WINED3DSPR_INPUT == regtype && !pshader)
reg_maps->attributes[reg] = 1;
else if (WINED3DSPR_INPUT == regtype) {
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)
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;
}
@ -699,6 +758,7 @@ void shader_generate_main(
CONST DWORD* pFunction) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
const DWORD *pToken = pFunction;
const SHADER_OPCODE *curOpcode = NULL;
SHADER_HANDLER hw_fct = NULL;
@ -788,6 +848,9 @@ void shader_generate_main(
/* Call appropriate function for output target */
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. ) */
if (This->baseShader.shader_mode == SHADER_GLSL)
shader_glsl_add_instruction_modifiers(&hw_arg);
@ -930,6 +993,10 @@ void shader_trace_init(
shader_dump_param(iface, *(pToken + 2), 0, 1);
TRACE(") ");
}
if (opcode_token & WINED3DSI_COISSUE) {
/* PixWin marks instructions with the coissue flag with a '+' */
TRACE("+");
}
TRACE("%s", curOpcode->name);

View file

@ -161,11 +161,39 @@ DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
UINT textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
TRACE("(%p) : returning invalid call\n", This);
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;
TRACE("(%p) :\n", This);
return WINED3D_OK;
@ -239,6 +267,16 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP;
IWineD3DBaseTexture_SetDirty(iface, 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 */

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);
#define PUSH1(att) attribs[nAttribs++] = (att);
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
if(create_pbuffer) {
HDC hdc_parent = GetDC(win_handle);
int iPixelFormat = 0;
short red, green, blue, alphaBits, colorBits;
short redBits, greenBits, blueBits, alphaBits, colorBits;
short depthBits, stencilBits;
IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
@ -144,23 +146,20 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
int nAttribs = 0;
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 */
getColorBits(target->resource.format, &red, &green, &blue, &alphaBits, &colorBits);
getColorBits(target->resource.format, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits);
getDepthStencilBits(StencilBufferFormat, &depthBits, &stencilBits);
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_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_DEPTH_BITS_ARB, depthBits);
PUSH2(WGL_STENCIL_BITS_ARB, stencilBits);
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 */
if(!GL_EXTCALL(wglChoosePixelFormatARB(hdc_parent, (const int*)&attribs, NULL, 1, &iPixelFormat, &nFormats)))
{
@ -205,10 +204,12 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
} else {
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
short red, green, blue, alpha;
short colorBits;
short depthBits, stencilBits;
short redBits, greenBits, blueBits, alphaBits, colorBits;
short depthBits=0, stencilBits=0;
int res;
int attribs[256];
int nAttribs = 0;
unsigned int nFormats;
hdc = GetDC(win_handle);
if(hdc == NULL) {
@ -217,36 +218,57 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
}
/* PixelFormat selection */
/* TODO: fill cColorBits/cDepthBits with target->resource.format */
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.cColorBits = 32;
pfd.cDepthBits = 0;
pfd.cStencilBits = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
PUSH2(WGL_DRAW_TO_WINDOW_ARB, GL_TRUE); /* We want to draw to a window */
PUSH2(WGL_DOUBLE_BUFFER_ARB, GL_TRUE);
PUSH2(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); /* Make sure we don't get a float or color index format */
PUSH2(WGL_SUPPORT_OPENGL_ARB, GL_TRUE);
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 */
/* Try to match the colorBits of the d3d format */
if(getColorBits(target->resource.format, &red, &green, &blue, &alpha, &colorBits))
pfd.cColorBits = colorBits;
if(!getColorBits(target->resource.format, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) {
ERR("Unable to get color bits for format %#x!\n", target->resource.format);
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.
* The choice of the proper format can give a nice performance boost
* in case of GPU limited programs. */
if(pPresentParms->EnableAutoDepthStencil) {
TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat));
if(getDepthStencilBits(pPresentParms->AutoDepthStencilFormat, &depthBits, &stencilBits)) {
pfd.cDepthBits = depthBits;
pfd.cStencilBits = stencilBits;
if(!getDepthStencilBits(pPresentParms->AutoDepthStencilFormat, &depthBits, &stencilBits)) {
ERR("Unable to get depth / stencil bits for AutoDepthStencilFormat %#x!\n", pPresentParms->AutoDepthStencilFormat);
return FALSE;
}
PUSH2(WGL_DEPTH_BITS_ARB, depthBits);
PUSH2(WGL_STENCIL_BITS_ARB, stencilBits);
}
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");
PUSH1(0); /* end the list */
/* In case of failure hope that standard ChooosePixelFormat will find something suitable */
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);
@ -265,6 +287,8 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
}
}
}
#undef PUSH1
#undef PUSH2
ctx = pwglCreateContext(hdc);
if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
@ -301,6 +325,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
goto out;
}
ENTER_GL();
TRACE("Setting up the screen\n");
/* Clear the screen */
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");
}
}
LEAVE_GL();
if(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);
checkGLcall("glColorMask");
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 */
glMatrixMode(GL_MODELVIEW);
@ -638,7 +674,7 @@ static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchai
* 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;
HRESULT hr;
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
*/
if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
if(((IWineD3DSwapChainImpl *) swapchain)->backBuffer) {
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
} else {
glDrawBuffer(GL_FRONT);
checkGLcall("glDrawBuffer(GL_FRONT)");
}
} else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
if(((IWineD3DSwapChainImpl *) swapchain)->frontBuffer == target) {
*buffer = GL_FRONT;
} else {
*buffer = GL_BACK;
}
if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
if(This->pbufferContext && tid == This->pbufferContext->tid) {
This->pbufferContext->tid = 0;
}
@ -673,16 +706,17 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
IWineD3DSwapChain_Release(swapchain);
if(oldRenderOffscreen) {
Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
Context_MarkStateDirty(context, WINED3DTS_PROJECTION);
Context_MarkStateDirty(context, STATE_VDECL);
Context_MarkStateDirty(context, STATE_VIEWPORT);
Context_MarkStateDirty(context, STATE_SCISSORRECT);
Context_MarkStateDirty(context, STATE_FRONTFACE);
}
} else {
TRACE("Rendering offscreen\n");
This->render_offscreen = TRUE;
*buffer = This->offscreenBuffer;
switch(wined3d_settings.offscreen_rendering_mode) {
case ORM_FBO:
@ -748,8 +782,6 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
*/
context = findThreadContextForSwapChain(This->swapchains[0], tid);
}
glDrawBuffer(This->offscreenBuffer);
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
break;
}
@ -761,11 +793,11 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
}
if(!oldRenderOffscreen) {
Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
Context_MarkStateDirty(context, WINED3DTS_PROJECTION);
Context_MarkStateDirty(context, STATE_VDECL);
Context_MarkStateDirty(context, STATE_VIEWPORT);
Context_MarkStateDirty(context, STATE_SCISSORRECT);
Context_MarkStateDirty(context, STATE_FRONTFACE);
}
}
if (readTexture) {
@ -783,7 +815,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
IWineD3DSurface_PreLoad(This->lastActiveRenderTarget);
/* 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;
}
@ -813,12 +845,11 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
DWORD dirtyState, idx;
BYTE shift;
WineD3DContext *context;
GLint drawBuffer=0;
TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
ENTER_GL();
if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
context = FindContext(This, target, tid);
context = FindContext(This, target, tid, &drawBuffer);
This->lastActiveRenderTarget = target;
This->lastThread = tid;
} else {
@ -830,15 +861,24 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
if(context != This->activeContext) {
BOOL ret;
TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
LEAVE_GL();
ret = pwglMakeCurrent(context->hdc, context->glCtx);
ENTER_GL();
if(ret == FALSE) {
ERR("Failed to activate the new context\n");
}
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) {
case CTXUSAGE_RESOURCELOAD:
/* 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 (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_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) {
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
int i,j;
unsigned int i,j;
TRACE("(%p) : Cleaning up\n",This);
for (i = 0; i < This->baseTexture.levels; i++) {
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 */
{"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE},
{"GL_APPLE_fence", APPLE_FENCE},
{"GL_APPLE_flush_render", APPLE_FLUSH_RENDER},
{"GL_APPLE_ycbcr_422", APPLE_YCBCR_422},
/* ATI */
{"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_program2", NV_VERTEX_PROGRAM2},
{"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);
LeaveCriticalSection(&wined3d_fake_gl_context_cs);
LEAVE_GL();
}
static BOOL WineD3D_CreateFakeGLContext(void) {
HGLRC glCtx = NULL;
ENTER_GL();
EnterCriticalSection(&wined3d_fake_gl_context_cs);
TRACE("getting context...\n");
@ -269,10 +273,17 @@ static BOOL WineD3D_CreateFakeGLContext(void) {
wined3d_fake_gl_context_hwnd = NULL;
if(glCtx) pwglDeleteContext(glCtx);
LeaveCriticalSection(&wined3d_fake_gl_context_cs);
LEAVE_GL();
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
@ -326,7 +337,13 @@ static void select_shader_mode(
if (wined3d_settings.vs_mode == VS_NONE) {
*vs_selected = SHADER_NONE;
} 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]) {
*vs_selected = SHADER_ARB;
} else {
@ -392,6 +409,38 @@ static void select_shader_max_constants(
**********************************************************/
#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) {
const char *GL_Extensions = NULL;
const char *WGL_Extensions = NULL;
@ -403,43 +452,12 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
BOOL return_value = TRUE;
int i;
HDC hdc;
HMODULE 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;
}
/* 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;
unsigned int vidmem=0;
TRACE_(d3d_caps)("(%p)\n", gl_info);
ENTER_GL();
gl_string = (const char *) glGetString(GL_RENDERER);
if (NULL == gl_string)
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);
glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
gl_info->max_pointsizemin = gl_floatv[0];
gl_info->max_pointsize = 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]) {
GLint 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 {
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;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &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 {
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_info->ps_arb_constantsF = gl_max;
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;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM temporaries: %d\n", gl_info->ps_arb_max_temps);
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
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_NATIVE_INSTRUCTIONS_ARB, &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]) {
gl_info->vs_arb_version = VS_VERSION_11;
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &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);
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;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM temporaries: %d\n", gl_info->vs_arb_max_temps);
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
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_NATIVE_INSTRUCTIONS_ARB, &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]) {
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);
gl_info->ps_glsl_constantsF = gl_max / 4;
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]) {
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
* 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
* 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) {
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.
*/
if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
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;
/* Geforce8 - highend */
if (strstr(gl_info->gl_renderer, "8800")) {
gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
}
/* 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") ||
strstr(gl_info->gl_renderer, "7600"))
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
strstr(gl_info->gl_renderer, "7600") ||
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") ||
strstr(gl_info->gl_renderer, "6610") ||
strstr(gl_info->gl_renderer, "6700"))
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
else
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400 */
{
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
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)) {
/* GeforceFX - highend */
if (strstr(gl_info->gl_renderer, "5800") ||
strstr(gl_info->gl_renderer, "5900") ||
strstr(gl_info->gl_renderer, "5950") ||
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") ||
strstr(gl_info->gl_renderer, "5650") ||
strstr(gl_info->gl_renderer, "5700") ||
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 */
vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
}
} 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 */
else
vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
}
else {
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)) {
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 */
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 */
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 */
else
vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
}
else {
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 {
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 */
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 */
vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
}
}
break;
case VENDOR_ATI:
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 */
if (strstr(gl_info->gl_renderer, "X1600") ||
strstr(gl_info->gl_renderer, "X1800") ||
strstr(gl_info->gl_renderer, "X1900") ||
strstr(gl_info->gl_renderer, "X1950"))
gl_info->gl_card = CARD_ATI_RADEON_X1600;
/* Radeon R4xx + X1300/X1400 (lowend R5xx) */
else if (strstr(gl_info->gl_renderer, "X1600") ||
strstr(gl_info->gl_renderer, "X1650") ||
strstr(gl_info->gl_renderer, "X1800") ||
strstr(gl_info->gl_renderer, "X1900") ||
strstr(gl_info->gl_renderer, "X1950"))
{
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") ||
strstr(gl_info->gl_renderer, "X800") ||
strstr(gl_info->gl_renderer, "X850") ||
strstr(gl_info->gl_renderer, "X1300") ||
strstr(gl_info->gl_renderer, "X1400"))
gl_info->gl_card = CARD_ATI_RADEON_X700;
strstr(gl_info->gl_renderer, "X1400") ||
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 */
else
else {
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)) {
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)) {
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
gl_info->gl_card = CARD_ATI_RAGE_128PRO;
vidmem = 16; /* There are 16-32MB models */
break;
case VENDOR_INTEL:
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))
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
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))
gl_info->gl_card = CARD_NVIDIA_GEFORCE;
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);
/* 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
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;
@ -1042,9 +1198,8 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
}
}
}
LEAVE_GL();
WineD3D_ReleaseFakeGLContext();
return return_value;
}
#undef GLINFO_LOCATION
@ -1496,6 +1651,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
if (Usage & WINED3DUSAGE_QUERY_FILTER) {
switch (CheckFormat) {
/* Filtering not supported */
case WINED3DFMT_R32F:
case WINED3DFMT_A32B32G32R32F:
TRACE_(d3d_caps)("[FAILED]\n");
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
* 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 */
@ -1715,7 +1932,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
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
* 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_X8L8V8U8:
case WINED3DFMT_Q8W8V8U8:
case WINED3DFMT_W11V11U10:
case WINED3DFMT_A2W10V10U10:
WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
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
* WINED3DFMT_DXT1
@ -1836,8 +2062,12 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
WINED3DCAPS2_FULLSCREENGAMMA |
WINED3DCAPS2_DYNAMICTEXTURES;
if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
*pCaps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
}
*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 |
WINED3DCURSORCAPS_LOWRES;
@ -1889,7 +2119,6 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPRASTERCAPS_ZFOG |
WINED3DPRASTERCAPS_FOGVERTEX |
WINED3DPRASTERCAPS_FOGTABLE |
WINED3DPRASTERCAPS_FOGRANGE |
WINED3DPRASTERCAPS_STIPPLE |
WINED3DPRASTERCAPS_SUBPIXEL |
WINED3DPRASTERCAPS_ZTEST |
@ -1901,6 +2130,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
WINED3DPRASTERCAPS_ZBIAS |
WINED3DPRASTERCAPS_MIPMAPLODBIAS;
}
if(GL_SUPPORT(NV_FOG_DISTANCE)) {
*pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
}
/* FIXME Add:
WINED3DPRASTERCAPS_COLORPERSPECTIVE
@ -1934,8 +2166,6 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPBLENDCAPS_ZERO;
*pCaps->DestBlendCaps = WINED3DPBLENDCAPS_BLENDFACTOR |
WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
WINED3DPBLENDCAPS_BOTHSRCALPHA |
WINED3DPBLENDCAPS_DESTALPHA |
WINED3DPBLENDCAPS_DESTCOLOR |
WINED3DPBLENDCAPS_INVDESTALPHA |
@ -1948,6 +2178,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPBLENDCAPS_ZERO;
/* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
* according to the glBlendFunc manpage
*
* WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
* legacy settings for srcblend only
*/
*pCaps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
@ -1973,8 +2206,12 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
WINED3DPTEXTURECAPS_BORDER |
WINED3DPTEXTURECAPS_MIPMAP |
WINED3DPTEXTURECAPS_PROJECTED |
WINED3DPTEXTURECAPS_PERSPECTIVE |
WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
WINED3DPTEXTURECAPS_PERSPECTIVE;
if( !GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
*pCaps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
}
if( GL_SUPPORT(EXT_TEXTURE3D)) {
*pCaps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
@ -2199,14 +2436,17 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
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
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
now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */
if(GLINFO_LOCATION.vs_nv_version == VS_VERSION_20)
* 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 way using glsl (it abstracts the lowlevel info away) and also not
* 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);
else
*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) {
*pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
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);
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
in case of GeforceFX cards. */
if(GLINFO_LOCATION.ps_nv_version == PS_VERSION_20)
/* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
* In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
* 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);
else
*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 */
*pCaps->PixelShader1xMaxValue = 1.0;
TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
/* FIXME: The following line is card dependent. -8.0 to 8.0 is the
* Direct3D minimum requirement.
*
* 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) {
*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");
} else {
*pCaps->PixelShaderVersion = 0;
@ -2408,6 +2668,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
} else {
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 */
object->state = WINED3DERR_DRIVERINTERNALERROR;
@ -2479,9 +2740,70 @@ ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
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 GLINFO_LOCATION (Adapters[0].gl_info)
BOOL InitAdapters(void) {
static HMODULE mod_gl;
BOOL ret;
int ps_selected_mode, vs_selected_mode;
@ -2491,77 +2813,132 @@ BOOL InitAdapters(void) {
if(numAdapters > 0) return TRUE;
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 */
{
int iPixelFormat;
int attribs[8];
int values[8];
int nAttribs = 0;
int res;
WineD3D_PixelFormat *cfgs;
int attribute;
DISPLAY_DEVICEW DisplayDevice;
HDC hdc;
TRACE("Initializing default adapter\n");
Adapters[0].monitorPoint.x = -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);
if(!ret) {
ERR("Failed to initialize gl caps for default adapter\n");
HeapFree(GetProcessHeap(), 0, Adapters);
WineD3D_ReleaseFakeGLContext();
return FALSE;
}
ret = initPixelFormats(&Adapters[0].gl_info);
if(!ret) {
ERR("Failed to init gl formats\n");
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;
}
Adapters[0].driver = "Display";
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 */
DisplayDevice.cb = sizeof(DisplayDevice);
EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
if (WineD3D_CreateFakeGLContext()) {
int iPixelFormat;
int attribs[8];
int values[8];
int nAttribs = 0;
int res;
WineD3D_PixelFormat *cfgs;
attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
GL_EXTCALL(wglGetPixelFormatAttribivARB(wined3d_fake_gl_context_hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
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));
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)
for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
res = GL_EXTCALL(wglGetPixelFormatAttribivARB(wined3d_fake_gl_context_hdc, iPixelFormat, 0, nAttribs, attribs, values));
if(!res)
continue;
if(!res)
continue;
/* Cache the pixel format */
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 */
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];
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();
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();
fixup_extensions(&Adapters[0].gl_info);
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);

View file

@ -178,6 +178,7 @@ void primitiveDeclarationConvertToStridedData(
if (This->stateBlock->streamSource[element->Stream] == NULL)
continue;
stride = This->stateBlock->streamStride[element->Stream];
if (This->stateBlock->streamIsUP) {
TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
streamVBO = 0;
@ -185,6 +186,22 @@ void primitiveDeclarationConvertToStridedData(
} else {
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);
/* 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( streamVBO != 0) *fixup = TRUE;
else if(*fixup && !useVertexShaderFunction &&
@ -195,7 +212,6 @@ void primitiveDeclarationConvertToStridedData(
}
}
}
stride = This->stateBlock->streamStride[element->Stream];
data += element->Offset;
reg = element->Reg;
@ -230,7 +246,10 @@ void primitiveDeclarationConvertToStridedData(
* once in there.
*/
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 */
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
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 *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 */
if (sd->u.s.normal.lpData == NULL) {
glNormal3f(0, 0, 1);
glNormal3f(0, 0, 0);
}
if(sd->u.s.diffuse.lpData == NULL) {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
@ -381,9 +401,10 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
}
/* 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 texture_idx = This->texUnitMap[textureNo];
float *ptrToCoords = NULL;
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));
if (texCoords[coordIdx] == NULL) {
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;
} else {
int texture_idx = This->texUnitMap[textureNo];
int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == WINED3DDECLTYPE_FLOAT1 etc */
if (texture_idx == -1) continue;
@ -413,36 +438,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
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 */
case WINED3DTTFF_COUNT1:
VTRACE(("tex:%d, s=%f\n", textureNo, s));
@ -761,7 +756,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVerte
break;
case WINED3DDECLTYPE_UBYTE4:
GL_EXTCALL(glVertexAttrib4NubvARB(instancedData[j], ptr));
GL_EXTCALL(glVertexAttrib4ubvARB(instancedData[j], ptr));
break;
case WINED3DDECLTYPE_UBYTE4N:
case WINED3DDECLTYPE_D3DCOLOR:
@ -834,125 +829,92 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVerte
}
}
struct coords {
int x, y, z;
};
static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStridedData *s) {
unsigned char i;
IWineD3DVertexBufferImpl *vb;
void blt_to_drawable(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *surface) {
struct coords coords[4];
int low_coord;
/* TODO: This could be supported for lazy unlocking */
if(!(surface->Flags & SFLAG_INTEXTURE)) {
/* It is ok at init to be nowhere */
if(!(surface->Flags & SFLAG_INSYSMEM)) {
ERR("Blitting surfaces from sysmem not supported yet\n");
if(s->u.s.position.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position.streamNo];
s->u.s.position.VBO = 0;
s->u.s.position.lpData = (BYTE *) ((unsigned long) s->u.s.position.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.blendWeights.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendWeights.streamNo];
s->u.s.blendWeights.VBO = 0;
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;
}
ActivateContext(This, This->render_targets[0], CTXUSAGE_BLIT);
ENTER_GL();
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.position2.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position2.streamNo];
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(This->render_offscreen) {
coords[0].y = coords[0].y == 1 ? low_coord : 1;
coords[1].y = coords[1].y == 1 ? low_coord : 1;
coords[2].y = coords[2].y == 1 ? low_coord : 1;
coords[3].y = coords[3].y == 1 ? low_coord : 1;
if(s->u.s.normal2.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal2.streamNo];
s->u.s.normal2.VBO = 0;
s->u.s.normal2.lpData = (BYTE *) ((unsigned long) s->u.s.normal2.lpData + (unsigned long) vb->resource.allocatedMemory);
}
glBegin(GL_QUADS);
glTexCoord3iv((GLint *) &coords[0]);
glVertex2i(0, 0);
glTexCoord3iv((GLint *) &coords[1]);
glVertex2i(0, surface->pow2Height);
glTexCoord3iv((GLint *) &coords[2]);
glVertex2i(surface->pow2Width, surface->pow2Height);
glTexCoord3iv((GLint *) &coords[3]);
glVertex2i(surface->pow2Width, 0);
glEnd();
checkGLcall("glEnd");
if(surface->glDescription.target != GL_TEXTURE_2D) {
glEnable(GL_TEXTURE_2D);
checkGLcall("glEnable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
if(s->u.s.tangent.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tangent.streamNo];
s->u.s.tangent.VBO = 0;
s->u.s.tangent.lpData = (BYTE *) ((unsigned long) s->u.s.tangent.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.binormal.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.binormal.streamNo];
s->u.s.binormal.VBO = 0;
s->u.s.binormal.lpData = (BYTE *) ((unsigned long) s->u.s.binormal.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.tessFactor.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tessFactor.streamNo];
s->u.s.tessFactor.VBO = 0;
s->u.s.tessFactor.lpData = (BYTE *) ((unsigned long) s->u.s.tessFactor.lpData + (unsigned long) vb->resource.allocatedMemory);
}
if(s->u.s.fog.VBO) {
vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.fog.streamNo];
s->u.s.fog.VBO = 0;
s->u.s.fog.lpData = (BYTE *) ((unsigned long) s->u.s.fog.lpData + (unsigned long) vb->resource.allocatedMemory);
}
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 */
@ -991,33 +953,29 @@ void drawPrimitive(IWineD3DDevice *iface,
IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DSwapChain, (void **)&swapchain);
/* Need the surface in the drawable! */
if(!(target->Flags & SFLAG_INDRAWABLE) && (swapchain || wined3d_settings.offscreen_rendering_mode != ORM_FBO)) {
blt_to_drawable(This, target);
}
IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
/* TODO: Move fbo logic to ModifyLocation */
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE);
if(swapchain) {
/* Onscreen target. Invalidate system memory copy and texture copy */
target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE);
target->Flags |= SFLAG_INDRAWABLE;
IWineD3DSwapChain_Release(swapchain);
} else if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
/* 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);
if(texture) {
IWineD3DBaseTexture_SetDirty(texture, TRUE);
IWineD3DTexture_Release(texture);
}
target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE);
target->Flags |= SFLAG_INDRAWABLE;
} else {
/* FBO offscreen target. Invalidate system memory copy */
target->Flags &= ~SFLAG_INSYSMEM;
/* FBO offscreen target. Texture == Drawable */
target->Flags |= SFLAG_INTEXTURE;
}
} else {
/* Must be an fbo render target */
target->Flags &= ~SFLAG_INSYSMEM;
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE);
target->Flags |= SFLAG_INTEXTURE;
}
}
@ -1050,40 +1008,24 @@ void drawPrimitive(IWineD3DDevice *iface,
if (numberOfVertices == 0 )
numberOfVertices = calculatedNumberOfindices;
if(!This->strided_streams.u.s.position_transformed && !use_vs(This)) {
if(This->activeContext->num_untracked_materials &&
This->stateBlock->renderState[WINED3DRS_LIGHTING]) {
IWineD3DVertexBufferImpl *vb;
if(!use_vs(This)) {
if(!This->strided_streams.u.s.position_transformed && This->activeContext->num_untracked_materials &&
This->stateBlock->renderState[WINED3DRS_LIGHTING]) {
FIXME("Using software emulation because not all material properties could be tracked\n");
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;
memcpy(&stridedlcl, &This->strided_streams, sizeof(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
remove_vbos(This, &stridedlcl);
}
}

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);
}
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) {
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
ULONG ref;
TRACE("(%p) : Releasing from %d\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
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) {
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");
destroy_glsl_pshader(This);
}
shader_delete_constant_list(&This->baseShader.constantsF);
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_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_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_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},
@ -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_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_POW, "pow", "POW", 1, 3, NULL, shader_glsl_pow, 0, 0},
{WINED3DSIO_CRS, "crs", "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0},
/* TODO: xyz normalise can be performed as VS_ARB using one temporary register,
DP3 tmp , vec, vec;
RSQ tmp, tmp.x;
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, 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},
{WINED3DSIO_POW, "pow", "POW", 1, 3, pshader_hw_map2gl, shader_glsl_pow, 0, 0},
{WINED3DSIO_CRS, "crs", "XPD", 1, 3, pshader_hw_map2gl, shader_glsl_cross, 0, 0},
{WINED3DSIO_NRM, "nrm", NULL, 1, 2, shader_hw_nrm, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, shader_hw_sincos, shader_glsl_sincos, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
{WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, shader_hw_sincos, shader_glsl_sincos, WINED3DPS_VERSION(3,0), -1},
{WINED3DSIO_DP2ADD, "dp2add", NULL, 1, 4, pshader_hw_dp2add, pshader_glsl_dp2add, WINED3DPS_VERSION(2,0), -1},
/* Matrix */
{WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x2, "m3x2", "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, shader_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, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
/* Register declarations */
{WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0},
/* Flow control - requires GLSL or software shaders */
@ -230,15 +212,15 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
/* Texture */
{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_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, "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_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_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_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)},
@ -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_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_TEXDP3TEX, "texdp3tex", GLNAME_REQUIRE_GLSL, 1, 2, NULL, 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_TEXDP3, "texdp3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, 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_TEXDEPTH, "texdepth", GLNAME_REQUIRE_GLSL, 1, 1, NULL, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{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, pshader_hw_texm3x2depth, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), 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", NULL, 1, 2, pshader_hw_texm3x3, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{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_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},
@ -379,8 +361,18 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
/* Pack 3.0 inputs */
if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0))
pshader_glsl_input_pack(&buffer, This->semantics_in);
if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
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 */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
@ -407,6 +399,23 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
else
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");
@ -448,12 +457,41 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
* -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");
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
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");
if(This->srgb_enabled) {
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 {
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");
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
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");
@ -504,6 +542,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) > 1) {
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
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.. */
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);
if (FAILED(hr)) return hr;
/* 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;
@ -535,11 +609,76 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
CONST DWORD *function = This->baseShader.function;
UINT i, sampler;
IWineD3DBaseTextureImpl *texture;
TRACE("(%p) : function %p\n", iface, function);
/* We're already compiled. */
if (This->baseShader.is_compiled) return WINED3D_OK;
/* We're already compiled, but check if any of the hardcoded stateblock assumptions
* 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 */
if (!function) {
@ -559,6 +698,9 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader
/* 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 */
TRACE("(%p) : Generating hardware program\n", This);
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:
{
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));
checkGLcall("glTestFenceAPPLE");
} else if(GL_SUPPORT(NV_FENCE)) {
@ -182,7 +187,9 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
case WINED3DQUERYTYPE_OCCLUSION:
{
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 samples;
GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
@ -201,7 +208,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
res = S_FALSE;
}
} 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;
res = S_OK;
}
@ -375,13 +382,19 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
switch (This->type) {
case WINED3DQUERYTYPE_OCCLUSION:
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
if (dwIssueFlags & WINED3DISSUE_BEGIN) {
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()");
WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
WARN("Not the owning context, can't start query\n");
} else {
if (dwIssueFlags & WINED3DISSUE_BEGIN) {
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 {
FIXME("(%p) : Occlusion queries not supported\n", This);
@ -390,7 +403,17 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs
case WINED3DQUERYTYPE_EVENT: {
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));
checkGLcall("glSetFenceAPPLE");
} else if (GL_SUPPORT(NV_FENCE)) {

View file

@ -71,7 +71,7 @@ void IWineD3DResourceImpl_CleanUp(IWineD3DResource *iface){
TRACE("(%p) Cleaning up resource\n", This);
if (This->resource.pool == WINED3DPOOL_DEFAULT) {
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) {
@ -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.heapMemory = 0;
if (This->resource.wineD3DDevice != NULL) {
IWineD3DDevice_ResourceReleased((IWineD3DDevice *)This->resource.wineD3DDevice, iface);
@ -137,6 +138,7 @@ HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData(IWineD3DResource *iface, REFG
if (Flags & WINED3DSPD_IUNKNOWN) {
if(SizeOfData != sizeof(IUnknown *)) {
WARN("IUnknown data with size %d, returning WINED3DERR_INVALIDCALL\n", SizeOfData);
HeapFree(GetProcessHeap(), 0, data);
return WINED3DERR_INVALIDCALL;
}
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) {
/* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */
/* If we are culling "back faces with clockwise vertices" then
set front faces to be counter clockwise and enable culling
of back faces */
/* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering
* switch
*/
switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
case WINED3DCULL_NONE:
glDisable(GL_CULL_FACE);
@ -145,26 +143,14 @@ static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
case WINED3DCULL_CW:
glEnable(GL_CULL_FACE);
checkGLcall("glEnable GL_CULL_FACE");
if (stateblock->wineD3DDevice->render_offscreen) {
glFrontFace(GL_CW);
checkGLcall("glFrontFace GL_CW");
} else {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace GL_CCW");
}
glCullFace(GL_BACK);
glCullFace(GL_FRONT);
checkGLcall("glCullFace(GL_FRONT)");
break;
case WINED3DCULL_CCW:
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);
checkGLcall("glCullFace(GL_BACK)");
break;
default:
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]);
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);
checkGLcall("glDepthFunc");
}
@ -247,33 +247,6 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
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]) {
case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; 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");
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;
srcBlend = GL_SRC_ALPHA;
FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
break;
case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
srcBlend = GL_ONE_MINUS_SRC_ALPHA;
FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
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]);
}
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] ||
stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
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]);
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");
}
@ -423,9 +429,17 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
if (stateblock->renderState[WINED3DRS_CLIPPING]) {
enable = 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 {
disable = 0xffffffff;
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)"); }
@ -471,7 +485,7 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
}
TRACE("glBlendEquation(%x)\n", glParm);
GL_EXTCALL(glBlendEquation(glParm));
GL_EXTCALL(glBlendEquationEXT(glParm));
checkGLcall("glBlendEquation");
}
@ -661,7 +675,7 @@ state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *c
if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
func = GL_ALWAYS;
if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
func = GL_ALWAYS;
func_ccw = GL_ALWAYS;
ref = stateblock->renderState[WINED3DRS_STENCILREF];
mask = stateblock->renderState[WINED3DRS_STENCILMASK];
stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
@ -678,29 +692,55 @@ state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *c
func, stencilFail, depthFail, stencilPass,
func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
if (twosided_enable) {
renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
if (twosided_enable && onesided_enable) {
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);
} else {
if (onesided_enable) {
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");
renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
} else if(onesided_enable) {
if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
}
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) {
DWORD mask;
if(stateblock->wineD3DDevice->stencilBufferTarget) {
glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
mask = stateblock->renderState[WINED3DRS_STENCILWRITEMASK];
} 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");
}
@ -796,6 +836,12 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
fogstart = 1.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;
}
else if( use_ps(stateblock->wineD3DDevice) ) {
@ -831,6 +877,12 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
break;
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,
* 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) {
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);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
break;
}
@ -857,9 +910,10 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
if(!context->last_was_rhw) {
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);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
break;
}
@ -868,9 +922,10 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
if(!context->last_was_rhw) {
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);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
break;
}
@ -881,8 +936,11 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
* Same happens with Vertexfog on transformed vertices
*/
if(GL_SUPPORT(EXT_FOG_COORD)) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
if(context->fog_coord == FALSE) {
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);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
fogstart = 0xff;
@ -904,27 +962,30 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
case WINED3DFOG_EXP:
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);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
break;
case WINED3DFOG_EXP2:
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);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
break;
case WINED3DFOG_LINEAR:
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);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
context->fog_coord = FALSE;
}
break;
@ -938,13 +999,26 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
glEnable(GL_FOG);
checkGLcall("glEnable GL_FOG");
glFogfv(GL_FOG_START, &fogstart);
checkGLcall("glFogf(GL_FOG_START, fogstart");
TRACE("Fog Start == %f\n", fogstart);
if(fogstart != fogend)
{
glFogfv(GL_FOG_START, &fogstart);
checkGLcall("glFogf(GL_FOG_START, fogstart");
TRACE("Fog Start == %f\n", fogstart);
glFogfv(GL_FOG_END, &fogend);
checkGLcall("glFogf(GL_FOG_END, fogend");
TRACE("Fog End == %f\n", fogend);
glFogfv(GL_FOG_END, &fogend);
checkGLcall("glFogf(GL_FOG_END, 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 {
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");
}
}
}
if (GL_SUPPORT(NV_FOG_DISTANCE)) {
glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
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) {
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);
checkGLcall("glEnable(GL_NORMALIZE);");
} 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) {
union {
DWORD d;
@ -1216,31 +1298,49 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
/* Default values */
GLfloat att[3] = {1.0f, 0.0f, 0.0f};
union {
DWORD d;
float f;
} pointSize, A, B, C;
/*
* Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
* This means that OpenGL will clamp really small point sizes to 1.0f.
* 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.
*/
GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
if(pointSize > 0.0f) {
pointSize.d = stateblock->renderState[WINED3DRS_POINTSIZE];
A.d = stateblock->renderState[WINED3DRS_POINTSCALE_A];
B.d = stateblock->renderState[WINED3DRS_POINTSCALE_B];
C.d = stateblock->renderState[WINED3DRS_POINTSCALE_C];
if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
GLfloat scaleFactor;
float h = stateblock->viewport.Height;
if(pointSize < 1.0f) {
scaleFactor = pointSize * pointSize;
if(pointSize.f < GL_LIMITS(pointsizemin)) {
/*
* 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 {
scaleFactor = 1.0f;
}
scaleFactor = pow(h * scaleFactor, 2);
if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
(stateblock->viewport.Height * stateblock->viewport.Height * 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);
}
att[0] = A.f / scaleFactor;
att[1] = B.f / scaleFactor;
att[2] = C.f / scaleFactor;
}
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)) {
GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
} else {
TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
} else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
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) {
@ -1468,12 +1571,6 @@ static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock,
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) {
TRACE("Stub\n");
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 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 (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],
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) {
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
union {
@ -2074,6 +2196,17 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, W
float f;
} 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];
if(tmpvalue.f != 0.0) {
FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
@ -2087,6 +2220,17 @@ static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock,
float f;
} 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];
if(tmpvalue.f != 0.0) {
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) {
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
BOOL use_pshader = use_ps(device);
@ -2435,8 +2565,12 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, W
stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
}
} else {
/* TODO: Implement vertex blending in drawStridedSlow */
FIXME("Vertex blending enabled, but not supported by hardware\n");
static BOOL once = FALSE;
if(!once) {
once = TRUE;
/* TODO: Implement vertex blending in drawStridedSlow */
FIXME("Vertex blending enabled, but not supported by hardware\n");
}
}
break;
@ -2543,7 +2677,23 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
/* 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
* 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);
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);
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 {
glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
}
}
checkGLcall("glOrtho");
/* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
glTranslatef(0.375, 0.375, 0);
checkGLcall("glTranslatef(0.375, 0.375, 0)");
/* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
glTranslatef(0.5, 0.5, 0);
checkGLcall("glTranslatef(0.5, 0.5, 0)");
/* D3D texture coordinates are flipped compared to OpenGL ones, so
* render everything upside down when rendering 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
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)
instead. */
glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
instead.
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
* render everything upside down when rendering offscreen. */
@ -2963,8 +3125,8 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
} else {
glNormal3f(0, 0, 1);
checkGLcall("glNormal3f(0, 0, 1)");
glNormal3f(0, 0, 0);
checkGLcall("glNormal3f(0, 0, 0)");
}
/* 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))) {
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
}
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
}
} else {
/* We compile the shader here because we need the vertex declaration
* 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) {
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) {
@ -3298,12 +3471,14 @@ static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
checkGLcall("glViewport");
stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
stateblock->wineD3DDevice->posFixup[3] = -1.0 / stateblock->viewport.Height;
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
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) {
@ -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[] =
{
/* State name representative, apply function */
@ -3505,7 +3690,7 @@ const struct StateEntry StateTable[] =
{ /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
{ /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
{ /* 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 },
{ /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
{ /* 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 },
{ /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
{ /*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 },
{ /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
{ /*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 },
{ /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
{ /*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 },
{ /*196, 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_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;
light2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*light));
memcpy(light2, light, sizeof(*light));
list_add_tail(&This->lightMap[l], &light2->entry);
if(light2->glIndex != -1) This->activeLights[light2->glIndex] = light2;
list_add_tail(&Dest->lightMap[l], &light2->entry);
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++) {
struct list *e1, *e2;
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) {
/* 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);
if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
This->vertexShader = targetStateBlock->vertexShader;
}
@ -424,13 +435,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
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 */
for (j = 0; j < This->num_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)
|| (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
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->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],
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];
}
@ -583,20 +591,22 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->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);
} else if(This->blockType == WINED3DSBT_ALL) {
This->vertexDecl = targetStateBlock->vertexDecl;
This->vertexShader = targetStateBlock->vertexShader;
memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride));
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->streamFlags, targetStateBlock->streamFlags, sizeof(This->streamFlags));
This->pIndexData = targetStateBlock->pIndexData;
This->baseVertexIndex = targetStateBlock->baseVertexIndex;
memcpy(This->transforms, targetStateBlock->transforms, sizeof(This->transforms));
record_lights(This, targetStateBlock);
@ -604,7 +614,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->clip_status = targetStateBlock->clip_status;
This->viewport = targetStateBlock->viewport;
This->material = targetStateBlock->material;
This->pixelShader = targetStateBlock->pixelShader;
memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
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->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
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) {
This->vertexShader = targetStateBlock->vertexShader;
memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
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]];
}
}
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) {
This->pixelShader = targetStateBlock->pixelShader;
memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
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]];
}
}
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);

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);
}
}
HeapFree(GetProcessHeap(), 0, This->backBuffer);
}
/* 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);
ENTER_GL();
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
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);
}
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);
/* 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)
FIXME("Singe Frame snapshots Starting\n");
isDumpingFrames = TRUE;
ENTER_GL();
glClear(GL_COLOR_BUFFER_BIT);
LEAVE_GL();
#endif
#if defined(SINGLE_FRAME_DEBUGGING)
@ -268,8 +274,6 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
}
#endif
LEAVE_GL();
if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
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;
front->resource.allocatedMemory = back->resource.allocatedMemory;
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 */
@ -333,8 +360,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
if(backuptodate) front->Flags |= SFLAG_INSYSMEM;
else front->Flags &= ~SFLAG_INSYSMEM;
} else {
back->Flags &= ~SFLAG_INSYSMEM;
front->Flags &= ~SFLAG_INSYSMEM;
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE);
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);
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_LoadTexture(This->surfaces[i], srgb_mode);
}

View file

@ -27,8 +27,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION This->adapter->gl_info
/*****************************************************************************
* 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_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_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_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_A8 ,GL_ALPHA8 ,GL_ALPHA8 ,GL_ALPHA ,GL_UNSIGNED_BYTE },
{WINED3DFMT_A8R3G3B2 ,0 ,0 ,0 ,0 },
{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_X8B8G8R8 ,GL_RGB8 ,GL_RGB8 ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV },
{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 },
/* Bump mapping stuff */
{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_X8L8V8U8 ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT8_MAG8_INTENSITY8_NV ,GL_DSDT_MAG_INTENSITY_NV ,GL_BYTE },
{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_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_V16U16 ,GL_SIGNED_HILO16_NV ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT },
{WINED3DFMT_W11V11U10 ,0 ,0 ,0 ,0 },
@ -210,9 +208,11 @@ static inline int getFmtIdx(WINED3DFORMAT fmt) {
return -1;
}
#define GLINFO_LOCATION (*gl_info)
BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
{
unsigned int src;
int dst;
gl_info->gl_formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
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
*/
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].glGammaInternal = gl_formats_template[src].glGammaInternal;
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].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;
}
#undef GLINFO_LOCATION
#define GLINFO_LOCATION This->adapter->gl_info
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
/* 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];
glMatrixMode(GL_TEXTURE);
checkGLcall("glMatrixMode(GL_TEXTURE)");
if (flags == WINED3DTTFF_DISABLE) {
if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
glLoadIdentity();
checkGLcall("glLoadIdentity()");
return;
@ -2438,12 +2489,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
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) {
switch (flags & ~WINED3DTTFF_PROJECTED) {
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;
break;
}
} else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
mat[12] = mat[8];
mat[13] = mat[9];
} else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
if(!calculatedCoords) {
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);
@ -2493,6 +2587,8 @@ BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *bl
case WINED3DFMT_X1R5G5B5:
case WINED3DFMT_A1R5G5B5:
case WINED3DFMT_R5G6B5:
case WINED3DFMT_X4R4G4B4:
case WINED3DFMT_A4R4G4B4:
case WINED3DFMT_R3G3B2:
case WINED3DFMT_A8P8:
case WINED3DFMT_P8:

View file

@ -136,7 +136,7 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte
This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count);
if (!This->pDeclarationWine) {
ERR("Memory allocation failed\n");
hr = WINED3DERR_OUTOFVIDEOMEMORY;
return WINED3DERR_OUTOFVIDEOMEMORY;
} else {
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_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_POW, "pow", "POW", 1, 3, NULL, shader_glsl_pow, 0, 0},
{WINED3DSIO_CRS, "crs", "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0},
{WINED3DSIO_POW, "pow", "POW", 1, 3, vshader_hw_map2gl, shader_glsl_pow, 0, 0},
{WINED3DSIO_CRS, "crs", "XPD", 1, 3, vshader_hw_map2gl, shader_glsl_cross, 0, 0},
/* TODO: sng can possibly be performed a s
RCP tmp, vec
MUL out, tmp, vec*/
{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,
DP3 tmp , vec, vec;
RSQ tmp, tmp.x;
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},
{WINED3DSIO_NRM, "nrm", NULL, 1, 2, shader_hw_nrm, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, shader_hw_sincos, shader_glsl_sincos, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
{WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, shader_hw_sincos, shader_glsl_sincos, WINED3DVS_VERSION(3,0), -1},
/* Matrix */
{WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x2, "m3x2", "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, shader_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, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
{WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0},
/* Declare registers */
{WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0},
/* Constant definitions */
@ -333,26 +324,34 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
/* Unpack 3.0 outputs */
if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0))
vshader_glsl_output_unpack(&buffer, This->semantics_out);
if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0)) {
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 (!reg_maps->fog)
shader_addline(&buffer, "gl_FogFragCoord = gl_Position.z;\n");
/* Write the final position.
*
* 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
* matrix to avoid wasting a free shader constant. Add them to the w and z coord
* of the 2nd row
* the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
* 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
* contains 1.0 to allow a mad.
*/
shader_addline(&buffer, "gl_Position.x = gl_Position.x + posFixup[2];\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
* (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
shader_addline(&buffer, "gl_Position.xy = gl_Position.xy * posFixup.xy + posFixup.zw;\n");
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
*
* 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");
@ -368,12 +367,18 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* Create the hw ARB shader */
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 */
if (GL_VEND(MESA) || GL_VEND(WINE))
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 */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
@ -390,15 +395,17 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* Write the final position.
*
* 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 x offset in z and the y offset in w. Add them to the resulting position
* the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
* 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.y, TMP_OUT.y, posFixup.w;\n");
/* 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)
shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;");
shader_addline(&buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, posFixup.w;");
/* 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");
@ -460,11 +467,6 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
TRACE("(%p) : Releasing from %d\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
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) {
struct list *linked_programs = &This->baseShader.linked_programs;
@ -560,6 +562,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
list_init(&This->baseShader.constantsI);
/* 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));
hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
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;
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 */
if (NULL != pFunction) {
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);
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",
GL_TEXTURE_3D,
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_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,
glDesc->glInternal,
This->currentDesc.Width,
@ -281,20 +290,8 @@ static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int
0,
glDesc->glFormat,
glDesc->glType,
This->resource.allocatedMemory);
GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D,
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");
This->resource.allocatedMemory));
checkGLcall("glTexImage3D");
/* 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).

View file

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!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" />
<include base="wined3d">.</include>
<include base="ReactOS">include/reactos/wine</include>
@ -36,6 +36,7 @@
<file>resource.c</file>
<file>state.c</file>
<file>stateblock.c</file>
<file>surface_base.c</file>
<file>surface.c</file>
<file>surface_gdi.c </file>
<file>swapchain.c</file>

View file

@ -39,25 +39,13 @@ wined3d_settings_t wined3d_settings =
VS_HW, /* Hardware by default */
PS_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 */
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) {
IWineD3DImpl* object;
@ -75,13 +63,6 @@ IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *p
object->ref = 1;
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);
return (IWineD3D *)object;
@ -112,8 +93,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
DWORD len;
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 might need CS_OWNDC in the future if we notice strange things on Windows.
* 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 (!strcmp(buffer,"enabled"))
{
TRACE("Use of GL Shading Language enabled for systems that support it\n");
wined3d_settings.glslRequested = TRUE;
}
else
if (!strcmp(buffer,"disabled"))
{
TRACE("Use of GL Shading Language disabled\n");
wined3d_settings.glslRequested = FALSE;
}
}
if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) )
@ -274,6 +249,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
else
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)
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_T 18
#define NUM_SAVEDPIXELSTATES_S 12
#define NUM_SAVEDVERTEXSTATES_R 31
#define NUM_SAVEDVERTEXSTATES_R 34
#define NUM_SAVEDVERTEXSTATES_T 2
#define NUM_SAVEDVERTEXSTATES_S 1
@ -203,17 +203,20 @@ typedef struct wined3d_settings_s {
int rendertargetlock_mode;
/* Memory tracking and object counting */
unsigned int emulated_textureram;
char *logo;
} wined3d_settings_t;
extern wined3d_settings_t wined3d_settings;
/* Shader backends */
struct SHADER_OPCODE_ARG;
typedef struct {
void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
void (*shader_select_depth_blt)(IWineD3DDevice *iface);
void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
void (*shader_cleanup)(IWineD3DDevice *iface);
void (*shader_color_correction)(struct SHADER_OPCODE_ARG *arg);
} shader_backend_t;
extern const shader_backend_t glsl_shader_backend;
@ -329,23 +332,6 @@ typedef struct IWineD3DSurfaceImpl IWineD3DSurfaceImpl;
typedef struct IWineD3DPaletteImpl IWineD3DPaletteImpl;
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 */
extern const float identity[16];
@ -429,8 +415,6 @@ void primitiveDeclarationConvertToStridedData(
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
void blt_to_drawable(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *surface);
#define eps 1e-8
#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_HIGHEST (STATE_MATERIAL)
#define STATE_FRONTFACE (STATE_MATERIAL + 1)
#define STATE_HIGHEST (STATE_FRONTFACE)
struct StateEntry
{
@ -513,6 +499,7 @@ struct WineD3DContext {
DWORD tid; /* Thread ID which owns this context at the moment */
/* 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_pshader;
BOOL last_was_vshader;
@ -524,6 +511,7 @@ struct WineD3DContext {
GLenum untracked_materials[2];
BOOL last_was_blit, last_was_ckey;
char texShaderBumpMap;
BOOL fog_coord;
/* The actual opengl context */
HGLRC glCtx;
@ -597,10 +585,13 @@ struct WineD3DAdapter
WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
int nCfgs;
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 initPixelFormats(WineD3D_GL_Info *gl_info);
extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
/*****************************************************************************
* High order patch management
@ -713,6 +704,7 @@ struct IWineD3DDeviceImpl
/* palettes texture management */
PALETTEENTRY palettes[MAX_PALETTES][256];
UINT currentPalette;
UINT paletteConversionShader;
/* For rendering to a texture using glCopyTexImage */
BOOL render_offscreen;
@ -733,6 +725,9 @@ struct IWineD3DDeviceImpl
BOOL haveHardwareCursor;
HCURSOR hardwareCursor;
/* The Wine logo surface */
IWineD3DSurface *logo_surface;
/* Textures for when no other textures are mapped */
UINT dummyTextureName[MAX_TEXTURES];
@ -829,7 +824,8 @@ typedef struct IWineD3DResourceClass
UINT size;
DWORD usage;
WINED3DFORMAT format;
BYTE *allocatedMemory;
BYTE *allocatedMemory; /* Pointer to the real data location */
BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */
struct list privateData;
} IWineD3DResourceClass;
@ -841,6 +837,8 @@ typedef struct IWineD3DResourceImpl
IWineD3DResourceClass resource;
} IWineD3DResourceImpl;
/* Tests show that the start address of resources is 32 byte aligned */
#define RESOURCE_ALIGNMENT 32
/*****************************************************************************
* IWineD3DVertexBuffer implementation structure (extends IWineD3DResourceImpl)
@ -931,6 +929,7 @@ typedef struct IWineD3DBaseTextureClass
DWORD sampler;
BOOL is_srgb;
UINT srgb_mode_change_count;
WINED3DFORMAT shader_conversion_group;
} IWineD3DBaseTextureClass;
typedef struct IWineD3DBaseTextureImpl
@ -1050,6 +1049,7 @@ typedef struct _WINED3DSURFACET_DESC
typedef struct wineD3DSurface_DIB {
HBITMAP DIBsection;
void* bitmap_data;
UINT bitmap_size;
HGDIOBJ holdbitmap;
BOOL client_memory;
} wineD3DSurface_DIB;
@ -1100,6 +1100,9 @@ struct IWineD3DSurfaceImpl
/* Oversized texture */
RECT glRect;
/* PBO */
GLuint pbo;
#if 0
/* precalculated x and y scalings for texture coords */
float pow2scalingFactorX; /* = (Width / pow2Width ) */
@ -1112,6 +1115,7 @@ struct IWineD3DSurfaceImpl
#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */
glDescriptor glDescription;
BOOL srgb;
/* For GetDC */
wineD3DSurface_DIB dib;
@ -1137,49 +1141,41 @@ extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl;
/* Predeclare the shared Surface functions */
HRESULT WINAPI IWineD3DSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
ULONG WINAPI IWineD3DSurfaceImpl_AddRef(IWineD3DSurface *iface);
ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent);
HRESULT WINAPI IWineD3DSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags);
HRESULT WINAPI IWineD3DSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData);
HRESULT WINAPI IWineD3DSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid);
DWORD WINAPI IWineD3DSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew);
DWORD WINAPI IWineD3DSurfaceImpl_GetPriority(IWineD3DSurface *iface);
void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface);
WINED3DRESOURCETYPE WINAPI IWineD3DSurfaceImpl_GetType(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer);
HRESULT WINAPI IWineD3DSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc);
HRESULT WINAPI IWineD3DSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DSurfaceImpl_IsLost(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_Restore(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPixelFormat(IWineD3DSurface *iface, WINED3DFORMAT Format, BYTE *Surface, DWORD Size);
HRESULT WINAPI IWineD3DSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD3DPalette **Pal);
HRESULT WINAPI IWineD3DSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal);
HRESULT WINAPI IWineD3DSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, WINEDDCOLORKEY *CKey);
HRESULT WINAPI IWineD3DSurfaceImpl_CleanDirtyRect(IWineD3DSurface *iface);
extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, CONST RECT* pDirtyRect);
HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container);
void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT textureName, int target);
void WINAPI IWineD3DSurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_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 IWineD3DBaseSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid);
DWORD WINAPI IWineD3DBaseSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew);
DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPriority(IWineD3DSurface *iface);
WINED3DRESOURCETYPE WINAPI IWineD3DBaseSurfaceImpl_GetType(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_IsLost(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Restore(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD3DPalette **Pal);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, WINEDDCOLORKEY *CKey);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container);
DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetOverlayPosition(IWineD3DSurface *iface, LONG X, LONG Y);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetOverlayPosition(IWineD3DSurface *iface, LONG *X, LONG *Y);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlayZOrder(IWineD3DSurface *iface, DWORD Flags, IWineD3DSurface *Ref);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *SrcRect, IWineD3DSurface *DstSurface, RECT *DstRect, DWORD Flags, WINEDDOVERLAYFX *FX);
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);
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: */
#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_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_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:
* 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_DYNLOCK: Avoid freeing the data for performance
* 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
*/
#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \
@ -1217,8 +1215,12 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
SFLAG_DYNLOCK | \
SFLAG_DYNCHANGE | \
SFLAG_USERPTR | \
SFLAG_PBO | \
SFLAG_CLIENT)
#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \
SFLAG_INTEXTURE | \
SFLAG_INDRAWABLE)
BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]);
typedef enum {
@ -1236,6 +1238,7 @@ typedef enum {
CONVERT_CK_8888_ARGB,
CONVERT_RGB32_888,
CONVERT_V8U8,
CONVERT_L6V5U5,
CONVERT_X8L8V8U8,
CONVERT_Q8W8V8U8,
CONVERT_V16U16,
@ -1348,8 +1351,8 @@ struct IWineD3DStateBlockImpl
/* Indices */
IWineD3DIndexBuffer* pIndexData;
UINT baseVertexIndex;
UINT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
INT baseVertexIndex;
INT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
/* Transform */
WINED3DMATRIX transforms[HIGHEST_TRANSFORMSTATE + 1];
@ -1465,10 +1468,12 @@ extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
/* Datastructures for IWineD3DQueryImpl.extendedData */
typedef struct WineQueryOcclusionData {
GLuint queryId;
WineD3DContext *ctx;
} WineQueryOcclusionData;
typedef struct WineQueryEventData {
GLuint fenceId;
WineD3DContext *ctx;
} WineQueryEventData;
/*****************************************************************************
@ -1535,7 +1540,7 @@ GLenum StencilOp(DWORD op);
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_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);
GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
@ -1545,6 +1550,7 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize
/* Math utils */
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
@ -1600,7 +1606,6 @@ void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED
/*** class static members ***/
void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface);
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
@ -1612,6 +1617,15 @@ struct glsl_shader_prog_link {
GLhandleARB programId;
GLhandleARB *vuniformF_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 pshader;
};
@ -1659,10 +1673,11 @@ typedef struct shader_reg_maps {
/* Sampler usage tokens
* Use 0 as default (bit 31 is always 1 on a valid token) */
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 */
char loop;
/* Whether or not loops are used in this shader, and nesting depth */
unsigned loop_depth;
/* Whether or not this shader uses 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_texm3x3spec(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 */
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);
/* 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_label(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);
/** 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_input_pack(
SHADER_BUFFER* buffer,
semantic* semantics_out);
/** GLSL Vertex Shader Prototypes */
extern void vshader_glsl_output_unpack(
SHADER_BUFFER* buffer,
semantic* semantics_out);
semantic* semantics_out,
IWineD3DPixelShader *iface);
/*****************************************************************************
* IDirect3DBaseShader implementation structure
@ -1879,6 +1903,7 @@ typedef struct IWineD3DBaseShaderClass
UINT functionLength;
GLuint prgId;
BOOL is_compiled;
UINT cur_loop_depth, cur_loop_regno;
/* Type of shader backend */
int shader_mode;
@ -1892,6 +1917,17 @@ typedef struct IWineD3DBaseShaderClass
struct list constantsI;
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 */
IWineD3DDevice *device;
@ -2030,6 +2066,9 @@ typedef struct IWineD3DVertexShaderImpl {
/* run time datas... */
VSHADERDATA *data;
UINT min_rel_offset, max_rel_offset;
UINT rel_offset;
#if 0 /* needs reworking */
/* run time datas */
VSHADERINPUTDATA input;
@ -2042,6 +2081,13 @@ extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
/*****************************************************************************
* IDirect3DPixelShader implementation structure
*/
enum vertexprocessing_mode {
fixedfunction,
vertexshader,
pretransformed
};
typedef struct IWineD3DPixelShaderImpl {
/* IUnknown parts */
const IWineD3DPixelShaderVtbl *lpVtbl;
@ -2055,6 +2101,8 @@ typedef struct IWineD3DPixelShaderImpl {
/* Pixel shader input semantics */
semantic semantics_in [MAX_REG_INPUT];
DWORD input_reg_map[MAX_REG_INPUT];
BOOL input_reg_used[MAX_REG_INPUT];
/* run time data */
PSHADERDATA *data;
@ -2062,6 +2110,15 @@ typedef struct IWineD3DPixelShaderImpl {
/* Some information about the shader behavior */
char needsbumpmat;
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 */
PSHADERINPUTDATA input;
@ -2072,6 +2129,13 @@ typedef struct IWineD3DPixelShaderImpl {
extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
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
*/

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 */
#define WINED3DSI_TEXLD_PROJECT 0x00010000
#define WINED3DSI_TEXLD_BIAS 0x00020000
/** 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 *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 *glPointParameterfv) (GLenum pname, const GLfloat *params);
/* WGL functions */
HGLRC (WINAPI *pwglCreateContext)(HDC);
@ -1483,7 +1484,8 @@ BOOL (WINAPI *pwglShareLists)(HGLRC,HGLRC);
USE_GL_FUNC(glVertex4s) \
USE_GL_FUNC(glVertex4sv) \
USE_GL_FUNC(glVertexPointer) \
USE_GL_FUNC(glViewport)
USE_GL_FUNC(glViewport) \
USE_GL_FUNC(glPointParameterfv) \
#define WGL_FUNCS_GEN \
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_PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, 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 */
#ifndef GL_EXT_texture
#define GL_EXT_texture 1
@ -2709,7 +2718,7 @@ typedef void (WINE_GLAPI * PGLFNGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage
#endif
/**
* Point sprites
* Point sprites
*/
/* 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
#endif
/**
* @TODO: GL_NV_point_sprite
* @TODO: GL_NV_point_sprite
*/
/**
* Occlusion Queries
* Occlusion Queries
*/
/* 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 * 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 */
#ifndef GL_VERSION_2_0
#define GL_VERSION_2_0 1
@ -3018,8 +3051,8 @@ typedef void (WINE_GLAPI * PGLFNVERTEXATTRIBPOINTERPROC) (GLuint index, GLint si
/****************************************************
* OpenGL Official Version
* defines
* OpenGL Official Version
* defines
****************************************************/
/* GL_VERSION_1_3 */
#if !defined(GL_DOT3_RGBA)
@ -3050,6 +3083,9 @@ typedef enum _GL_Cards {
CARD_ATI_RADEON_9500 = 0x4144,
CARD_ATI_RADEON_X700 = 0x5e4c,
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_TNT = 0x0020,
@ -3067,6 +3103,9 @@ typedef enum _GL_Cards {
CARD_NVIDIA_GEFORCE_6600GT = 0x0140,
CARD_NVIDIA_GEFORCE_6800 = 0x0041,
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_I830G = 0x3577,
@ -3076,6 +3115,8 @@ typedef enum _GL_Cards {
CARD_INTEL_I915GM = 0x2592
} GL_Cards;
#define WINE_DEFAULT_VIDMEM 64*1024*1024
typedef enum _GL_VSVersion {
VS_VERSION_NOT_SUPPORTED = 0x0,
VS_VERSION_10 = 0x10,
@ -3167,6 +3208,7 @@ typedef enum _GL_SupportedExt {
NV_VERTEX_PROGRAM2,
NV_VERTEX_PROGRAM3,
NV_FENCE,
NV_DEPTH_CLAMP,
/* ATI */
ATI_SEPARATE_STENCIL,
ATI_TEXTURE_ENV_COMBINE3,
@ -3176,8 +3218,11 @@ typedef enum _GL_SupportedExt {
/* APPLE */
APPLE_FENCE,
APPLE_CLIENT_STORAGE,
APPLE_FLUSH_RENDER,
APPLE_YCBCR_422,
/* SGI */
SGI_VIDEO_SYNC,
SGIS_GENERATE_MIPMAP,
/* WGL extensions */
WGL_ARB_PBUFFER,
@ -3187,15 +3232,15 @@ typedef enum _GL_SupportedExt {
/****************************************************
* #Defines
* #Defines
****************************************************/
#define GL_EXT_FUNCS_GEN \
/** ARB Extensions **/ \
/* GL_ARB_draw_buffers */ \
USE_GL_FUNC(PGLFNDRAWBUFFERSARBPROC, glDrawBuffersARB); \
/* GL_ARB_imaging */ \
USE_GL_FUNC(PGLFNBLENDCOLORPROC, glBlendColor); \
USE_GL_FUNC(PGLFNBLENDEQUATIONPROC, glBlendEquation); \
/* GL_ARB_imaging, GL_EXT_blend_minmax */ \
USE_GL_FUNC(PGLFNBLENDCOLORPROC, glBlendColorEXT); \
USE_GL_FUNC(PGLFNBLENDEQUATIONPROC, glBlendEquationEXT); \
/* GL_ARB_multisample */ \
USE_GL_FUNC(WINED3D_PFNGLSAMPLECOVERAGEARBPROC, glSampleCoverageARB); \
/* GL_ARB_multitexture */ \
@ -3343,9 +3388,9 @@ typedef enum _GL_SupportedExt {
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, glUniform2fARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FARBPROC, glUniform3fARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FARBPROC, glUniform4fARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3IVARBPROC, glUniform3fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1FVARBPROC, glUniform1fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FVARBPROC, glUniform2fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FVARBPROC, glUniform3fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FVARBPROC, glUniform4fvARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1ivARB); \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2ivARB); \
@ -3457,6 +3502,9 @@ typedef enum _GL_SupportedExt {
/* GLX_SGI_video_sync */ \
USE_GL_FUNC(PGLXFNGETVIDEOSYNCSGIPROC, glXGetVideoSyncSGI); \
USE_GL_FUNC(PGLXFNWAITVIDEOSYNCSGIPROC, glXWaitVideoSyncSGI); \
/* GL_APPLE_flush_render */ \
USE_GL_FUNC(PGLFNFLUSHRENDERAPPLEPROC, glFlushRenderApple); \
USE_GL_FUNC(PGLFNFINISHRENDERAPPLEPROC, glFinishRenderApple); \
/* OpenGL 2.0 functions */
#define GL2_FUNCS_GEN \
@ -3657,11 +3705,12 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer,
/****************************************************
* Structures
* Structures
****************************************************/
typedef struct {
GLint glInternal, glGammaInternal, glFormat, glType;
WINED3DFORMAT conversion_group;
} GlPixelFormatDesc;
#define USE_GL_FUNC(type, pfn) type pfn;
@ -3672,10 +3721,11 @@ typedef struct _WineD3D_GL_Info {
GL_Vendors gl_vendor;
GL_Cards gl_card;
UINT vidmem;
DWORD gl_driver_version;
CHAR gl_renderer[255];
/**
* CAPS Constants
* CAPS Constants
*/
UINT max_buffers;
UINT max_lights;
@ -3688,10 +3738,11 @@ typedef struct _WineD3D_GL_Info {
UINT max_clipplanes;
UINT max_texture_size;
UINT max_texture3d_size;
float max_pointsize;
float max_pointsize, max_pointsizemin;
UINT max_blends;
UINT max_anisotropy;
UINT max_aux_buffers;
UINT max_glsl_varyings;
unsigned max_vshader_constantsF;
unsigned max_pshader_constantsF;
@ -3712,6 +3763,8 @@ typedef struct _WineD3D_GL_Info {
GL_VSVersion vs_nv_version;
GL_VSVersion vs_ati_version;
BOOL arb_vs_offset_limit;
BOOL supported[OPENGL_SUPPORTED_EXT_END + 1];
/** OpenGL EXT and ARB functions ptr */

View file

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

View file

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