X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=dll%2Fdirectx%2Fwine%2Fwined3d%2Fstate.c;h=a43cc383ca1bea7231516d549ad8e48acb9fa8af;hp=adb426b904b98f9f2544ceb378aade5a898c3391;hb=84291d0d727fc29e14ce67db55edf5e29b87af69;hpb=9ea495ba334cf6a96c8e2cc3fa93d38127a32c29 diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c index adb426b904b..a43cc383ca1 100644 --- a/dll/directx/wine/wined3d/state.c +++ b/dll/directx/wine/wined3d/state.c @@ -8,7 +8,7 @@ * Copyright 2005 Oliver Stieber * Copyright 2006 Henri Verbeet * Copyright 2006-2008 Stefan Dösinger for CodeWeavers - * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2009-2011 Henri Verbeet for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,34 +35,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); -#define GLINFO_LOCATION (*context->gl_info) - /* GL locking for state handlers is done by the caller. */ -static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context); +static void state_blendop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context); -static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_undefined(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - /* Used for states which are not mapped to a gl state as-is, but used somehow different, - * e.g as a parameter for drawing, or which are unimplemented in windows d3d - */ - if(STATE_IS_RENDER(state)) { - WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0); - TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]); - } else { - /* Shouldn't have an unknown type here */ - FIXME("%d no direct mapping to gl of state with unknown type\n", state); - } + ERR("Undefined state.\n"); } -static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_nop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - ERR("Undefined state.\n"); + TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state)); } -static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_fillmode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE]; + WINED3DFILLMODE Value = stateblock->state.render_states[WINED3DRS_FILLMODE]; switch(Value) { case WINED3DFILL_POINT: @@ -82,7 +71,7 @@ static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, stru } } -static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_lighting(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { /* Lighting is not enabled if transformed vertices are drawn * but lighting does not affect the stream sources, so it is not grouped for performance reasons. @@ -94,7 +83,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru return; } - if (stateblock->renderState[WINED3DRS_LIGHTING] + if (stateblock->state.render_states[WINED3DRS_LIGHTING] && !stateblock->device->strided_streams.position_transformed) { glEnable(GL_LIGHTING); @@ -105,10 +94,10 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru } } -static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_zenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { /* No z test without depth stencil buffers */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->fb.depth_stencil) { TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ @@ -116,7 +105,8 @@ static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struc return; } - switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) { + switch (stateblock->state.render_states[WINED3DRS_ZENABLE]) + { case WINED3DZB_FALSE: glDisable(GL_DEPTH_TEST); checkGLcall("glDisable GL_DEPTH_TEST"); @@ -131,16 +121,17 @@ static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struc FIXME("W buffer is not well handled\n"); break; default: - FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]); + FIXME("Unrecognized D3DZBUFFERTYPE value %#x.\n", + stateblock->state.render_states[WINED3DRS_ZENABLE]); } } -static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_cullmode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - /* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering - * switch - */ - switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) { + /* glFrontFace() is set in context.c at context init and on an + * offscreen / onscreen rendering switch. */ + switch (stateblock->state.render_states[WINED3DRS_CULLMODE]) + { case WINED3DCULL_NONE: glDisable(GL_CULL_FACE); checkGLcall("glDisable GL_CULL_FACE"); @@ -158,13 +149,15 @@ static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, stru checkGLcall("glCullFace(GL_BACK)"); break; default: - FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]); + FIXME("Unrecognized/Unhandled WINED3DCULL value %#x.\n", + stateblock->state.render_states[WINED3DRS_CULLMODE]); } } -static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_shademode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) { + switch (stateblock->state.render_states[WINED3DRS_SHADEMODE]) + { case WINED3DSHADE_FLAT: glShadeModel(GL_FLAT); checkGLcall("glShadeModel(GL_FLAT)"); @@ -177,84 +170,136 @@ static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, str FIXME("WINED3DSHADE_PHONG isn't supported\n"); break; default: - FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]); + FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %#x.\n", + stateblock->state.render_states[WINED3DRS_SHADEMODE]); } } -static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_ditherenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if (stateblock->renderState[WINED3DRS_DITHERENABLE]) { + if (stateblock->state.render_states[WINED3DRS_DITHERENABLE]) + { glEnable(GL_DITHER); checkGLcall("glEnable GL_DITHER"); - } else { + } + else + { glDisable(GL_DITHER); checkGLcall("glDisable GL_DITHER"); } } -static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_zwritenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes, - * this has to be merged with ZENABLE and ZFUNC - */ - if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) { + /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. + * If yes, this has to be merged with ZENABLE and ZFUNC. */ + if (stateblock->state.render_states[WINED3DRS_ZWRITEENABLE]) + { glDepthMask(1); checkGLcall("glDepthMask(1)"); - } else { + } + else + { glDepthMask(0); checkGLcall("glDepthMask(0)"); } } -static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_zfunc(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]); + GLenum depth_func = CompareFunc(stateblock->state.render_states[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"); - } - } + if (!depth_func) return; - glDepthFunc(glParm); - checkGLcall("glDepthFunc"); + if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL) + { + static BOOL once; + /* 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(depth_func); + checkGLcall("glDepthFunc"); } -static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_ambient(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { float col[4]; - D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col); + D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_AMBIENT], col); TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col); checkGLcall("glLightModel for MODEL_AMBIENT"); } -static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static GLenum gl_blend_factor(WINED3DBLEND factor, const struct wined3d_format *dst_format) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; - int srcBlend = GL_ZERO; - int dstBlend = GL_ZERO; - - /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */ - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] || - stateblock->renderState[WINED3DRS_EDGEANTIALIAS] || - stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) { + switch (factor) + { + case WINED3DBLEND_ZERO: + return GL_ZERO; + case WINED3DBLEND_ONE: + return GL_ONE; + case WINED3DBLEND_SRCCOLOR: + return GL_SRC_COLOR; + case WINED3DBLEND_INVSRCCOLOR: + return GL_ONE_MINUS_SRC_COLOR; + case WINED3DBLEND_SRCALPHA: + return GL_SRC_ALPHA; + case WINED3DBLEND_INVSRCALPHA: + return GL_ONE_MINUS_SRC_ALPHA; + case WINED3DBLEND_DESTCOLOR: + return GL_DST_COLOR; + case WINED3DBLEND_INVDESTCOLOR: + return GL_ONE_MINUS_DST_COLOR; + /* To compensate for the lack of format switching with backbuffer + * offscreen rendering, and with onscreen rendering, we modify the + * alpha test parameters for (INV)DESTALPHA if the render target + * doesn't support alpha blending. A nonexistent alpha channel + * returns 1.0, so WINED3DBLEND_DESTALPHA becomes GL_ONE, and + * WINED3DBLEND_INVDESTALPHA becomes GL_ZERO. */ + case WINED3DBLEND_DESTALPHA: + return dst_format->alpha_mask ? GL_DST_ALPHA : GL_ONE; + case WINED3DBLEND_INVDESTALPHA: + return dst_format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO; + case WINED3DBLEND_SRCALPHASAT: + return GL_SRC_ALPHA_SATURATE; + case WINED3DBLEND_BLENDFACTOR: + return GL_CONSTANT_COLOR_EXT; + case WINED3DBLEND_INVBLENDFACTOR: + return GL_ONE_MINUS_CONSTANT_COLOR_EXT; + default: + FIXME("Unhandled blend factor %#x.\n", factor); + return GL_NONE; + } +} - /* Disable blending in all cases even without pixelshaders. With blending on we could face a big performance penalty. +static void state_blend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + struct wined3d_surface *target = stateblock->device->fb.render_targets[0]; + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum srcBlend, dstBlend; + WINED3DBLEND d3d_blend; + + /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific + * blending parameters to work. */ + if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE] + || stateblock->state.render_states[WINED3DRS_EDGEANTIALIAS] + || stateblock->state.render_states[WINED3DRS_ANTIALIASEDLINEENABLE]) + { + /* Disable blending in all cases even without pixelshaders. + * With blending on we could face a big performance penalty. * The d3d9 visual test confirms the behavior. */ if (context->render_offscreen - && !(target->resource.format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) + && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) { glDisable(GL_BLEND); checkGLcall("glDisable GL_BLEND"); @@ -270,86 +315,30 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct return; }; - switch (stateblock->renderState[WINED3DRS_DESTBLEND]) { - case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break; - case WINED3DBLEND_ONE : dstBlend = GL_ONE; break; - case WINED3DBLEND_SRCCOLOR : dstBlend = GL_SRC_COLOR; break; - case WINED3DBLEND_INVSRCCOLOR : dstBlend = GL_ONE_MINUS_SRC_COLOR; break; - case WINED3DBLEND_SRCALPHA : dstBlend = GL_SRC_ALPHA; break; - case WINED3DBLEND_INVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; break; - case WINED3DBLEND_DESTCOLOR : dstBlend = GL_DST_COLOR; break; - case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break; - - /* To compensate the lack of format switching with backbuffer offscreen rendering, - * and with onscreen rendering, we modify the alpha test parameters for (INV)DESTALPHA - * if the render target doesn't support alpha blending. A nonexistent alpha channel - * returns 1.0, so D3DBLEND_DESTALPHA is GL_ONE, and D3DBLEND_INVDESTALPHA is GL_ZERO - */ - case WINED3DBLEND_DESTALPHA : - dstBlend = target->resource.format_desc->alpha_mask ? GL_DST_ALPHA : GL_ONE; - break; - case WINED3DBLEND_INVDESTALPHA : - dstBlend = target->resource.format_desc->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO; - break; - - case WINED3DBLEND_SRCALPHASAT : - dstBlend = GL_SRC_ALPHA_SATURATE; - 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; - case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break; - default: - 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_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_DESTALPHA : - srcBlend = target->resource.format_desc->alpha_mask ? GL_DST_ALPHA : GL_ONE; - break; - case WINED3DBLEND_INVDESTALPHA : - srcBlend = target->resource.format_desc->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO; - 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]); + /* 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. */ + d3d_blend = stateblock->state.render_states[WINED3DRS_SRCBLEND]; + if (d3d_blend == WINED3DBLEND_BOTHSRCALPHA) + { + srcBlend = GL_SRC_ALPHA; + dstBlend = GL_ONE_MINUS_SRC_ALPHA; + } + else if (d3d_blend == WINED3DBLEND_BOTHINVSRCALPHA) + { + srcBlend = GL_ONE_MINUS_SRC_ALPHA; + dstBlend = GL_SRC_ALPHA; + } + else + { + srcBlend = gl_blend_factor(d3d_blend, target->resource.format); + dstBlend = gl_blend_factor(stateblock->state.render_states[WINED3DRS_DESTBLEND], + target->resource.format); } - if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] || - stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) { + if (stateblock->state.render_states[WINED3DRS_EDGEANTIALIAS] + || stateblock->state.render_states[WINED3DRS_ANTIALIASEDLINEENABLE]) + { glEnable(GL_LINE_SMOOTH); checkGLcall("glEnable(GL_LINE_SMOOTH)"); if(srcBlend != GL_SRC_ALPHA) { @@ -368,9 +357,9 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct state_blendop(STATE_RENDER(WINED3DRS_BLENDOPALPHA), stateblock, context); } - if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) { - int srcBlendAlpha = GL_ZERO; - int dstBlendAlpha = GL_ZERO; + if (stateblock->state.render_states[WINED3DRS_SEPARATEALPHABLENDENABLE]) + { + GLenum srcBlendAlpha, dstBlendAlpha; /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */ if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) @@ -379,64 +368,25 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct return; } - switch (stateblock->renderState[WINED3DRS_DESTBLENDALPHA]) { - case WINED3DBLEND_ZERO : dstBlendAlpha = GL_ZERO; break; - case WINED3DBLEND_ONE : dstBlendAlpha = GL_ONE; break; - case WINED3DBLEND_SRCCOLOR : dstBlendAlpha = GL_SRC_COLOR; break; - case WINED3DBLEND_INVSRCCOLOR : dstBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break; - case WINED3DBLEND_SRCALPHA : dstBlendAlpha = GL_SRC_ALPHA; break; - case WINED3DBLEND_INVSRCALPHA : dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break; - case WINED3DBLEND_DESTCOLOR : dstBlendAlpha = GL_DST_COLOR; break; - case WINED3DBLEND_INVDESTCOLOR : dstBlendAlpha = GL_ONE_MINUS_DST_COLOR; break; - case WINED3DBLEND_DESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break; - case WINED3DBLEND_INVDESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break; - case WINED3DBLEND_SRCALPHASAT : - dstBlend = GL_SRC_ALPHA_SATURATE; - 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 : - dstBlendAlpha = GL_SRC_ALPHA; - srcBlendAlpha = GL_SRC_ALPHA; - FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHSRCALPHA, what to do?\n"); - break; - case WINED3DBLEND_BOTHINVSRCALPHA : - dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; - srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; - FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n"); - break; - case WINED3DBLEND_BLENDFACTOR : dstBlendAlpha = GL_CONSTANT_COLOR; break; - case WINED3DBLEND_INVBLENDFACTOR : dstBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break; - default: - FIXME("Unrecognized dst blend alpha value %d\n", stateblock->renderState[WINED3DRS_DESTBLENDALPHA]); + /* 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. */ + d3d_blend = stateblock->state.render_states[WINED3DRS_SRCBLENDALPHA]; + if (d3d_blend == WINED3DBLEND_BOTHSRCALPHA) + { + srcBlendAlpha = GL_SRC_ALPHA; + dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; } - - switch (stateblock->renderState[WINED3DRS_SRCBLENDALPHA]) { - case WINED3DBLEND_ZERO : srcBlendAlpha = GL_ZERO; break; - case WINED3DBLEND_ONE : srcBlendAlpha = GL_ONE; break; - case WINED3DBLEND_SRCCOLOR : srcBlendAlpha = GL_SRC_COLOR; break; - case WINED3DBLEND_INVSRCCOLOR : srcBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break; - case WINED3DBLEND_SRCALPHA : srcBlendAlpha = GL_SRC_ALPHA; break; - case WINED3DBLEND_INVSRCALPHA : srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break; - case WINED3DBLEND_DESTCOLOR : srcBlendAlpha = GL_DST_COLOR; break; - case WINED3DBLEND_INVDESTCOLOR : srcBlendAlpha = GL_ONE_MINUS_DST_COLOR; break; - case WINED3DBLEND_SRCALPHASAT : srcBlendAlpha = GL_SRC_ALPHA_SATURATE; break; - case WINED3DBLEND_DESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break; - case WINED3DBLEND_INVDESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break; - case WINED3DBLEND_BOTHSRCALPHA : - srcBlendAlpha = GL_SRC_ALPHA; - dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; - break; - case WINED3DBLEND_BOTHINVSRCALPHA : - srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; - dstBlendAlpha = GL_SRC_ALPHA; - break; - case WINED3DBLEND_BLENDFACTOR : srcBlendAlpha = GL_CONSTANT_COLOR; break; - case WINED3DBLEND_INVBLENDFACTOR : srcBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break; - default: - FIXME("Unrecognized src blend alpha value %d\n", stateblock->renderState[WINED3DRS_SRCBLENDALPHA]); + else if (d3d_blend == WINED3DBLEND_BOTHINVSRCALPHA) + { + srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; + dstBlendAlpha = GL_SRC_ALPHA; + } + else + { + srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format); + dstBlendAlpha = gl_blend_factor(stateblock->state.render_states[WINED3DRS_DESTBLENDALPHA], + target->resource.format); } GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha)); @@ -449,29 +399,27 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state, so it may need updating */ - if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) - { - const struct StateEntry *StateTable = stateblock->device->StateTable; - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); - } + if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE]) + stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } -static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_blendfactor_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n"); } -static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_blendfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; - TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]); - D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col); + TRACE("Setting blend factor to %#x.\n", stateblock->state.render_states[WINED3DRS_BLENDFACTOR]); + D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_BLENDFACTOR], col); GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3])); checkGLcall("glBlendColor"); } -static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_alpha(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { int glParm = 0; float ref; @@ -485,35 +433,32 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha * in case it finds some texture+colorkeyenable combination which needs extra care. */ - if (stateblock->textures[0]) + if (stateblock->state.textures[0]) { - UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]); + struct wined3d_texture *texture = stateblock->state.textures[0]; + GLenum texture_dimensions = texture->target; if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0]; + struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]); if (surf->CKeyFlags & WINEDDSD_CKSRCBLT) { /* The surface conversion does not do color keying conversion for surfaces that have an alpha * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the * surface has alpha bits */ - if (!surf->resource.format_desc->alpha_mask) enable_ckey = TRUE; + if (!surf->resource.format->alpha_mask) enable_ckey = TRUE; } } } if (enable_ckey || context->last_was_ckey) - { - const struct StateEntry *StateTable = stateblock->device->StateTable; - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); - } + stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); context->last_was_ckey = enable_ckey; - if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] || - (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) { + if (stateblock->state.render_states[WINED3DRS_ALPHATESTENABLE] + || (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && enable_ckey)) + { glEnable(GL_ALPHA_TEST); checkGLcall("glEnable GL_ALPHA_TEST"); } else { @@ -525,12 +470,13 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct return; } - if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) { + if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && enable_ckey) + { glParm = GL_NOTEQUAL; ref = 0.0f; } else { - ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f; - glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]); + ref = ((float)stateblock->state.render_states[WINED3DRS_ALPHAREF]) / 255.0f; + glParm = CompareFunc(stateblock->state.render_states[WINED3DRS_ALPHAFUNC]); } if(glParm) { glAlphaFunc(glParm, ref); @@ -538,20 +484,22 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } } -static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_clipping(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state *state = &stateblock->state; DWORD enable = 0xFFFFFFFF; DWORD disable = 0x00000000; - if (!stateblock->device->vs_clipping && use_vs(stateblock)) + if (!stateblock->device->vs_clipping && use_vs(state)) { /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't, * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some * conditions I got sick of tracking down. The shader state handler disables all clip planes because * of that - don't do anything here and keep them disabled */ - if(stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) { + if (state->render_states[WINED3DRS_CLIPPLANEENABLE]) + { static BOOL warned = FALSE; if(!warned) { FIXME("Clipping not supported with vertex shaders\n"); @@ -568,9 +516,10 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, stru /* If enabling / disabling all * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum? */ - if (stateblock->renderState[WINED3DRS_CLIPPING]) { - enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]; - disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]; + if (state->render_states[WINED3DRS_CLIPPING]) + { + enable = state->render_states[WINED3DRS_CLIPPLANEENABLE]; + disable = ~state->render_states[WINED3DRS_CLIPPLANEENABLE]; if (gl_info->supported[ARB_DEPTH_CLAMP]) { glDisable(GL_DEPTH_CLAMP); @@ -584,6 +533,10 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, stru glEnable(GL_DEPTH_CLAMP); checkGLcall("glEnable(GL_DEPTH_CLAMP)"); } + else + { + FIXME("Clipping disabled, but ARB_depth_clamp isn't supported.\n"); + } } if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); } @@ -601,54 +554,62 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, stru if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); } /** update clipping status */ - if (enable) { - stateblock->clip_status.ClipUnion = 0; - stateblock->clip_status.ClipIntersection = 0xFFFFFFFF; - } else { - stateblock->clip_status.ClipUnion = 0; - stateblock->clip_status.ClipIntersection = 0; + if (enable) + { + stateblock->state.clip_status.ClipUnion = 0; + stateblock->state.clip_status.ClipIntersection = 0xFFFFFFFF; + } + else + { + stateblock->state.clip_status.ClipUnion = 0; + stateblock->state.clip_status.ClipIntersection = 0; } } -static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_blendop_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { WARN("Unsupported in local OpenGL implementation: glBlendEquation\n"); } -static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static GLenum gl_blend_op(WINED3DBLENDOP op) { - int blendEquation = GL_FUNC_ADD; - int blendEquationAlpha = GL_FUNC_ADD; + switch (op) + { + case WINED3DBLENDOP_ADD: + return GL_FUNC_ADD_EXT; + case WINED3DBLENDOP_SUBTRACT: + return GL_FUNC_SUBTRACT_EXT; + case WINED3DBLENDOP_REVSUBTRACT: + return GL_FUNC_REVERSE_SUBTRACT_EXT; + case WINED3DBLENDOP_MIN: + return GL_MIN_EXT; + case WINED3DBLENDOP_MAX: + return GL_MAX_EXT; + default: + FIXME("Unhandled blend op %#x.\n", op); + return GL_NONE; + } +} + +static void state_blendop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + int blendEquation = GL_FUNC_ADD_EXT; + int blendEquationAlpha = GL_FUNC_ADD_EXT; /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */ - if (stateblock->renderState[WINED3DRS_BLENDOPALPHA] - && !context->gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) + if (stateblock->state.render_states[WINED3DRS_BLENDOPALPHA] + && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) { WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n"); return; } - switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) { - case WINED3DBLENDOP_ADD : blendEquation = GL_FUNC_ADD; break; - case WINED3DBLENDOP_SUBTRACT : blendEquation = GL_FUNC_SUBTRACT; break; - case WINED3DBLENDOP_REVSUBTRACT : blendEquation = GL_FUNC_REVERSE_SUBTRACT; break; - case WINED3DBLENDOP_MIN : blendEquation = GL_MIN; break; - case WINED3DBLENDOP_MAX : blendEquation = GL_MAX; break; - default: - FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]); - } - - switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOPALPHA]) { - case WINED3DBLENDOP_ADD : blendEquationAlpha = GL_FUNC_ADD; break; - case WINED3DBLENDOP_SUBTRACT : blendEquationAlpha = GL_FUNC_SUBTRACT; break; - case WINED3DBLENDOP_REVSUBTRACT : blendEquationAlpha = GL_FUNC_REVERSE_SUBTRACT; break; - case WINED3DBLENDOP_MIN : blendEquationAlpha = GL_MIN; break; - case WINED3DBLENDOP_MAX : blendEquationAlpha = GL_MAX; break; - default: - FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOPALPHA]); - } + blendEquation = gl_blend_op(stateblock->state.render_states[WINED3DRS_BLENDOP]); + blendEquationAlpha = gl_blend_op(stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]); - if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) { + if (stateblock->state.render_states[WINED3DRS_SEPARATEALPHABLENDENABLE]) + { TRACE("glBlendEquationSeparateEXT(%x, %x)\n", blendEquation, blendEquationAlpha); GL_EXTCALL(glBlendEquationSeparateEXT(blendEquation, blendEquationAlpha)); checkGLcall("glBlendEquationSeparateEXT"); @@ -659,7 +620,7 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struc } } -static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_specularenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR) @@ -693,11 +654,12 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock */ TRACE("Setting specular enable state and materials\n"); - if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular); + if (stateblock->state.render_states[WINED3DRS_SPECULARENABLE]) + { + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&stateblock->state.material.Specular); checkGLcall("glMaterialfv"); - if (stateblock->material.Power > gl_info->limits.shininess) + if (stateblock->state.material.Power > gl_info->limits.shininess) { /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent @@ -705,10 +667,12 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp * them, it should be safe to do so without major visual distortions. */ - WARN("Material power = %f, limit %f\n", stateblock->material.Power, gl_info->limits.shininess); + WARN("Material power = %f, limit %f\n", stateblock->state.material.Power, gl_info->limits.shininess); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess); - } else { - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->material.Power); + } + else + { + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->state.material.Power); } checkGLcall("glMaterialf(GL_SHININESS)"); @@ -753,38 +717,39 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock } TRACE("(%p) : Diffuse {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, - stateblock->material.Diffuse.r, stateblock->material.Diffuse.g, - stateblock->material.Diffuse.b, stateblock->material.Diffuse.a); + stateblock->state.material.Diffuse.r, stateblock->state.material.Diffuse.g, + stateblock->state.material.Diffuse.b, stateblock->state.material.Diffuse.a); TRACE("(%p) : Ambient {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, - stateblock->material.Ambient.r, stateblock->material.Ambient.g, - stateblock->material.Ambient.b, stateblock->material.Ambient.a); + stateblock->state.material.Ambient.r, stateblock->state.material.Ambient.g, + stateblock->state.material.Ambient.b, stateblock->state.material.Ambient.a); TRACE("(%p) : Specular {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, - stateblock->material.Specular.r, stateblock->material.Specular.g, - stateblock->material.Specular.b, stateblock->material.Specular.a); + stateblock->state.material.Specular.r, stateblock->state.material.Specular.g, + stateblock->state.material.Specular.b, stateblock->state.material.Specular.a); TRACE("(%p) : Emissive {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, - stateblock->material.Emissive.r, stateblock->material.Emissive.g, - stateblock->material.Emissive.b, stateblock->material.Emissive.a); + stateblock->state.material.Emissive.r, stateblock->state.material.Emissive.g, + stateblock->state.material.Emissive.b, stateblock->state.material.Emissive.a); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &stateblock->material.Ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&stateblock->state.material.Ambient); checkGLcall("glMaterialfv(GL_AMBIENT)"); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &stateblock->material.Diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&stateblock->state.material.Diffuse); checkGLcall("glMaterialfv(GL_DIFFUSE)"); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &stateblock->material.Emissive); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&stateblock->state.material.Emissive); checkGLcall("glMaterialfv(GL_EMISSION)"); } -static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_texfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; /* Note the texture color applies to all textures whereas * GL_TEXTURE_ENV_COLOR applies to active only */ float col[4]; - D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); + D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col); /* And now the default texture color as well */ - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { /* Note the WINED3DRS value applies to all textures, but GL has one * per texture, so apply it now ready to be used! @@ -800,6 +765,8 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass) { + const struct wined3d_gl_info *gl_info = context->gl_info; + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)"); GL_EXTCALL(glActiveStencilFaceEXT(face)); @@ -810,7 +777,7 @@ static void renderstate_stencil_twosided(struct wined3d_context *context, GLint checkGLcall("glStencilOp(...)"); } -static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_stencil(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; DWORD onesided_enable = FALSE; @@ -827,27 +794,27 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc GLint stencilPass_ccw = GL_KEEP; /* No stencil test without a stencil buffer. */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->fb.depth_stencil) { glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); return; } - onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE]; - twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE]; - if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) ) + onesided_enable = stateblock->state.render_states[WINED3DRS_STENCILENABLE]; + twosided_enable = stateblock->state.render_states[WINED3DRS_TWOSIDEDSTENCILMODE]; + if (!(func = CompareFunc(stateblock->state.render_states[WINED3DRS_STENCILFUNC]))) func = GL_ALWAYS; - if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) ) + if (!(func_ccw = CompareFunc(stateblock->state.render_states[WINED3DRS_CCW_STENCILFUNC]))) func_ccw = GL_ALWAYS; - ref = stateblock->renderState[WINED3DRS_STENCILREF]; - mask = stateblock->renderState[WINED3DRS_STENCILMASK]; - stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]); - depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]); - stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]); - stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]); - depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]); - stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]); + ref = stateblock->state.render_states[WINED3DRS_STENCILREF]; + mask = stateblock->state.render_states[WINED3DRS_STENCILMASK]; + stencilFail = StencilOp(stateblock->state.render_states[WINED3DRS_STENCILFAIL]); + depthFail = StencilOp(stateblock->state.render_states[WINED3DRS_STENCILZFAIL]); + stencilPass = StencilOp(stateblock->state.render_states[WINED3DRS_STENCILPASS]); + stencilFail_ccw = StencilOp(stateblock->state.render_states[WINED3DRS_CCW_STENCILFAIL]); + depthFail_ccw = StencilOp(stateblock->state.render_states[WINED3DRS_CCW_STENCILZFAIL]); + stencilPass_ccw = StencilOp(stateblock->state.render_states[WINED3DRS_CCW_STENCILPASS]); TRACE("(onesided %d, twosided %d, ref %x, mask %x, " "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x " @@ -908,9 +875,10 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc } } -static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_stencilwrite2s(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->fb.depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0; + const struct wined3d_gl_info *gl_info = context->gl_info; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); @@ -921,23 +889,24 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock glStencilMask(mask); } -static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_stencilwrite(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->fb.depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0; glStencilMask(mask); checkGLcall("glStencilMask"); } -static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_fog_vertexpart(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context); - if (!stateblock->renderState[WINED3DRS_FOGENABLE]) return; + if (!stateblock->state.render_states[WINED3DRS_FOGENABLE]) return; /* Table fog on: Never use fog coords, and use per-fragment fog */ - if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE) { + if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE) + { glHint(GL_FOG_HINT, GL_NICEST); if(context->fog_coord) { glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); @@ -950,7 +919,8 @@ static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock /* Otherwise use per-vertex fog in any case */ glHint(GL_FOG_HINT, GL_FASTEST); - if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) { + if (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) + { /* No fog at all, or transformed vertices: Use fog coord */ if(!context->fog_coord) { glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); @@ -967,7 +937,7 @@ static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock } } -void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +void state_fogstartend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { float fogstart, fogend; union { @@ -987,13 +957,13 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w break; case FOGSOURCE_FFP: - tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART]; + tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGSTART]; fogstart = tmpvalue.f; - tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND]; + tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGEND]; fogend = tmpvalue.f; /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/ if(fogstart == fogend) { - fogstart = -1.0f / 0.0f; + fogstart = -INFINITY; fogend = 0.0f; } break; @@ -1016,13 +986,15 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w TRACE("Fog End == %f\n", fogend); } -void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +void state_fog_fragpart(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { + const struct wined3d_state *state = &stateblock->state; enum fogsource new_source; - TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context); + TRACE("state_id %#x, stateblock %p, context %p\n", state_id, stateblock, context); - if (!stateblock->renderState[WINED3DRS_FOGENABLE]) { + if (!state->render_states[WINED3DRS_FOGENABLE]) + { /* No fog? Disable it, and we're done :-) */ glDisableWINE(GL_FOG); checkGLcall("glDisable GL_FOG"); @@ -1075,13 +1047,18 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct /* 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." */ - if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { - if(use_vs(stateblock)) { + if (state->render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) + { + if (use_vs(state)) + { glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); new_source = FOGSOURCE_VS; - } else { - switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { + } + else + { + switch (state->render_states[WINED3DRS_FOGVERTEXMODE]) + { /* If processed vertices are used, fall through to the NONE case */ case WINED3DFOG_EXP: if(!context->last_was_rhw) { @@ -1121,14 +1098,16 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct break; default: - FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]); + FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %#x.\n", + state->render_states[WINED3DRS_FOGVERTEXMODE]); new_source = FOGSOURCE_FFP; /* Make the compiler happy */ } } } else { new_source = FOGSOURCE_FFP; - switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) { + switch (state->render_states[WINED3DRS_FOGTABLEMODE]) + { case WINED3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)"); @@ -1146,7 +1125,8 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct case WINED3DFOG_NONE: /* Won't happen */ default: - FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]); + FIXME("Unexpected WINED3DRS_FOGTABLEMODE %#x.\n", + state->render_states[WINED3DRS_FOGTABLEMODE]); } } @@ -1158,16 +1138,16 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } } -static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_rangefog_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) { + if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE]) WARN("Range fog enabled, but not supported by this opengl implementation\n"); - } } -static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_rangefog(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) { + if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE]) + { glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV); checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)"); } else { @@ -1176,28 +1156,29 @@ static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, stru } } -void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +void state_fogcolor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { float col[4]; - D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col); + D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_FOGCOLOR], col); glFogfv(GL_FOG_COLOR, &col[0]); checkGLcall("glFog GL_FOG_COLOR"); } -void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +void state_fogdensity(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { union { DWORD d; float f; } tmpvalue; - tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY]; + tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGDENSITY]; glFogfv(GL_FOG_DENSITY, &tmpvalue.f); checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)"); } -static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_colormat(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->device; + const struct wined3d_state *state = &stateblock->state; + struct wined3d_device *device = stateblock->device; GLenum Parm = 0; /* Depends on the decoded vertex declaration to read the existence of diffuse data. @@ -1210,45 +1191,56 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, stru context->num_untracked_materials = 0; if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE)) - && stateblock->renderState[WINED3DRS_COLORVERTEX]) + && state->render_states[WINED3DRS_COLORVERTEX]) { TRACE("diff %d, amb %d, emis %d, spec %d\n", - stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE], - stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE], - stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE], - stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]); + state->render_states[WINED3DRS_DIFFUSEMATERIALSOURCE], + state->render_states[WINED3DRS_AMBIENTMATERIALSOURCE], + state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE], + state->render_states[WINED3DRS_SPECULARMATERIALSOURCE]); - if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) { - if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) { + if (state->render_states[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) + { + if (state->render_states[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) Parm = GL_AMBIENT_AND_DIFFUSE; - } else { + else Parm = GL_DIFFUSE; - } - if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) { + if (state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) + { context->untracked_materials[context->num_untracked_materials] = GL_EMISSION; context->num_untracked_materials++; } - if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) { + if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) + { context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR; context->num_untracked_materials++; } - } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) { + } + else if (state->render_states[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) + { Parm = GL_AMBIENT; - if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) { + if (state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) + { context->untracked_materials[context->num_untracked_materials] = GL_EMISSION; context->num_untracked_materials++; } - if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) { + if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) + { context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR; context->num_untracked_materials++; } - } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) { + } + else if (state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) + { Parm = GL_EMISSION; - if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) { + if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) + { context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR; context->num_untracked_materials++; } - } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) { + } + else if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) + { Parm = GL_SPECULAR; } } @@ -1270,30 +1262,31 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, stru * tracking with glColorMaterial, so apply those here. */ switch (context->tracking_parm) { case GL_AMBIENT_AND_DIFFUSE: - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.Ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.Diffuse); checkGLcall("glMaterialfv"); break; case GL_DIFFUSE: - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.Diffuse); checkGLcall("glMaterialfv"); break; case GL_AMBIENT: - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.Ambient); checkGLcall("glMaterialfv"); break; case GL_EMISSION: - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.Emissive); checkGLcall("glMaterialfv"); break; case GL_SPECULAR: /* Only change material color if specular is enabled, otherwise it is set to black */ - if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular); + if (state->render_states[WINED3DRS_SPECULARENABLE]) + { + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.Specular); checkGLcall("glMaterialfv"); } else { static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -1306,13 +1299,13 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, stru context->tracking_parm = Parm; } -static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_linepattern(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { union { DWORD d; WINED3DLINEPATTERN lp; } tmppattern; - tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN]; + tmppattern.d = stateblock->state.render_states[WINED3DRS_LINEPATTERN]; TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern); @@ -1327,36 +1320,7 @@ static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) -{ - union { - DWORD d; - float f; - } tmpvalue; - - if (stateblock->renderState[WINED3DRS_ZBIAS]) { - tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS]; - TRACE("ZBias value %f\n", tmpvalue.f); - glPolygonOffset(0, -tmpvalue.f); - checkGLcall("glPolygonOffset(0, -Value)"); - glEnable(GL_POLYGON_OFFSET_FILL); - checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);"); - glEnable(GL_POLYGON_OFFSET_LINE); - checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);"); - glEnable(GL_POLYGON_OFFSET_POINT); - checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);"); - } else { - glDisable(GL_POLYGON_OFFSET_FILL); - checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);"); - glDisable(GL_POLYGON_OFFSET_LINE); - checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);"); - glDisable(GL_POLYGON_OFFSET_POINT); - checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);"); - } -} - - -static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_normalize(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { if(isStateDirty(context, STATE_VDECL)) { return; @@ -1365,7 +1329,7 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, str * 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] + if (stateblock->state.render_states[WINED3DRS_NORMALIZENORMALS] && (stateblock->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL))) { glEnable(GL_NORMALIZE); @@ -1376,19 +1340,19 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, str } } -static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_psizemin_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { union { DWORD d; float f; } tmpvalue; - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; + tmpvalue.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN]; if (tmpvalue.f != 1.0f) { FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f); } - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; + tmpvalue.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX]; if (tmpvalue.f != 64.0f) { FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f); @@ -1396,15 +1360,17 @@ static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, st } -static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_psizemin_ext(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - union { + const struct wined3d_gl_info *gl_info = context->gl_info; + union + { DWORD d; float f; } min, max; - min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; - max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; + min.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN]; + max.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX]; /* Max point size trumps min point size */ if(min.f > max.f) { @@ -1417,15 +1383,17 @@ static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, checkGLcall("glPointParameterfEXT(...)"); } -static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_psizemin_arb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - union { + const struct wined3d_gl_info *gl_info = context->gl_info; + union + { DWORD d; float f; } min, max; - min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; - max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; + min.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN]; + max.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX]; /* Max point size trumps min point size */ if(min.f > max.f) { @@ -1438,7 +1406,7 @@ static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, checkGLcall("glPointParameterfARB(...)"); } -static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_pscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; /* TODO: Group this with the viewport */ @@ -1455,14 +1423,15 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct float f; } pointSize, A, B, C; - 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]; + pointSize.d = stateblock->state.render_states[WINED3DRS_POINTSIZE]; + A.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_A]; + B.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_B]; + C.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_C]; - if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) { + if (stateblock->state.render_states[WINED3DRS_POINTSCALEENABLE]) + { GLfloat scaleFactor; - float h = stateblock->viewport.Height; + DWORD h = stateblock->state.viewport.Height; if (pointSize.f < gl_info->limits.pointsize_min) { @@ -1490,7 +1459,7 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } else { scaleFactor = 1.0f; } - scaleFactor = pow(h * scaleFactor, 2); + scaleFactor = powf(h * scaleFactor, 2); att[0] = A.f / scaleFactor; att[1] = B.f / scaleFactor; @@ -1506,7 +1475,9 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct { GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att); checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)"); - } else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) { + } + else if(stateblock->state.render_states[WINED3DRS_POINTSCALEENABLE]) + { WARN("POINT_PARAMETERS not supported in this version of opengl\n"); } @@ -1514,40 +1485,71 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct checkGLcall("glPointSize(...);"); } -static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_debug_monitor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - WARN("token: %#x\n", stateblock->renderState[WINED3DRS_DEBUGMONITORTOKEN]); + WARN("token: %#x\n", stateblock->state.render_states[WINED3DRS_DEBUGMONITORTOKEN]); } -static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_colorwrite(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE]; + DWORD mask0 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE]; + DWORD mask1 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1]; + DWORD mask2 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2]; + DWORD mask3 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3]; TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", - Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); - glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); + mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); + glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); checkGLcall("glColorMask(...)"); - /* depends on WINED3DRS_COLORWRITEENABLE. */ - if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F || - stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F || - stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) { - ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n", - stateblock->renderState[WINED3DRS_COLORWRITEENABLE1], - stateblock->renderState[WINED3DRS_COLORWRITEENABLE2], - stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]); + if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) + || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) + { + FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", + mask0, mask1, mask2, mask3); + FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); } } -static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) +{ + GL_EXTCALL(glColorMaskIndexedEXT(index, + mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE)); +} + +static void state_colorwrite0(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 0, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE]); +} + +static void state_colorwrite1(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) { + set_color_mask(context->gl_info, 1, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1]); +} + +static void state_colorwrite2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 2, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2]); +} + +static void state_colorwrite3(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 3, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3]); +} + +static void state_localviewer(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + if (stateblock->state.render_states[WINED3DRS_LOCALVIEWER]) + { glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)"); } else { @@ -1556,9 +1558,10 @@ static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_lastpixel(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_LASTPIXEL]) { + if (stateblock->state.render_states[WINED3DRS_LASTPIXEL]) + { TRACE("Last Pixel Drawing Enabled\n"); } else { static BOOL warned; @@ -1571,29 +1574,31 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, str } } -static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_pointsprite_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { static BOOL warned; /* TODO: NV_POINT_SPRITE */ - if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) { + if (!warned && stateblock->state.render_states[WINED3DRS_POINTSPRITEENABLE]) + { /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */ FIXME("Point sprites not supported\n"); warned = TRUE; } } -static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_pointsprite(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state *state = &stateblock->state; - if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) + if (state->render_states[WINED3DRS_POINTSPRITEENABLE]) { static BOOL warned; if (gl_info->limits.point_sprite_units < gl_info->limits.textures && !warned) { - if (use_ps(stateblock) || stateblock->lowest_disabled_stage > gl_info->limits.point_sprite_units) + if (use_ps(state) || state->lowest_disabled_stage > gl_info->limits.point_sprite_units) { FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n"); warned = TRUE; @@ -1608,7 +1613,7 @@ static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_wrap(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { /** http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/ @@ -1618,37 +1623,37 @@ static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w so far as I can tell, wrapping and texture-coordinate generate go hand in hand, */ - TRACE("Stub\n"); - if(stateblock->renderState[WINED3DRS_WRAP0] || - stateblock->renderState[WINED3DRS_WRAP1] || - stateblock->renderState[WINED3DRS_WRAP2] || - stateblock->renderState[WINED3DRS_WRAP3] || - stateblock->renderState[WINED3DRS_WRAP4] || - stateblock->renderState[WINED3DRS_WRAP5] || - stateblock->renderState[WINED3DRS_WRAP6] || - stateblock->renderState[WINED3DRS_WRAP7] || - stateblock->renderState[WINED3DRS_WRAP8] || - stateblock->renderState[WINED3DRS_WRAP9] || - stateblock->renderState[WINED3DRS_WRAP10] || - stateblock->renderState[WINED3DRS_WRAP11] || - stateblock->renderState[WINED3DRS_WRAP12] || - stateblock->renderState[WINED3DRS_WRAP13] || - stateblock->renderState[WINED3DRS_WRAP14] || - stateblock->renderState[WINED3DRS_WRAP15] ) { - FIXME("(WINED3DRS_WRAP0) Texture wrapping not yet supported\n"); + if (stateblock->state.render_states[WINED3DRS_WRAP0] + || stateblock->state.render_states[WINED3DRS_WRAP1] + || stateblock->state.render_states[WINED3DRS_WRAP2] + || stateblock->state.render_states[WINED3DRS_WRAP3] + || stateblock->state.render_states[WINED3DRS_WRAP4] + || stateblock->state.render_states[WINED3DRS_WRAP5] + || stateblock->state.render_states[WINED3DRS_WRAP6] + || stateblock->state.render_states[WINED3DRS_WRAP7] + || stateblock->state.render_states[WINED3DRS_WRAP8] + || stateblock->state.render_states[WINED3DRS_WRAP9] + || stateblock->state.render_states[WINED3DRS_WRAP10] + || stateblock->state.render_states[WINED3DRS_WRAP11] + || stateblock->state.render_states[WINED3DRS_WRAP12] + || stateblock->state.render_states[WINED3DRS_WRAP13] + || stateblock->state.render_states[WINED3DRS_WRAP14] + || stateblock->state.render_states[WINED3DRS_WRAP15]) + { + FIXME("(WINED3DRS_WRAP0) Texture wrapping not yet supported.\n"); } } -static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_msaa_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) { + if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS]) WARN("Multisample antialiasing not supported by gl\n"); - } } -static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_msaa(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) { + if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS]) + { glEnable(GL_MULTISAMPLE_ARB); checkGLcall("glEnable(GL_MULTISAMPLE_ARB)"); } else { @@ -1657,9 +1662,10 @@ static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w } } -static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_scissor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) { + if (stateblock->state.render_states[WINED3DRS_SCISSORTESTENABLE]) + { glEnable(GL_SCISSOR_TEST); checkGLcall("glEnable(GL_SCISSOR_TEST)"); } else { @@ -1674,27 +1680,44 @@ static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struc * convert from D3D to GL we need to divide the D3D depth bias by that value. * There's no practical way to retrieve that value from a given GL * implementation, but the D3D application has essentially the same problem, - * which makes a guess of 1e-6f seem reasonable here. Note that - * SLOPESCALEDEPTHBIAS is a scaling factor for the depth slope, and doesn't - * need to be scaled. */ -static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) + * which makes a guess of the depth buffer format's highest possible value a + * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the + * depth slope, and doesn't need to be scaled. */ +static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if (stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] - || stateblock->renderState[WINED3DRS_DEPTHBIAS]) + if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS] + || stateblock->state.render_states[WINED3DRS_DEPTHBIAS]) { + struct wined3d_surface *depth = stateblock->device->fb.depth_stencil; + float scale; + union { DWORD d; float f; } scale_bias, const_bias; - scale_bias.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS]; - const_bias.d = stateblock->renderState[WINED3DRS_DEPTHBIAS]; + scale_bias.d = stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS]; + const_bias.d = stateblock->state.render_states[WINED3DRS_DEPTHBIAS]; glEnable(GL_POLYGON_OFFSET_FILL); checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)"); - glPolygonOffset(scale_bias.f, const_bias.f * 1e6f); + if (depth) + { + const struct wined3d_format *fmt = depth->resource.format; + scale = powf(2, fmt->depth_size) - 1; + TRACE("Depth format %s, using depthbias scale of %f\n", + debug_d3dformat(fmt->id), scale); + } + else + { + /* The context manager will reapply this state on a depth stencil change */ + TRACE("No depth stencil, using depthbias scale of 0.0\n"); + scale = 0; + } + + glPolygonOffset(scale_bias.f, const_bias.f * scale); checkGLcall("glPolygonOffset(...)"); } else { glDisable(GL_POLYGON_OFFSET_FILL); @@ -1702,9 +1725,16 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, str } } -static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_zvisible(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + if (stateblock->state.render_states[WINED3DRS_ZVISIBLE]) + FIXME("WINED3DRS_ZVISIBLE not implemented.\n"); +} + +static void state_perspective(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) { + if (stateblock->state.render_states[WINED3DRS_TEXTUREPERSPECTIVE]) + { glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)"); } else { @@ -1713,35 +1743,33 @@ static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_stippledalpha(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA]) + if (stateblock->state.render_states[WINED3DRS_STIPPLEDALPHA]) FIXME(" Stippled Alpha not supported yet.\n"); } -static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_antialias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_ANTIALIAS]) - FIXME(" Antialias not supported yet.\n"); + if (stateblock->state.render_states[WINED3DRS_ANTIALIAS]) + FIXME("Antialias not supported yet.\n"); } -static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_multisampmask(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF) - FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]); + if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK] != 0xffffffff) + FIXME("WINED3DRS_MULTISAMPLEMASK %#x not yet implemented.\n", + stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK]); } -static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_patchedgestyle(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE) - FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]); + if (stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE) + FIXME("WINED3DRS_PATCHEDGESTYLE %#x not yet implemented.\n", + stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE]); } -static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_patchsegments(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { union { DWORD d; @@ -1749,12 +1777,11 @@ static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, } tmpvalue; tmpvalue.f = 1.0f; - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d) + if (stateblock->state.render_states[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d) { static BOOL displayed = FALSE; - tmpvalue.d = stateblock->renderState[WINED3DRS_PATCHSEGMENTS]; + tmpvalue.d = stateblock->state.render_states[WINED3DRS_PATCHSEGMENTS]; if(!displayed) FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f); @@ -1762,138 +1789,151 @@ static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, } } -static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_positiondegree(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC) - FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]); + if (stateblock->state.render_states[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC) + FIXME("WINED3DRS_POSITIONDEGREE %#x not yet implemented.\n", + stateblock->state.render_states[WINED3DRS_POSITIONDEGREE]); } -static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_normaldegree(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR) - FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]); + if (stateblock->state.render_states[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR) + FIXME("WINED3DRS_NORMALDEGREE %#x not yet implemented.\n", + stateblock->state.render_states[WINED3DRS_NORMALDEGREE]); } -static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_tessellation(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - TRACE("Stub\n"); - if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]) - FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]); + if (stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION]) + FIXME("WINED3DRS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n", + stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION]); } -static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_nvdb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_WRAPU]) { - FIXME("Render state WINED3DRS_WRAPU not implemented yet\n"); + union { + DWORD d; + float f; + } zmin, zmax; + + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_X] == WINED3DFMT_NVDB) + { + zmin.d = stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_Z]; + zmax.d = stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_W]; + + /* If zmin is larger than zmax INVALID_VALUE error is generated. + * In d3d9 test is not performed in this case*/ + if (zmin.f <= zmax.f) + { + glEnable(GL_DEPTH_BOUNDS_TEST_EXT); + checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)"); + GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f)); + checkGLcall("glDepthBoundsEXT(...)"); + } + else { + glDisable(GL_DEPTH_BOUNDS_TEST_EXT); + checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)"); + } + } + else { + glDisable(GL_DEPTH_BOUNDS_TEST_EXT); + checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)"); } + + state_tessellation(state, stateblock, context); } -static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_wrapu(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_WRAPV]) { - FIXME("Render state WINED3DRS_WRAPV not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_WRAPU]) + FIXME("Render state WINED3DRS_WRAPU not implemented yet.\n"); } -static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_wrapv(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_MONOENABLE]) { - FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_WRAPV]) + FIXME("Render state WINED3DRS_WRAPV not implemented yet.\n"); } -static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_monoenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_ROP2]) { - FIXME("Render state WINED3DRS_ROP2 not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_MONOENABLE]) + FIXME("Render state WINED3DRS_MONOENABLE not implemented yet.\n"); } -static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_rop2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_PLANEMASK]) { - FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_ROP2]) + FIXME("Render state WINED3DRS_ROP2 not implemented yet.\n"); } -static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_planemask(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_SUBPIXEL]) { - FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_PLANEMASK]) + FIXME("Render state WINED3DRS_PLANEMASK not implemented yet.\n"); } -static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_subpixel(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_SUBPIXELX]) { - FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_SUBPIXEL]) + FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet.\n"); } -static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_subpixelx(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) { - FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_SUBPIXELX]) + FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet.\n"); } -static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_stippleenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) { - FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_STIPPLEENABLE]) + FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet.\n"); } -static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_mipmaplodbias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) { - FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_MIPMAPLODBIAS]) + FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet.\n"); } -static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_anisotropy(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_ANISOTROPY]) { - FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_ANISOTROPY]) + FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet.\n"); } -static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_flushbatch(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) { - FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_FLUSHBATCH]) + FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet.\n"); } -static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_translucentsi(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) { - FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) + FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n"); } -static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_extents(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_EXTENTS]) { - FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_EXTENTS]) + FIXME("Render state WINED3DRS_EXTENTS not implemented yet.\n"); } -static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_ckeyblend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) { - FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n"); - } + if (stateblock->state.render_states[WINED3DRS_COLORKEYBLENDENABLE]) + FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet.\n"); } -static void state_swvp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_swvp(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if (stateblock->renderState[WINED3DRS_SOFTWAREVERTEXPROCESSING]) - { + if (stateblock->state.render_states[WINED3DRS_SOFTWAREVERTEXPROCESSING]) FIXME("Software vertex processing not implemented.\n"); - } } /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/ @@ -1944,10 +1984,9 @@ static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* op } /* Setup the texture operations texture stage states */ -static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *iface, +static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) { - const struct wined3d_gl_info *gl_info = context->gl_info; GLenum src1, src2, src3; GLenum opr1, opr2, opr3; GLenum comb_target; @@ -1956,7 +1995,6 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if GLenum scal_target; GLenum opr=0, invopr, src3_target, opr3_target; BOOL Handled = FALSE; - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3); @@ -1996,12 +2034,14 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if /* If a texture stage references an invalid texture unit the stage just * passes through the result from the previous stage */ - if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) { + if (is_invalid_op(state, Stage, op, arg1, arg2, arg3)) + { arg1 = WINED3DTA_CURRENT; op = WINED3DTOP_SELECTARG1; } - if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) { + if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE) + { get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1); } else { get_src_and_opr(arg1, isAlpha, &src1, &opr1); @@ -2942,11 +2982,10 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if { DWORD op2; - if (isAlpha) { - op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP]; - } else { - op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP]; - } + if (isAlpha) + op2 = state->texture_states[Stage][WINED3DTSS_COLOROP]; + else + op2 = state->texture_states[Stage][WINED3DTSS_ALPHAOP]; /* Note: If COMBINE4 in effect can't go back to combine! */ switch (op2) { @@ -2984,17 +3023,18 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if } -static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void tex_colorop(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage); DWORD mapped_stage = stateblock->device->texUnitMap[stage]; const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state *state = &stateblock->state; TRACE("Setting color op for stage %d\n", stage); /* Using a pixel shader? Don't care for anything here, the shader applying does it */ - if (use_ps(stateblock)) return; + if (use_ps(state)) return; if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage); @@ -3009,7 +3049,8 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct checkGLcall("glActiveTextureARB"); } - if(stage >= stateblock->lowest_disabled_stage) { + if (stage >= state->lowest_disabled_stage) + { TRACE("Stage disabled\n"); if (mapped_stage != WINED3D_UNMAPPED_STAGE) { @@ -3033,21 +3074,19 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct return; } - /* The sampler will also activate the correct texture dimensions, so no need to do it here - * if the sampler for this stage is dirty - */ - if(!isStateDirty(context, STATE_SAMPLER(stage))) { - if (tex_used) texture_activate_dimensions(stage, stateblock, context); - } + /* The sampler will also activate the correct texture dimensions, so no + * need to do it here if the sampler for this stage is dirty. */ + if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used) + texture_activate_dimensions(state->textures[stage], gl_info); - set_tex_op(context, (IWineD3DDevice *)stateblock->device, FALSE, stage, - stateblock->textureState[stage][WINED3DTSS_COLOROP], - stateblock->textureState[stage][WINED3DTSS_COLORARG1], - stateblock->textureState[stage][WINED3DTSS_COLORARG2], - stateblock->textureState[stage][WINED3DTSS_COLORARG0]); + set_tex_op(gl_info, state, FALSE, stage, + state->texture_states[stage][WINED3DTSS_COLOROP], + state->texture_states[stage][WINED3DTSS_COLORARG1], + state->texture_states[stage][WINED3DTSS_COLORARG2], + state->texture_states[stage][WINED3DTSS_COLORARG0]); } -void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +void tex_alphaop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage); @@ -3068,22 +3107,21 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d checkGLcall("glActiveTextureARB"); } - op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP]; - arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1]; - arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2]; - arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0]; + op = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAOP]; + arg1 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG1]; + arg2 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG2]; + arg0 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG0]; - if (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && stateblock->textures[0]) + if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && !stage && stateblock->state.textures[0]) { - UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]); + struct wined3d_texture *texture = stateblock->state.textures[0]; + GLenum texture_dimensions = texture->target; if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]); - if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask) + if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask) { /* Color keying needs to pass alpha values from the texture through to have the alpha test work * properly. On the other hand applications can still use texture combiners apparently. This code @@ -3114,7 +3152,7 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d } else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) { - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) + if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE]) { arg2 = WINED3DTA_TEXTURE; op = WINED3DTOP_MODULATE; @@ -3123,7 +3161,7 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d } else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) { - if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) + if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE]) { arg1 = WINED3DTA_TEXTURE; op = WINED3DTOP_MODULATE; @@ -3140,81 +3178,83 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d TRACE("Setting alpha op for stage %d\n", stage); if (gl_info->supported[NV_REGISTER_COMBINERS]) { - set_tex_op_nvrc((IWineD3DDevice *)stateblock->device, TRUE, stage, op, arg1, arg2, arg0, - mapped_stage, stateblock->textureState[stage][WINED3DTSS_RESULTARG]); + set_tex_op_nvrc(gl_info, &stateblock->state, TRUE, stage, op, arg1, arg2, arg0, + mapped_stage, stateblock->state.texture_states[stage][WINED3DTSS_RESULTARG]); } else { - set_tex_op(context, (IWineD3DDevice *)stateblock->device, TRUE, stage, op, arg1, arg2, arg0); + set_tex_op(gl_info, &stateblock->state, TRUE, stage, op, arg1, arg2, arg0); } } -static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void transform_texture(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); DWORD mapped_stage = stateblock->device->texUnitMap[texUnit]; + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state *state = &stateblock->state; BOOL generated; int coordIdx; /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */ - if (use_vs(stateblock) || isStateDirty(context, STATE_VDECL)) + if (use_vs(state) || isStateDirty(context, STATE_VDECL)) { TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n"); return; } if (mapped_stage == WINED3D_UNMAPPED_STAGE) return; - if (mapped_stage >= context->gl_info->limits.textures) return; + if (mapped_stage >= gl_info->limits.textures) return; GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("glActiveTextureARB"); - generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU; - coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1); + generated = (state->texture_states[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; + coordIdx = min(state->texture_states[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000ffff], MAX_TEXTURES - 1); - set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], - stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw, + set_texture_matrix(&state->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], + state->texture_states[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], + generated, context->last_was_rhw, stateblock->device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)) - ? stateblock->device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format + ? stateblock->device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id : WINED3DFMT_UNKNOWN, stateblock->device->frag_pipe->ffp_proj_control); /* The sampler applying function calls us if this changes */ - if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->textures[texUnit]) + if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit]) { if(generated) { FIXME("Non-power2 texture being used with generated texture coords\n"); } /* NP2 texcoord fixup is implemented for pixelshaders so only enable the fixed-function-pipeline fixup via pow2Matrix when no PS is used. */ - if (!use_ps(stateblock)) { + if (!use_ps(state)) + { TRACE("Non power two matrix multiply fixup\n"); - glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix); + glMultMatrixf(state->textures[texUnit]->pow2_matrix); } } } -static void unloadTexCoords(const struct wined3d_context *context) +static void unloadTexCoords(const struct wined3d_gl_info *gl_info) { unsigned int texture_idx; - for (texture_idx = 0; texture_idx < context->gl_info->limits.texture_stages; ++texture_idx) + for (texture_idx = 0; texture_idx < gl_info->limits.texture_stages; ++texture_idx) { GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } -static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock, +static void loadTexCoords(const struct wined3d_gl_info *gl_info, struct wined3d_stateblock *stateblock, const struct wined3d_stream_info *si, GLuint *curVBO) { - const struct wined3d_gl_info *gl_info = context->gl_info; - const UINT *offset = stateblock->streamOffset; unsigned int mapped_stage = 0; unsigned int textureNo = 0; for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo) { - int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX]; + int coordIdx = stateblock->state.texture_states[textureNo][WINED3DTSS_TEXCOORDINDEX]; mapped_stage = stateblock->device->texUnitMap[textureNo]; if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; @@ -3222,6 +3262,7 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))) { const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx]; + const struct wined3d_stream_state *stream = &stateblock->state.streams[e->stream_idx]; TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n", textureNo, mapped_stage, coordIdx, e->data); @@ -3237,8 +3278,8 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl checkGLcall("glClientActiveTextureARB"); /* The coords to supply depend completely on the fvf / vertex shader */ - glTexCoordPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } else { GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1)); @@ -3256,7 +3297,7 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl checkGLcall("loadTexCoords"); } -static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void tex_coordindex(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); DWORD mapped_stage = stateblock->device->texUnitMap[stage]; @@ -3289,7 +3330,7 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up * to the TEXCOORDINDEX value */ - switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000) + switch (stateblock->state.texture_states[stage][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000) { case WINED3DTSS_TCI_PASSTHRU: /* Use the specified texture coordinates contained within the @@ -3403,8 +3444,8 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru break; default: - FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %#x\n", - stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]); + FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %#x.\n", + stateblock->state.texture_states[stage][WINED3DTSS_TEXCOORDINDEX]); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); @@ -3427,14 +3468,15 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru */ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - unloadTexCoords(context); - loadTexCoords(context, stateblock, &stateblock->device->strided_streams, &curVBO); + unloadTexCoords(gl_info); + loadTexCoords(gl_info, stateblock, &stateblock->device->strided_streams, &curVBO); } } -static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void shaderconstant(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->device; + const struct wined3d_state *state = &stateblock->state; + struct wined3d_device *device = stateblock->device; /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them * has an update pending @@ -3444,15 +3486,15 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, stru return; } - device->shader_backend->shader_load_constants(context, use_ps(stateblock), use_vs(stateblock)); + device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state)); } -static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void tex_bumpenvlscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_shader *ps = stateblock->state.pixel_shader; - if (stateblock->pixelShader && stage != 0 - && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.luminanceparams & (1 << stage))) + if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage))) { /* The pixel shader has to know the luminance scale. Do a constants update if it * isn't scheduled anyway @@ -3464,23 +3506,24 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void sampler_texmatrix(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const DWORD sampler = state - STATE_SAMPLER(0); - IWineD3DBaseTexture *texture = stateblock->textures[sampler]; + struct wined3d_texture *texture = stateblock->state.textures[sampler]; TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context); if(!texture) return; /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates - * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the + * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the * scaling is reapplied or removed, the texture matrix has to be reapplied * * The mapped stage is already active because the sampler() function below, which is part of the * misc pipeline */ - if(sampler < MAX_TEXTURES) { - const BOOL texIsPow2 = !((IWineD3DBaseTextureImpl *)texture)->baseTexture.pow2Matrix_identity; + if (sampler < MAX_TEXTURES) + { + const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT); if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler))) { @@ -3492,11 +3535,13 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void sampler(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - DWORD sampler = state - STATE_SAMPLER(0); - DWORD mapped_stage = stateblock->device->texUnitMap[sampler]; + DWORD sampler = state_id - STATE_SAMPLER(0); + struct wined3d_device *device = stateblock->device; + DWORD mapped_stage = device->texUnitMap[sampler]; const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state *state = &stateblock->state; union { float f; DWORD d; @@ -3520,26 +3565,27 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("glActiveTextureARB"); - if(stateblock->textures[sampler]) { - BOOL srgb = stateblock->samplerState[sampler][WINED3DSAMP_SRGBTEXTURE]; - IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler]; - tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB); - IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb); - basetexture_apply_state_changes(stateblock->textures[sampler], - stateblock->textureState[sampler], stateblock->samplerState[sampler], gl_info); + if (state->textures[sampler]) + { + struct wined3d_texture *texture = state->textures[sampler]; + BOOL srgb = state->sampler_states[sampler][WINED3DSAMP_SRGBTEXTURE]; + + texture->texture_ops->texture_bind(texture, gl_info, srgb); + wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info); if (gl_info->supported[EXT_TEXTURE_LOD_BIAS]) { - tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS]; + tmpvalue.d = state->sampler_states[sampler][WINED3DSAMP_MIPMAPLODBIAS]; glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f); - checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)"); + checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)"); } - if (!use_ps(stateblock) && sampler < stateblock->lowest_disabled_stage) + if (!use_ps(state) && sampler < state->lowest_disabled_stage) { - if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) { + if (state->render_states[WINED3DRS_COLORKEYENABLE] && !sampler) + { /* If color keying is enabled update the alpha test, it depends on the existence * of a color key in stage 0 */ @@ -3548,35 +3594,34 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine } /* Trigger shader constant reloading (for NP2 texcoord fixup) */ - if (!tex_impl->baseTexture.pow2Matrix_identity) - { - IWineD3DDeviceImpl *d3ddevice = stateblock->device; - d3ddevice->shader_backend->shader_load_np2fixup_constants( - (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock)); - } + if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) + device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state); } else if (mapped_stage < gl_info->limits.textures) { - if(sampler < stateblock->lowest_disabled_stage) { + if (sampler < state->lowest_disabled_stage) + { /* TODO: What should I do with pixel shaders here ??? */ - if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) { + if (state->render_states[WINED3DRS_COLORKEYENABLE] && !sampler) + { /* If color keying is enabled update the alpha test, it depends on the existence * of a color key in stage 0 */ state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context); } } /* Otherwise tex_colorop disables the stage */ - glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler]); - checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler])"); + glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler]); + checkGLcall("glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler])"); } } -void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +void apply_pixelshader(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->device; - BOOL use_pshader = use_ps(stateblock); - BOOL use_vshader = use_vs(stateblock); - int i; + const struct wined3d_state *state = &stateblock->state; + struct wined3d_device *device = stateblock->device; + BOOL use_vshader = use_vs(state); + BOOL use_pshader = use_ps(state); + unsigned int i; if (use_pshader) { if(!context->last_was_pshader) { @@ -3597,13 +3642,11 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w } } else { /* Disabled the pixel shader - color ops weren't applied - * while it was enabled, so re-apply them. - */ - for(i=0; i < MAX_TEXTURES; i++) { - if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) { - device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply - (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context); - } + * while it was enabled, so re-apply them. */ + for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + { + if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) + stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context); } context->last_was_pshader = FALSE; } @@ -3617,11 +3660,12 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w } } -static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void shader_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - if (stateblock->pixelShader && stage != 0 - && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.bumpmat & (1 << stage))) + const struct wined3d_shader *ps = stateblock->state.pixel_shader; + + if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage))) { /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled * anyway @@ -3633,7 +3677,7 @@ static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void transform_world(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { /* This function is called by transform_view below if the view matrix was changed too * @@ -3652,56 +3696,53 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str /* In the general case, the view matrix is the identity matrix */ if (stateblock->device->view_ident) { - glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); + glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); checkGLcall("glLoadMatrixf"); } else { - glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); + glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]); checkGLcall("glLoadMatrixf"); - glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); + glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); checkGLcall("glMultMatrixf"); } } } -static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void clipplane(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - UINT index = state - STATE_CLIPPLANE(0); + const struct wined3d_state *state = &stateblock->state; + UINT index = state_id - STATE_CLIPPLANE(0); if (isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= context->gl_info->limits.clipplanes) { return; } + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */ - if(!use_vs(stateblock)) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); - } else { + if (!use_vs(state)) + glLoadMatrixf(&state->transforms[WINED3DTS_VIEW].u.m[0][0]); + else /* with vertex shaders, clip planes are not transformed in direct3d, * in OpenGL they are still transformed by the model view. - * Use this to swap the y coordinate if necessary */ - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); glLoadIdentity(); - if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f); - } - TRACE("Clipplane [%f,%f,%f,%f]\n", - stateblock->clipplane[index][0], - stateblock->clipplane[index][1], - stateblock->clipplane[index][2], - stateblock->clipplane[index][3]); - glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]); + TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n", + state->clip_planes[index][0], + state->clip_planes[index][1], + state->clip_planes[index][2], + state->clip_planes[index][3]); + glClipPlane(GL_CLIP_PLANE0 + index, state->clip_planes[index]); checkGLcall("glClipPlane"); glPopMatrix(); } -static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void transform_worldex(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)); GLenum glMat; @@ -3733,41 +3774,34 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s */ if (stateblock->device->view_ident) { - glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]); + glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]); checkGLcall("glLoadMatrixf"); } else { - glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); + glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]); checkGLcall("glLoadMatrixf"); - glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]); + glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]); checkGLcall("glMultMatrixf"); } } -static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_vertexblend_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - static BOOL once = FALSE; + WINED3DVERTEXBLENDFLAGS f = stateblock->state.render_states[WINED3DRS_VERTEXBLEND]; + static unsigned int once; - switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) { - case WINED3DVBF_1WEIGHTS: - case WINED3DVBF_2WEIGHTS: - case WINED3DVBF_3WEIGHTS: - if(!once) { - once = TRUE; - /* TODO: Implement vertex blending in drawStridedSlow */ - FIXME("Vertex blending enabled, but not supported by hardware\n"); - } - break; + if (f == WINED3DVBF_DISABLE) return; - case WINED3DVBF_TWEENING: - WARN("Tweening not supported yet\n"); - } + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f); + else WARN("Vertex blend flags %#x not supported.\n", f); } -static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void state_vertexblend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND]; + WINED3DVERTEXBLENDFLAGS val = stateblock->state.render_states[WINED3DRS_VERTEXBLEND]; + const struct wined3d_gl_info *gl_info = context->gl_info; + static unsigned int once; switch(val) { case WINED3DVBF_1WEIGHTS: @@ -3779,12 +3813,12 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context * creation with enabling GL_WEIGHT_SUM_UNITY_ARB. */ - GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1)); + GL_EXTCALL(glVertexBlendARB(stateblock->state.render_states[WINED3DRS_VERTEXBLEND] + 1)); if (!stateblock->device->vertexBlendUsed) { unsigned int i; - for (i = 1; i < context->gl_info->limits.blends; ++i) + for (i = 1; i < gl_info->limits.blends; ++i) { if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) { @@ -3795,23 +3829,19 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s } break; + case WINED3DVBF_TWEENING: + case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */ + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val); + else WARN("Vertex blend flags %#x not supported.\n", val); + /* Fall through. */ case WINED3DVBF_DISABLE: - case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */ glDisable(GL_VERTEX_BLEND_ARB); checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)"); break; - - case WINED3DVBF_TWEENING: - /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have - * vertex weights in the vertices? - * For now we don't report that as supported, so a warn should suffice - */ - WARN("Tweening not supported yet\n"); - break; } } -static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void transform_view(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_light_info *light = NULL; @@ -3825,13 +3855,13 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru glMatrixMode(GL_MODELVIEW); checkGLcall("glMatrixMode(GL_MODELVIEW)"); - glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); + glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]); checkGLcall("glLoadMatrixf(...)"); /* Reset lights. TODO: Call light apply func */ - for (k = 0; k < stateblock->device->maxConcurrentLights; ++k) + for (k = 0; k < gl_info->limits.lights; ++k) { - light = stateblock->activeLights[k]; + light = stateblock->state.lights[k]; if(!light) continue; glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn); checkGLcall("glLightfv posn"); @@ -3873,75 +3903,27 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru } } -static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void transform_projection(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { glMatrixMode(GL_PROJECTION); checkGLcall("glMatrixMode(GL_PROJECTION)"); glLoadIdentity(); checkGLcall("glLoadIdentity"); - if(context->last_was_rhw) { - double X, Y, height, width, minZ, maxZ; - - X = stateblock->viewport.X; - Y = stateblock->viewport.Y; - height = stateblock->viewport.Height; - width = stateblock->viewport.Width; - minZ = stateblock->viewport.MinZ; - maxZ = stateblock->viewport.MaxZ; + if (context->last_was_rhw) + { + double x = stateblock->state.viewport.X; + double y = stateblock->state.viewport.Y; + double w = stateblock->state.viewport.Width; + double h = stateblock->state.viewport.Height; - if (!stateblock->device->untransformed) - { - /* 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. 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 (context->render_offscreen) - { - glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ); - } else { - glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ); - } - } else { - /* If the app mixes transformed and untransformed primitives we can't use the coordinate system - * trick above because this would mess up transformed and untransformed Z order. Pass the z position - * unmodified to opengl. - * - * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline - * replacement shader. - */ - TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0); - if (context->render_offscreen) - { - glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0); - } else { - glOrtho(X, X + width, Y + height, Y, 0.0, -1.0); - } - } + TRACE("Calling glOrtho with x %.8e, y %.8e, w %.8e, h %.8e.\n", x, y, w, h); + if (context->render_offscreen) + glOrtho(x, x + w, -y, -y - h, 0.0, -1.0); + else + glOrtho(x, x + w, y + h, y, 0.0, -1.0); checkGLcall("glOrtho"); - /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */ - glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f); - checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)"); - /* D3D texture coordinates are flipped compared to OpenGL ones, so * render everything upside down when rendering offscreen. */ if (context->render_offscreen) @@ -3949,7 +3931,13 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock glScalef(1.0f, -1.0f, 1.0f); checkGLcall("glScalef"); } - } else { + + /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */ + glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f); + checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)"); + } + else + { /* The rule is that the window coordinate 0 does not correspond to the beginning of the first pixel, but the center of the first pixel. As a consequence if you want to correctly draw one line exactly from @@ -3991,8 +3979,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock * filling convention. We want the difference to be large enough that * it doesn't get lost due to rounding inside the driver, but small * enough to prevent it from interfering with any anti-aliasing. */ - GLfloat xoffset = (63.0f / 64.0f) / stateblock->viewport.Width; - GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height; + GLfloat xoffset = (63.0f / 64.0f) / stateblock->state.viewport.Width; + GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height; if (context->render_offscreen) { @@ -4008,7 +3996,7 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock } checkGLcall("glScalef"); - glMultMatrixf(&stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]); + glMultMatrixf(&stateblock->state.transforms[WINED3DTS_PROJECTION].u.m[0][0]); checkGLcall("glLoadMatrixf"); } } @@ -4016,10 +4004,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock /* This should match any arrays loaded in loadVertexData. * TODO: Only load / unload arrays if we have to. */ -static inline void unloadVertexData(const struct wined3d_context *context) +static inline void unloadVertexData(const struct wined3d_gl_info *gl_info) { - const struct wined3d_gl_info *gl_info = context->gl_info; - glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); @@ -4031,11 +4017,13 @@ static inline void unloadVertexData(const struct wined3d_context *context) { glDisableClientState(GL_WEIGHT_ARRAY_ARB); } - unloadTexCoords(context); + unloadTexCoords(gl_info); } -static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i) +static inline void unload_numbered_array(struct wined3d_context *context, int i) { + const struct wined3d_gl_info *gl_info = context->gl_info; + GL_EXTCALL(glDisableVertexAttribArrayARB(i)); checkGLcall("glDisableVertexAttribArrayARB(reg)"); @@ -4045,7 +4033,7 @@ static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, str /* This should match any arrays loaded in loadNumberedArrays * TODO: Only load / unload arrays if we have to. */ -static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static inline void unloadNumberedArrays(struct wined3d_context *context) { /* disable any attribs (this is the same for both GLSL and ARB modes) */ GLint maxAttribs = 16; @@ -4057,34 +4045,37 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, stru if (glGetError() != GL_NO_ERROR) maxAttribs = 16; for (i = 0; i < maxAttribs; ++i) { - unload_numbered_array(stateblock, context, i); + unload_numbered_array(context, i); } } -static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, +static void loadNumberedArrays(struct wined3d_stateblock *stateblock, const struct wined3d_stream_info *stream_info, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; int i; - const UINT *offset = stateblock->streamOffset; struct wined3d_buffer *vb; - DWORD_PTR shift_index; /* Default to no instancing */ stateblock->device->instancedDraw = FALSE; - for (i = 0; i < MAX_ATTRIBS; i++) { + for (i = 0; i < MAX_ATTRIBS; i++) + { + const struct wined3d_stream_state *stream; + if (!(stream_info->use_map & (1 << i))) { - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); continue; } + stream = &stateblock->state.streams[stream_info->elements[i].stream_idx]; + /* Do not load instance data. It will be specified using glTexCoord by drawprim */ - if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA) + if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) { - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); stateblock->device->instancedDraw = TRUE; continue; } @@ -4099,56 +4090,40 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, checkGLcall("glBindBufferARB"); curVBO = stream_info->elements[i].buffer_object; } - vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; - /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a - * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no - * vbo we won't be load converted attributes anyway - */ - if (curVBO && vb->conversion_shift) - { - TRACE("Loading attribute from shifted buffer\n"); - TRACE("Attrib %d has original stride %d, new stride %d\n", - i, stream_info->elements[i].stride, vb->conversion_stride); - TRACE("Original offset %p, additional offset 0x%08x\n", - stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]); - TRACE("Opengl type %#x\n", stream_info->elements[i].format_desc->gl_vtx_type); - shift_index = ((DWORD_PTR)stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx]); - shift_index = shift_index % stream_info->elements[i].stride; - GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format_desc->gl_vtx_format, - stream_info->elements[i].format_desc->gl_vtx_type, - stream_info->elements[i].format_desc->gl_normalized, - vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index] - + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride - + offset[stream_info->elements[i].stream_idx])); - - } else { - GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format_desc->gl_vtx_format, - stream_info->elements[i].format_desc->gl_vtx_type, - stream_info->elements[i].format_desc->gl_normalized, - stream_info->elements[i].stride, stream_info->elements[i].data - + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride - + offset[stream_info->elements[i].stream_idx])); - } + /* Use the VBO to find out if a vertex buffer exists, not the vb + * pointer. vb can point to a user pointer data blob. In that case + * curVBO will be 0. If there is a vertex buffer but no vbo we + * won't be load converted attributes anyway. */ + vb = stream->buffer; + GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format, + stream_info->elements[i].format->gl_vtx_type, + stream_info->elements[i].format->gl_normalized, + stream_info->elements[i].stride, stream_info->elements[i].data + + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride + + stream->offset)); if (!(context->numbered_array_mask & (1 << i))) { GL_EXTCALL(glEnableVertexAttribArrayARB(i)); context->numbered_array_mask |= (1 << i); } - } else { - /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and - * set up the attribute statically. But we have to figure out the system memory address. - */ - const BYTE *ptr = stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx]; + } + else + { + /* Stride = 0 means always the same values. + * glVertexAttribPointerARB doesn't do that. Instead disable the + * pointer and set up the attribute statically. But we have to + * figure out the system memory address. */ + const BYTE *ptr = stream_info->elements[i].data + stream->offset; if (stream_info->elements[i].buffer_object) { - vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; - ptr += (long) buffer_get_sysmem(vb); + vb = stream->buffer; + ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info); } - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); - switch (stream_info->elements[i].format_desc->format) + switch (stream_info->elements[i].format->id) { case WINED3DFMT_R32_FLOAT: GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr)); @@ -4167,7 +4142,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr)); break; case WINED3DFMT_B8G8R8A8_UNORM: - if (gl_info->supported[EXT_VERTEX_ARRAY_BGRA]) + if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) { const DWORD *src = (const DWORD *)ptr; DWORD c = *src & 0xff00ff00; @@ -4237,13 +4212,13 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, } /* Used from 2 different functions, and too big to justify making it inlined */ -static void loadVertexData(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock, +static void loadVertexData(const struct wined3d_context *context, struct wined3d_stateblock *stateblock, const struct wined3d_stream_info *si) { const struct wined3d_gl_info *gl_info = context->gl_info; - const UINT *offset = stateblock->streamOffset; GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; const struct wined3d_stream_info_element *e; + const struct wined3d_stream_state *stream; TRACE("Using fast vertex array code\n"); @@ -4255,21 +4230,17 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB || si->use_map & (1 << WINED3D_FFP_BLENDINDICES)) { e = &si->elements[WINED3D_FFP_BLENDWEIGHT]; + stream = &stateblock->state.streams[e->stream_idx]; if (gl_info->supported[ARB_VERTEX_BLEND]) { - TRACE("Blend %d %p %d\n", e->format_desc->component_count, - e->data + stateblock->loadBaseVertexIndex * e->stride, e->stride + offset[e->stream_idx]); + TRACE("Blend %u %p %u\n", e->format->component_count, + e->data + stateblock->state.load_base_vertex_index * e->stride, e->stride + stream->offset); glEnableClientState(GL_WEIGHT_ARRAY_ARB); checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)"); - GL_EXTCALL(glVertexBlendARB(e->format_desc->component_count + 1)); - - VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n", - WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) , - sd->u.s.blendWeights.dwStride, - sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo])); + GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1)); if (curVBO != e->buffer_object) { @@ -4278,8 +4249,13 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB curVBO = e->buffer_object; } - GL_EXTCALL(glWeightPointerARB)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n", + e->format->gl_vtx_format, + e->format->gl_vtx_type, + e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset)); checkGLcall("glWeightPointerARB"); @@ -4305,7 +4281,7 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB { static const GLbyte one = 1; GL_EXTCALL(glWeightbvARB(1, &one)); - checkGLcall("glWeightivARB(gl_info->max_blends, weights)"); + checkGLcall("glWeightbvARB(gl_info->max_blends, weights)"); } } @@ -4320,9 +4296,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB /* Vertex Pointers -----------------------------------------*/ if (si->use_map & (1 << WINED3D_FFP_POSITION)) { - VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data)); - e = &si->elements[WINED3D_FFP_POSITION]; + stream = &stateblock->state.streams[e->stream_idx]; + if (curVBO != e->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); @@ -4340,11 +4316,18 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB */ if (!e->buffer_object) { - glVertexPointer(3 /* min(e->format_desc->gl_vtx_format, 3) */, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); - } else { - glVertexPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + glVertexPointer(3 /* min(e->format->gl_vtx_format, 3) */, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + } + else + { + TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", + e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); } checkGLcall("glVertexPointer(...)"); glEnableClientState(GL_VERTEX_ARRAY); @@ -4354,17 +4337,20 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB /* Normals -------------------------------------------------*/ if (si->use_map & (1 << WINED3D_FFP_NORMAL)) { - VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data)); - e = &si->elements[WINED3D_FFP_NORMAL]; + stream = &stateblock->state.streams[e->stream_idx]; + if (curVBO != e->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); curVBO = e->buffer_object; } - glNormalPointer(e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + + TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + glNormalPointer(e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); checkGLcall("glNormalPointer(...)"); glEnableClientState(GL_NORMAL_ARRAY); checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); @@ -4385,9 +4371,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB if (si->use_map & (1 << WINED3D_FFP_DIFFUSE)) { - VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); - e = &si->elements[WINED3D_FFP_DIFFUSE]; + stream = &stateblock->state.streams[e->stream_idx]; + if (curVBO != e->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); @@ -4395,8 +4381,11 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB curVBO = e->buffer_object; } - glColorPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glColorPointer(%#x, %#x %#x, %p);\n", + e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); glEnableClientState(GL_COLOR_ARRAY); checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); @@ -4410,13 +4399,14 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB if (si->use_map & (1 << WINED3D_FFP_SPECULAR)) { TRACE("setting specular colour\n"); - VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); e = &si->elements[WINED3D_FFP_SPECULAR]; + stream = &stateblock->state.streams[e->stream_idx]; + if (gl_info->supported[EXT_SECONDARY_COLOR]) { - GLenum type = e->format_desc->gl_vtx_type; - GLint format = e->format_desc->gl_vtx_format; + GLenum type = e->format->gl_vtx_type; + GLint format = e->format->gl_vtx_format; if (curVBO != e->buffer_object) { @@ -4432,8 +4422,10 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts * 4 component secondary colors use it */ - GL_EXTCALL(glSecondaryColorPointerEXT)(format, type, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset)); checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); } else @@ -4441,25 +4433,29 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB switch(type) { case GL_UNSIGNED_BYTE: - GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset)); checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); break; default: FIXME("Add 4 component specular color pointers for type %x\n", type); /* Make sure that the right color component is dropped */ - GL_EXTCALL(glSecondaryColorPointerEXT)(3, type, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset); + GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, + e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset)); checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); } } glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - } else { - - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); } } else @@ -4468,145 +4464,64 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB { GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); - } else { - - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); } } /* Texture coords -------------------------------------------*/ - loadTexCoords(context, stateblock, si, &curVBO); -} - -static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations) -{ - /* Dump out what parts we have supplied */ - TRACE("Strided Data:\n"); - TRACE_STRIDED((dataLocations), WINED3D_FFP_POSITION); - TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDWEIGHT); - TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDINDICES); - TRACE_STRIDED((dataLocations), WINED3D_FFP_NORMAL); - TRACE_STRIDED((dataLocations), WINED3D_FFP_PSIZE); - TRACE_STRIDED((dataLocations), WINED3D_FFP_DIFFUSE); - TRACE_STRIDED((dataLocations), WINED3D_FFP_SPECULAR); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD0); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD1); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD2); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD3); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD4); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD5); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD6); - TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD7); + loadTexCoords(gl_info, stateblock, si, &curVBO); } -static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void streamsrc(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = context->gl_info; - IWineD3DDeviceImpl *device = stateblock->device; - BOOL fixup = FALSE; - struct wined3d_stream_info *dataLocations = &device->strided_streams; - BOOL useVertexShaderFunction; - BOOL load_numbered = FALSE; - BOOL load_named = FALSE; - - useVertexShaderFunction = (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader) ? TRUE : FALSE; - - if(device->up_strided) { - /* Note: this is a ddraw fixed-function code path */ - TRACE("================ Strided Input ===================\n"); - device_stream_info_from_strided(gl_info, device->up_strided, dataLocations); - - if(TRACE_ON(d3d)) { - drawPrimitiveTraceDataLocations(dataLocations); - } - } else { - /* Note: This is a fixed function or shader codepath. - * This means it must handle both types of strided data. - * Shaders must go through here to zero the strided data, even if they - * don't set any declaration at all - */ - TRACE("================ Vertex Declaration ===================\n"); - device_stream_info_from_declaration(device, useVertexShaderFunction, dataLocations, &fixup); - } - - if (dataLocations->position_transformed) useVertexShaderFunction = FALSE; - - if(useVertexShaderFunction) { - if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) { - TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion\n"); - device->useDrawStridedSlow = TRUE; - } else { - load_numbered = TRUE; - device->useDrawStridedSlow = FALSE; - } - } - else - { - WORD slow_mask = (1 << WINED3D_FFP_PSIZE); - slow_mask |= -!gl_info->supported[EXT_VERTEX_ARRAY_BGRA] - & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR)); - - if (fixup || (!dataLocations->position_transformed - && !(dataLocations->use_map & slow_mask))) - { - /* Load the vertex data using named arrays */ - load_named = TRUE; - device->useDrawStridedSlow = FALSE; - } - else - { - TRACE("Not loading vertex data\n"); - device->useDrawStridedSlow = TRUE; - } - } + struct wined3d_device *device = stateblock->device; + BOOL load_numbered = use_vs(&stateblock->state) && !device->useDrawStridedSlow; + BOOL load_named = !use_vs(&stateblock->state) && !device->useDrawStridedSlow; if (context->numberedArraysLoaded && !load_numbered) { - unloadNumberedArrays(stateblock, context); + unloadNumberedArrays(context); context->numberedArraysLoaded = FALSE; context->numbered_array_mask = 0; } else if (context->namedArraysLoaded) { - unloadVertexData(context); + unloadVertexData(context->gl_info); context->namedArraysLoaded = FALSE; } if (load_numbered) { TRACE("Loading numbered arrays\n"); - loadNumberedArrays(stateblock, dataLocations, context); + loadNumberedArrays(stateblock, &device->strided_streams, context); context->numberedArraysLoaded = TRUE; } else if (load_named) { TRACE("Loading vertex data\n"); - loadVertexData(context, stateblock, dataLocations); + loadVertexData(context, stateblock, &device->strided_streams); context->namedArraysLoaded = TRUE; } } -static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void vertexdeclaration(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_state *state = &stateblock->state; + struct wined3d_device *device = stateblock->device; + BOOL useVertexShaderFunction = use_vs(state); + BOOL usePixelShaderFunction = use_ps(state); BOOL updateFog = FALSE; - BOOL useVertexShaderFunction = use_vs(stateblock); - BOOL usePixelShaderFunction = use_ps(stateblock); - IWineD3DDeviceImpl *device = stateblock->device; BOOL transformed; BOOL wasrhw = context->last_was_rhw; unsigned int i; transformed = device->strided_streams.position_transformed; - if(transformed != context->last_was_rhw && !useVertexShaderFunction) { + if (transformed != context->last_was_rhw && !useVertexShaderFunction) updateFog = TRUE; - } - - /* Reapply lighting if it is not scheduled for reapplication already */ - if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) { - state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context); - } if (transformed) { context->last_was_rhw = TRUE; @@ -4616,20 +4531,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s context->last_was_rhw = FALSE; /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/ device->untransformed = TRUE; - - /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices - * Not needed as long as only hw shaders are supported - */ - - /* This sets the shader output position correction constants. - * TODO: Move to the viewport state - */ - if (useVertexShaderFunction) - { - GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height; - device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f; - device->posFixup[3] = device->posFixup[1] * yoffset; - } } /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned @@ -4664,6 +4565,9 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) { state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context); } + if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) { + state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context); + } if(context->last_was_vshader) { updateFog = TRUE; @@ -4691,7 +4595,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s checkGLcall("glDisable(GL_CLIP_PLANE0 + i)"); } - if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) { + if (!warned && stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE]) + { FIXME("Clipping not supported with vertex shaders\n"); warned = TRUE; } @@ -4735,9 +4640,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s context->last_was_vshader = useVertexShaderFunction; - if(updateFog) { - device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context); - } + if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context); + if(!useVertexShaderFunction) { int i; for(i = 0; i < MAX_TEXTURES; i++) { @@ -4748,14 +4652,16 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void viewport_miscpart(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + struct wined3d_surface *target = stateblock->device->fb.render_targets[0]; UINT width, height; - WINED3DVIEWPORT vp = stateblock->viewport; + WINED3DVIEWPORT vp = stateblock->state.viewport; - if(vp.Width > target->currentDesc.Width) vp.Width = target->currentDesc.Width; - if(vp.Height > target->currentDesc.Height) vp.Height = target->currentDesc.Height; + if (vp.Width > target->resource.width) + vp.Width = target->resource.width; + if (vp.Height > target->resource.height) + vp.Height = target->resource.height; glDepthRange(vp.MinZ, vp.MaxZ); checkGLcall("glDepthRange"); @@ -4775,25 +4681,23 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, s checkGLcall("glViewport"); } -static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void viewport_vertexpart(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height; - - stateblock->device->posFixup[2] = (63.0f / 64.0f) / stateblock->viewport.Width; - stateblock->device->posFixup[3] = stateblock->device->posFixup[1] * yoffset; - 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); } + /* Update the position fixup. */ + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) + shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context); } -static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void light(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { UINT Index = state - STATE_ACTIVELIGHT(0); - const struct wined3d_light_info *lightInfo = stateblock->activeLights[Index]; + const struct wined3d_light_info *lightInfo = stateblock->state.lights[Index]; if(!lightInfo) { glDisable(GL_LIGHT0 + Index); @@ -4805,7 +4709,7 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/ glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); + glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]); /* Diffuse: */ colRGBA[0] = lightInfo->OriginalParms.Diffuse.r; @@ -4904,10 +4808,10 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3 } } -static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void scissorrect(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; - RECT *pRect = &stateblock->scissorRect; + struct wined3d_surface *target = stateblock->device->fb.render_targets[0]; + RECT *pRect = &stateblock->state.scissor_rect; UINT height; UINT width; @@ -4927,17 +4831,22 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct checkGLcall("glScissor"); } -static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void indexbuffer(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { - if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) { + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (stateblock->state.user_stream || !stateblock->state.index_buffer) + { GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); - } else { - struct wined3d_buffer *ib = (struct wined3d_buffer *) stateblock->pIndexData; + } + else + { + struct wined3d_buffer *ib = stateblock->state.index_buffer; GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object)); } } -static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void frontface(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { if (context->render_offscreen) { @@ -4949,77 +4858,109 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi } } +static void psorigin_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + static BOOL warned; + + if (!warned) + { + WARN("Point sprite coordinate origin switching not supported.\n"); + warned = TRUE; + } +} + +static void psorigin(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT; + + if (glPointParameteri) + { + glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin); + checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)"); + } + else if (gl_info->supported[NV_POINT_SPRITE]) + { + GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin)); + checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)"); + } +} + const struct StateEntryTemplate misc_state_template[] = { - { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_STREAMSRC, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, + { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 }, + { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE }, + /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and * vshader loadings are untied from each other */ { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE }, - { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE }, + { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT }, + { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE }, @@ -5033,9 +4974,9 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE }, @@ -5043,42 +4984,41 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_SUBPIXEL), { STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SUBPIXELX), { STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ZBIAS), { STATE_RENDER(WINED3DRS_ZBIAS), state_zbias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STIPPLEENABLE), { STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ANISOTROPY), { STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE }, { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE }, @@ -5086,28 +5026,34 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_nvdb }, EXT_DEPTH_BOUNDS_TEST }, { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX }, { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR }, { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, /* Samplers */ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE }, @@ -5134,8 +5080,8 @@ const struct StateEntryTemplate misc_state_template[] = { const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_VSHADER, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, + { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, /* Clip planes */ { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE }, @@ -5184,14 +5130,14 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { /* Transform states follow */ { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE }, @@ -5466,159 +5412,161 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE }, /* Fog */ { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE }, { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND }, { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE }, { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE }, + /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported, * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states. * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix */ { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(0), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(1), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(2), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(3), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(4), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(5), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(6), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, - { STATE_SAMPLER(7), { 0, NULL }, WINE_NORMALIZED_TEXRECT }, + { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT }, { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_BORDERCOLOR), { STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -5629,53 +5577,52 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; -#undef GLINFO_LOCATION -/* Context activation is done by the caller. */ -static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { } +/* Context activation and GL locking are done by the caller. */ +static void ffp_enable(BOOL enable) {} -static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, - const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps) +static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) { - pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD | - WINED3DTEXOPCAPS_ADDSIGNED | - WINED3DTEXOPCAPS_ADDSIGNED2X | - WINED3DTEXOPCAPS_MODULATE | - WINED3DTEXOPCAPS_MODULATE2X | - WINED3DTEXOPCAPS_MODULATE4X | - WINED3DTEXOPCAPS_SELECTARG1 | - WINED3DTEXOPCAPS_SELECTARG2 | - WINED3DTEXOPCAPS_DISABLE; + caps->PrimitiveMiscCaps = 0; + caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD + | WINED3DTEXOPCAPS_ADDSIGNED + | WINED3DTEXOPCAPS_ADDSIGNED2X + | WINED3DTEXOPCAPS_MODULATE + | WINED3DTEXOPCAPS_MODULATE2X + | WINED3DTEXOPCAPS_MODULATE4X + | WINED3DTEXOPCAPS_SELECTARG1 + | WINED3DTEXOPCAPS_SELECTARG2 + | WINED3DTEXOPCAPS_DISABLE; if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE] || gl_info->supported[EXT_TEXTURE_ENV_COMBINE] || gl_info->supported[NV_TEXTURE_ENV_COMBINE4]) { - pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA | - WINED3DTEXOPCAPS_BLENDTEXTUREALPHA | - WINED3DTEXOPCAPS_BLENDFACTORALPHA | - WINED3DTEXOPCAPS_BLENDCURRENTALPHA | - WINED3DTEXOPCAPS_LERP | - WINED3DTEXOPCAPS_SUBTRACT; + caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA + | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA + | WINED3DTEXOPCAPS_BLENDFACTORALPHA + | WINED3DTEXOPCAPS_BLENDCURRENTALPHA + | WINED3DTEXOPCAPS_LERP + | WINED3DTEXOPCAPS_SUBTRACT; } if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3] || gl_info->supported[NV_TEXTURE_ENV_COMBINE4]) { - pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH | - WINED3DTEXOPCAPS_MULTIPLYADD | - WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | - WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | - WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM; + caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH + | WINED3DTEXOPCAPS_MULTIPLYADD + | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR + | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA + | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM; } if (gl_info->supported[ARB_TEXTURE_ENV_DOT3]) - pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3; + caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3; - pCaps->MaxTextureBlendStages = gl_info->limits.texture_stages; - pCaps->MaxSimultaneousTextures = gl_info->limits.textures; + caps->MaxTextureBlendStages = gl_info->limits.textures; + caps->MaxSimultaneousTextures = gl_info->limits.textures; } -static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } -static void ffp_fragment_free(IWineD3DDevice *iface) {} +static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; } +static void ffp_fragment_free(struct wined3d_device *device) {} static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup) { if (TRACE_ON(d3d)) @@ -5712,19 +5659,132 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs) return i; } -static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void multistate_apply_2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { stateblock->device->multistate_funcs[state][0](state, stateblock, context); stateblock->device->multistate_funcs[state][1](state, stateblock, context); } -static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static void multistate_apply_3(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context) { stateblock->device->multistate_funcs[state][0](state, stateblock, context); stateblock->device->multistate_funcs[state][1](state, stateblock, context); stateblock->device->multistate_funcs[state][2](state, stateblock, context); } +static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info) +{ + unsigned int start, last, i; + + start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0); + last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE); + for (i = start; i <= last; ++i) + { + state_table[i].representative = 0; + state_table[i].apply = state_undefined; + } + + start = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + gl_info->limits.texture_stages); + last = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + MAX_TEXTURES - 1); + for (i = start; i <= last; ++i) + { + state_table[i].representative = 0; + state_table[i].apply = state_undefined; + } + + start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends)); + last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)); + for (i = start; i <= last; ++i) + { + state_table[i].representative = 0; + state_table[i].apply = state_undefined; + } +} + +static void validate_state_table(struct StateEntry *state_table) +{ + static const struct + { + DWORD first; + DWORD last; + } + rs_holes[] = + { + { 1, 1}, + { 3, 3}, + { 17, 18}, + { 21, 21}, + { 42, 45}, + { 47, 47}, + { 61, 127}, + {149, 150}, + {169, 169}, + {177, 177}, + {196, 197}, + { 0, 0}, + }; + static const DWORD simple_states[] = + { + STATE_MATERIAL, + STATE_VDECL, + STATE_STREAMSRC, + STATE_INDEXBUFFER, + STATE_VERTEXSHADERCONSTANT, + STATE_PIXELSHADERCONSTANT, + STATE_VSHADER, + STATE_PIXELSHADER, + STATE_VIEWPORT, + STATE_SCISSORRECT, + STATE_FRONTFACE, + STATE_POINTSPRITECOORDORIGIN, + }; + unsigned int i, current; + + for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i) + { + if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first)) + { + if (!state_table[i].representative) + ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i); + } + else if (state_table[i].representative) + ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i); + + if (i == STATE_RENDER(rs_holes[current].last)) ++current; + } + + for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i) + { + if (!state_table[simple_states[i]].representative) + ERR("State %s (%#x) should have a representative.\n", + debug_d3dstate(simple_states[i]), simple_states[i]); + } + + for (i = 0; i < STATE_HIGHEST + 1; ++i) + { + DWORD rep = state_table[i].representative; + if (rep) + { + if (state_table[rep].representative != rep) + { + ERR("State %s (%#x) has invalid representative %s (%#x).\n", + debug_d3dstate(i), i, debug_d3dstate(rep), rep); + state_table[i].representative = 0; + } + + if (rep != i) + { + if (state_table[i].apply) + ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i); + } + else if (!state_table[i].apply) + { + ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i); + } + } + } +} + HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs, const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex, const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) @@ -5777,7 +5837,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ * applying later lines, but do not record anything in the state * table */ - if(!cur[i].content.apply) continue; + if (!cur[i].content.representative) continue; handlers = num_handlers(multistate_funcs[cur[i].state]); multistate_funcs[cur[i].state][handlers] = cur[i].content.apply; @@ -5824,6 +5884,9 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ } } + prune_invalid_states(StateTable, gl_info); + validate_state_table(StateTable); + return WINED3D_OK; out_of_mem: