diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index d6ca4a87739..b044f31e1e8 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -468,7 +468,7 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, break; case WINED3DSPR_CONST: if(param & WINED3DSHADER_ADDRMODE_RELATIVE) { - if(reg - This->rel_offset >= 0) { + if(reg >= This->rel_offset) { sprintf(tmpReg, "C[A0.x + %u]", reg - This->rel_offset); } else { sprintf(tmpReg, "C[A0.x - %u]", -reg + This->rel_offset); @@ -1723,10 +1723,14 @@ static void shader_arb_cleanup(IWineD3DDevice *iface) { if (GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) glDisable(GL_FRAGMENT_PROGRAM_ARB); } +static void shader_arb_destroy(IWineD3DBaseShader *iface) { +} + const shader_backend_t arb_program_shader_backend = { &shader_arb_select, &shader_arb_select_depth_blt, &shader_arb_load_constants, &shader_arb_cleanup, - &shader_arb_color_correction + &shader_arb_color_correction, + &shader_arb_destroy }; diff --git a/reactos/dll/directx/wine/wined3d/baseshader.c b/reactos/dll/directx/wine/wined3d/baseshader.c index 520554fd289..638db902f08 100644 --- a/reactos/dll/directx/wine/wined3d/baseshader.c +++ b/reactos/dll/directx/wine/wined3d/baseshader.c @@ -447,12 +447,16 @@ HRESULT shader_get_registers_used( else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader) reg_maps->vpos = 1; - else if(WINED3DSPR_CONST == regtype && !pshader && - param & WINED3DSHADER_ADDRMODE_RELATIVE) { - if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) { - ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg; - } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) { - ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg; + else if(WINED3DSPR_CONST == regtype) { + if(param & WINED3DSHADER_ADDRMODE_RELATIVE) { + if(!pshader) { + if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) { + ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg; + } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) { + ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg; + } + } + reg_maps->usesrelconstF = TRUE; } } } @@ -1058,7 +1062,7 @@ void shader_trace_init( } } -void shader_delete_constant_list( +static void shader_delete_constant_list( struct list* clist) { struct list *ptr; @@ -1076,10 +1080,56 @@ static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {} static void shader_none_select_depth_blt(IWineD3DDevice *iface) {} static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {} static void shader_none_cleanup(IWineD3DDevice *iface) {} +static void shader_none_color_correction(SHADER_OPCODE_ARG* arg) {} +static void shader_none_destroy(IWineD3DBaseShader *iface) {} const shader_backend_t none_shader_backend = { &shader_none_select, &shader_none_select_depth_blt, &shader_none_load_constants, - &shader_none_cleanup + &shader_none_cleanup, + &shader_none_color_correction, + &shader_none_destroy }; + +/* ******************************************* + IWineD3DPixelShader IUnknown parts follow + ******************************************* */ +HRESULT WINAPI IWineD3DBaseShaderImpl_QueryInterface(IWineD3DBaseShader *iface, REFIID riid, LPVOID *ppobj) +{ + IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface; + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IWineD3DBase) + || IsEqualGUID(riid, &IID_IWineD3DBaseShader) + || IsEqualGUID(riid, &IID_IWineD3DPixelShader)) { + IUnknown_AddRef(iface); + *ppobj = This; + return S_OK; + } + *ppobj = NULL; + return E_NOINTERFACE; +} + +ULONG WINAPI IWineD3DBaseShaderImpl_AddRef(IWineD3DBaseShader *iface) { + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; + TRACE("(%p) : AddRef increasing from %d\n", This, This->baseShader.ref); + return InterlockedIncrement(&This->baseShader.ref); +} + +ULONG WINAPI IWineD3DBaseShaderImpl_Release(IWineD3DBaseShader *iface) { + IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface; + IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device; + ULONG ref; + TRACE("(%p) : Releasing from %d\n", This, This->baseShader.ref); + ref = InterlockedDecrement(&This->baseShader.ref); + if (ref == 0) { + deviceImpl->shader_backend->shader_destroy(iface); + HeapFree(GetProcessHeap(), 0, This->baseShader.function); + shader_delete_constant_list(&This->baseShader.constantsF); + shader_delete_constant_list(&This->baseShader.constantsB); + shader_delete_constant_list(&This->baseShader.constantsI); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index 8311ab5be9d..32d75b60835 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -860,10 +860,17 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU /* Activate the opengl context */ if(context != This->activeContext) { BOOL ret; - TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx); - ret = pwglMakeCurrent(context->hdc, context->glCtx); - if(ret == FALSE) { - ERR("Failed to activate the new context\n"); + + /* Prevent an unneeded context switch as those are expensive */ + if(context->glCtx && (context->glCtx == pwglGetCurrentContext())) { + TRACE("Already using gl context %p\n", context->glCtx); + } + else { + TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx); + ret = pwglMakeCurrent(context->hdc, context->glCtx); + if(ret == FALSE) { + ERR("Failed to activate the new context\n"); + } } This->activeContext = context; } diff --git a/reactos/dll/directx/wine/wined3d/cubetexture.c b/reactos/dll/directx/wine/wined3d/cubetexture.c index 3cb44e62e8a..e2d90999489 100644 --- a/reactos/dll/directx/wine/wined3d/cubetexture.c +++ b/reactos/dll/directx/wine/wined3d/cubetexture.c @@ -230,40 +230,8 @@ static UINT WINAPI IWineD3DCubeTextureImpl_GetTextureDimensions(IWineD3DCubeText static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface, const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) { - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - float matrix[16]; + TRACE("(%p) : relay to BaseTexture\n", iface); IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates); - - - /* Apply non-power2 mappings and texture offsets so long as the texture coords aren't projected or generated */ - if(This->pow2scalingFactor != 1.0f) { - if((textureStates[WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) == WINED3DTSS_TCI_PASSTHRU && - (~textureStates[WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) { - - glMatrixMode(GL_TEXTURE); - memset(matrix, 0 , sizeof(matrix)); - - matrix[0] = This->pow2scalingFactor; - matrix[5] = This->pow2scalingFactor; - matrix[10] = This->pow2scalingFactor; -#if 0 /* Translation fixup is no longer required (here for reminder) */ - matrix[12] = -0.25f / (float)This->edgeLength; - matrix[13] = -0.75f / (float)This->edgeLength; - matrix[14] = -0.25f / (float)This->edgeLength; -#endif - TRACE("(%p) Setup Matrix:\n", This); - TRACE(" %f %f %f %f\n", matrix[0], matrix[1], matrix[2], matrix[3]); - TRACE(" %f %f %f %f\n", matrix[4], matrix[5], matrix[6], matrix[7]); - TRACE(" %f %f %f %f\n", matrix[8], matrix[9], matrix[10], matrix[11]); - TRACE(" %f %f %f %f\n", matrix[12], matrix[13], matrix[14], matrix[15]); - TRACE("\n"); - glMultMatrixf(matrix); - } else { - /* I don't expect nonpower 2 textures to be used with generated texture coordinates, but if they are present a fixme. */ - FIXME("Non-power2 texture being used with generated texture coords\n"); - } - } - } diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index ef6a0eaa411..30ac0b79d41 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -71,8 +71,8 @@ static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3 object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \ D3DMEMCHECK(object, pp##type); \ object->lpVtbl = &IWineD3D##type##_Vtbl; \ - object->parent = parent; \ - object->ref = 1; \ + object->parent = parent; \ + object->baseShader.ref = 1; \ object->baseShader.device = (IWineD3DDevice*) This; \ list_init(&object->baseShader.linked_programs); \ *pp##type = (IWineD3D##type *) object; \ @@ -179,9 +179,9 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { /* NOTE: You must release the parent if the object was created via a callback ** ***************************/ - if (This->resources != NULL ) { + if (!list_empty(&This->resources)) { FIXME("(%p) Device released with resources still bound, acceptable but unexpected\n", This); - dumpResources(This->resources); + dumpResources(&This->resources); } if(This->contexts) ERR("Context array not freed!\n"); @@ -880,9 +880,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U /** FIXME: add support for real non-power-two if it's provided by the video card **/ /* Precalculated scaling for 'faked' non power of two texture coords */ - object->pow2scalingFactorX = (((float)Width) / ((float)pow2Width)); - object->pow2scalingFactorY = (((float)Height) / ((float)pow2Height)); - TRACE(" xf(%f) yf(%f)\n", object->pow2scalingFactorX, object->pow2scalingFactorY); + object->baseTexture.pow2Matrix[0] = (((float)Width) / ((float)pow2Width)); + object->baseTexture.pow2Matrix[5] = (((float)Height) / ((float)pow2Height)); + object->baseTexture.pow2Matrix[10] = 1.0; + object->baseTexture.pow2Matrix[15] = 1.0; + TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], object->baseTexture.pow2Matrix[5]); /* Calculate levels for mip mapping */ if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) { @@ -976,6 +978,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa object->height = Height; object->depth = Depth; + /* Is NP2 support for volumes needed? */ + object->baseTexture.pow2Matrix[ 0] = 1.0; + object->baseTexture.pow2Matrix[ 5] = 1.0; + object->baseTexture.pow2Matrix[10] = 1.0; + object->baseTexture.pow2Matrix[15] = 1.0; + /* Calculate levels for mip mapping */ if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) { if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) { @@ -1112,7 +1120,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface object->edgeLength = EdgeLength; /* TODO: support for native non-power 2 */ /* Precalculated scaling for 'faked' non power of two texture coords */ - object->pow2scalingFactor = ((float)EdgeLength) / ((float)pow2EdgeLength); + object->baseTexture.pow2Matrix[ 0] = ((float)EdgeLength) / ((float)pow2EdgeLength); + object->baseTexture.pow2Matrix[ 5] = ((float)EdgeLength) / ((float)pow2EdgeLength); + object->baseTexture.pow2Matrix[10] = ((float)EdgeLength) / ((float)pow2EdgeLength); + object->baseTexture.pow2Matrix[15] = 1.0; /* Calculate levels for mip mapping */ if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) { @@ -1578,7 +1589,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic /* Under directX swapchains share the depth stencil, so only create one depth-stencil */ if (pPresentationParameters->EnableAutoDepthStencil && hr == WINED3D_OK) { TRACE("Creating depth stencil buffer\n"); - if (This->depthStencilBuffer == NULL ) { + if (This->auto_depth_stencil_buffer == NULL ) { hr = D3DCB_CreateDepthStencil((IUnknown *) This->parent, parent, object->presentParms.BackBufferWidth, @@ -1587,10 +1598,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic object->presentParms.MultiSampleType, object->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, - &This->depthStencilBuffer, + &This->auto_depth_stencil_buffer, NULL /* pShared (always null)*/ ); - if (This->depthStencilBuffer != NULL) - IWineD3DSurface_SetContainer(This->depthStencilBuffer, 0); + if (This->auto_depth_stencil_buffer != NULL) + IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0); } /** TODO: A check on width, height and multisample types @@ -2054,7 +2065,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR This->lastThread = GetCurrentThreadId(); /* Depth Stencil support */ - This->stencilBufferTarget = This->depthStencilBuffer; + This->stencilBufferTarget = This->auto_depth_stencil_buffer; if (NULL != This->stencilBufferTarget) { IWineD3DSurface_AddRef(This->stencilBufferTarget); } @@ -2206,8 +2217,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D /* Release the buffers (with sanity checks)*/ TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); if(This->stencilBufferTarget != NULL && (IWineD3DSurface_Release(This->stencilBufferTarget) >0)){ - if(This->depthStencilBuffer != This->stencilBufferTarget) - FIXME("(%p) Something's still holding the depthStencilBuffer\n",This); + if(This->auto_depth_stencil_buffer != This->stencilBufferTarget) + FIXME("(%p) Something's still holding the stencilBufferTarget\n",This); } This->stencilBufferTarget = NULL; @@ -2218,11 +2229,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D TRACE("Setting rendertarget to NULL\n"); This->render_targets[0] = NULL; - if (This->depthStencilBuffer) { - if(D3DCB_DestroyDepthStencilSurface(This->depthStencilBuffer) > 0) { - FIXME("(%p) Something's still holding the depthStencilBuffer\n", This); + if (This->auto_depth_stencil_buffer) { + if(D3DCB_DestroyDepthStencilSurface(This->auto_depth_stencil_buffer) > 0) { + FIXME("(%p) Something's still holding the auto depth stencil buffer\n", This); } - This->depthStencilBuffer = NULL; + This->auto_depth_stencil_buffer = NULL; } for(i=0; i < This->NumberOfSwapChains; i++) { @@ -6045,7 +6056,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice* iface, IWineD3DSurface **ppZStencilSurface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *ppZStencilSurface = This->depthStencilBuffer; + *ppZStencilSurface = This->stencilBufferTarget; TRACE("(%p) : zStencilSurface returning %p\n", This, *ppZStencilSurface); if(*ppZStencilSurface != NULL) { @@ -6387,7 +6398,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice * HRESULT hr = WINED3D_OK; IWineD3DSurface *tmp; - TRACE("(%p) Swapping z-buffer\n",This); + TRACE("(%p) Swapping z-buffer. Old = %p, new = %p\n",This, This->stencilBufferTarget, pNewZStencil); if (pNewZStencil == This->stencilBufferTarget) { TRACE("Trying to do a NOP SetRenderTarget operation\n"); @@ -6611,18 +6622,18 @@ static BOOL WINAPI IWineD3DDeviceImpl_ShowCursor(IWineD3DDevice* iface, BOO static HRESULT WINAPI IWineD3DDeviceImpl_TestCooperativeLevel(IWineD3DDevice* iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + IWineD3DResourceImpl *resource; TRACE("(%p) : state (%u)\n", This, This->state); + /* TODO: Implement wrapping of the WndProc so that mimimize and maxamise can be monitored and the states adjusted. */ switch (This->state) { case WINED3D_OK: return WINED3D_OK; case WINED3DERR_DEVICELOST: { - ResourceList *resourceList = This->resources; - while (NULL != resourceList) { - if (((IWineD3DResourceImpl *)resourceList->resource)->resource.pool == WINED3DPOOL_DEFAULT /* TODO: IWineD3DResource_GetPool(resourceList->resource)*/) - return WINED3DERR_DEVICENOTRESET; - resourceList = resourceList->next; + LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry) { + if (resource->resource.pool == WINED3DPOOL_DEFAULT) + return WINED3DERR_DEVICENOTRESET; } return WINED3DERR_DEVICELOST; } @@ -6865,51 +6876,17 @@ static void WINAPI IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice *iface, UINT i *****************************************************/ static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource){ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - ResourceList* resourceList; - TRACE("(%p) : resource %p\n", This, resource); - /* add a new texture to the frot of the linked list */ - resourceList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ResourceList)); - resourceList->resource = resource; - - /* Get the old head */ - resourceList->next = This->resources; - - This->resources = resourceList; - TRACE("Added resource %p with element %p pointing to %p\n", resource, resourceList, resourceList->next); - - return; + TRACE("(%p) : Adding Resource %p\n", This, resource); + list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry); } static void WINAPI IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWineD3DResource *resource){ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - ResourceList* resourceList = NULL; - ResourceList* previousResourceList = NULL; - - TRACE("(%p) : resource %p\n", This, resource); - resourceList = This->resources; + TRACE("(%p) : Removing resource %p\n", This, resource); - while (resourceList != NULL) { - if(resourceList->resource == resource) break; - previousResourceList = resourceList; - resourceList = resourceList->next; - } - - if (resourceList == NULL) { - FIXME("Attempted to remove resource %p that hasn't been stored\n", resource); - return; - } else { - TRACE("Found resource %p with element %p pointing to %p (previous %p)\n", resourceList->resource, resourceList, resourceList->next, previousResourceList); - } - /* make sure we don't leave a hole in the list */ - if (previousResourceList != NULL) { - previousResourceList->next = resourceList->next; - } else { - This->resources = resourceList->next; - } - - return; + list_remove(&((IWineD3DResourceImpl *) resource)->resource.resource_list_entry); } diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index 9bfb52ea31e..f106321b445 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -40,89 +40,91 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); static const struct { const char *extension_string; GL_SupportedExt extension; + DWORD version; } EXTENSION_MAP[] = { /* APPLE */ - {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE}, - {"GL_APPLE_fence", APPLE_FENCE}, - {"GL_APPLE_flush_render", APPLE_FLUSH_RENDER}, - {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422}, + {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE, 0 }, + {"GL_APPLE_fence", APPLE_FENCE, 0 }, + {"GL_APPLE_flush_render", APPLE_FLUSH_RENDER, 0 }, + {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422, 0 }, /* ATI */ - {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL}, - {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3}, - {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE}, - {"GL_ATI_envmap_bumpmap", ATI_ENVMAP_BUMPMAP}, + {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL, 0 }, + {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3, 0 }, + {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 }, + {"GL_ATI_envmap_bumpmap", ATI_ENVMAP_BUMPMAP, 0 }, /* ARB */ - {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS}, - {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM}, - {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER}, - {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL}, - {"GL_ARB_imaging", ARB_IMAGING}, - {"GL_ARB_multisample", ARB_MULTISAMPLE}, /* needs GLX_ARB_MULTISAMPLE as well */ - {"GL_ARB_multitexture", ARB_MULTITEXTURE}, - {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY}, - {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT}, - {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS}, - {"GL_ARB_point_sprite", ARB_POINT_SPRITE}, - {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP}, - {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION}, - {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP}, - {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD}, - {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE}, - {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3}, - {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT}, - {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT}, - {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO}, - {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND}, - {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT}, - {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM}, - {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER}, + {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS, 0 }, + {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM, 0 }, + {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER, 0 }, + {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL, 0 }, + {"GL_ARB_imaging", ARB_IMAGING, 0 }, + {"GL_ARB_multisample", ARB_MULTISAMPLE, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */ + {"GL_ARB_multitexture", ARB_MULTITEXTURE, 0 }, + {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY, 0 }, + {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT, 0 }, + {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS, 0 }, + {"GL_ARB_point_sprite", ARB_POINT_SPRITE, 0 }, + {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 }, + {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 }, + {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP, 0 }, + {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD, 0 }, + {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE, 0 }, + {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3, 0 }, + {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT, 0 }, + {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT, 0 }, + {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, 0 }, + {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 }, + {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 }, + {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 }, + {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 }, + {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 }, /* EXT */ - {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX}, - {"GL_EXT_fog_coord", EXT_FOG_COORD}, - {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT}, - {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT}, - {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE}, - {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS}, - {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR}, - {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE}, - {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP}, - {"GL_EXT_texture3D", EXT_TEXTURE3D}, - {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC}, - {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD}, - {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE}, - {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3}, - {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB}, - {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC}, - {"GL_EXT_texture_lod", EXT_TEXTURE_LOD}, - {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS}, - {"GL_EXT_vertex_shader", EXT_VERTEX_SHADER}, - {"GL_EXT_vertex_weighting", EXT_VERTEX_WEIGHTING}, + {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 }, + {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 }, + {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 }, + {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT, 0 }, + {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE, 0 }, + {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS, 0 }, + {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR, 0 }, + {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE, 0 }, + {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 }, + {"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) }, + {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 }, + {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 }, + {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 }, + {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 }, + {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB, 0 }, + {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 }, + {"GL_EXT_texture_lod", EXT_TEXTURE_LOD, 0 }, + {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 }, + {"GL_EXT_vertex_shader", EXT_VERTEX_SHADER, 0 }, + {"GL_EXT_vertex_weighting", EXT_VERTEX_WEIGHTING, 0 }, /* NV */ - {"GL_NV_half_float", NV_HALF_FLOAT}, - {"GL_NV_fence", NV_FENCE}, - {"GL_NV_fog_distance", NV_FOG_DISTANCE}, - {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM}, - {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2}, - {"GL_NV_register_combiners", NV_REGISTER_COMBINERS}, - {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2}, - {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION}, - {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4}, - {"GL_NV_texture_shader", NV_TEXTURE_SHADER}, - {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2}, - {"GL_NV_texture_shader3", NV_TEXTURE_SHADER3}, - {"GL_NV_occlusion_query", NV_OCCLUSION_QUERY}, - {"GL_NV_vertex_program", NV_VERTEX_PROGRAM}, - {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1}, - {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2}, - {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3}, - {"GL_NV_depth_clamp", NV_DEPTH_CLAMP}, + {"GL_NV_half_float", NV_HALF_FLOAT, 0 }, + {"GL_NV_fence", NV_FENCE, 0 }, + {"GL_NV_fog_distance", NV_FOG_DISTANCE, 0 }, + {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM, 0 }, + {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2, 0 }, + {"GL_NV_register_combiners", NV_REGISTER_COMBINERS, 0 }, + {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2, 0 }, + {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION, 0 }, + {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4, 0 }, + {"GL_NV_texture_shader", NV_TEXTURE_SHADER, 0 }, + {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2, 0 }, + {"GL_NV_texture_shader3", NV_TEXTURE_SHADER3, 0 }, + {"GL_NV_occlusion_query", NV_OCCLUSION_QUERY, 0 }, + {"GL_NV_vertex_program", NV_VERTEX_PROGRAM, 0 }, + {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1, 0 }, + {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2, 0 }, + {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3, 0 }, + {"GL_NV_depth_clamp", NV_DEPTH_CLAMP, 0 }, /* SGI */ - {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP}, + {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP, 0 }, }; /********************************************************** @@ -441,6 +443,17 @@ static inline BOOL test_arb_vs_offset_limit(WineD3D_GL_Info *gl_info) { return ret; } +static DWORD ver_for_ext(GL_SupportedExt ext) +{ + unsigned int i; + for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) { + if(EXTENSION_MAP[i].extension == ext) { + return EXTENSION_MAP[i].version; + } + } + return 0; +} + BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { const char *GL_Extensions = NULL; const char *WGL_Extensions = NULL; @@ -623,12 +636,6 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { gl_info->vs_arb_constantsF = 0; gl_info->ps_arb_constantsF = 0; -/* Now work out what GL support this card really has */ -#define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) pwglGetProcAddress(#pfn); - GL_EXT_FUNCS_GEN; - WGL_EXT_FUNCS_GEN; -#undef USE_GL_FUNC - /* Retrieve opengl defaults */ glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max); gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max); @@ -685,6 +692,31 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { } } } + /* Now work out what GL support this card really has */ +#define USE_GL_FUNC(type, pfn, ext, replace) { \ + DWORD ver = ver_for_ext(ext); \ + if(gl_info->supported[ext]) gl_info->pfn = (type) pwglGetProcAddress(#pfn); \ + else if(ver && ver <= gl_info->gl_driver_version) gl_info->pfn = (type) pwglGetProcAddress(#replace); \ + else gl_info->pfn = NULL; \ + } + GL_EXT_FUNCS_GEN; +#undef USE_GL_FUNC + +#define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type) pwglGetProcAddress(#pfn); + WGL_EXT_FUNCS_GEN; +#undef USE_GL_FUNC + + /* Now mark all the extensions supported which are included in the opengl core version. Do this *after* + * loading the functions, otherwise the code above will load the extension entry points instead of the + * core functions, which may not work + */ + for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) { + if (gl_info->supported[EXTENSION_MAP[i].extension] == FALSE && + EXTENSION_MAP[i].version <= gl_info->gl_driver_version && EXTENSION_MAP[i].version) { + TRACE_(d3d_caps)(" GL CORE: %s support\n", EXTENSION_MAP[i].extension_string); + gl_info->supported[EXTENSION_MAP[i].extension] = TRUE; + } + } if (gl_info->supported[APPLE_FENCE]) { /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically. @@ -726,7 +758,7 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { GLint tmp; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp); - gl_info->max_fragment_samplers = min(8, tmp); + gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp); } else { gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max); } @@ -1070,9 +1102,10 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { } else if(WINE_D3D7_CAPABLE(gl_info)) { gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */ vidmem = 32; /* There are models with up to 64MB */ - } else + } else { gl_info->gl_card = CARD_ATI_RAGE_128PRO; vidmem = 16; /* There are 16-32MB models */ + } break; case VENDOR_INTEL: if (strstr(gl_info->gl_renderer, "915GM")) { @@ -2662,6 +2695,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, object->adapter = numAdapters ? &Adapters[Adapter] : NULL; IWineD3D_AddRef(object->wineD3D); object->parent = parent; + list_init(&object->resources); if(This->dxVersion == 7) { object->surface_alignment = 8; @@ -2825,10 +2859,7 @@ BOOL InitAdapters(void) { #else #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn); /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */ - - /* ReactOS hack, we do not have wglGetProcAddress implement in gdi32.dll yet, */ mod_gl = GetModuleHandleA("opengl32.dll"); - #endif } diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index c6cb9da96d4..64ed0386bd2 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -630,7 +630,7 @@ static void depth_blt(IWineD3DDevice *iface, GLuint texture) { static void depth_copy(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *)This->depthStencilBuffer; + IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer; /* Only copy the depth buffer if there is one. */ if (!depth_stencil) return; diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index 73fb0f69774..d9e525bb5aa 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -199,6 +199,11 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL } checkGLcall("glUniform4fvARB()"); + if(!This->baseShader.load_local_constsF) { + TRACE("No need to load local float constants for this shader\n"); + return; + } + /* Load immediate constants */ if (TRACE_ON(d3d_shader)) { LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { @@ -288,7 +293,7 @@ static void shader_glsl_load_constantsB( for (i=0; ibaseShader.device; int i; unsigned int extra_constants_needed = 0; + local_constant* lconst; /* There are some minor differences between pixel and vertex shaders */ char pshader = shader_is_pshader_version(This->baseShader.hex_version); @@ -527,9 +533,9 @@ void shader_generate_glsl_declarations( extra_constants_needed++; } else { ps_impl->srgb_mode_hardcoded = 1; - shader_addline(buffer, "const vec4 srgb_mul_low = {%f, %f, %f, %f};\n", + shader_addline(buffer, "const vec4 srgb_mul_low = vec4(%f, %f, %f, %f);\n", srgb_mul_low, srgb_mul_low, srgb_mul_low, srgb_mul_low); - shader_addline(buffer, "const vec4 srgb_comparison = {%f, %f, %f, %f};\n", + shader_addline(buffer, "const vec4 srgb_comparison = vec4(%f, %f, %f, %f);\n", srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp); } } else { @@ -551,7 +557,7 @@ void shader_generate_glsl_declarations( * actually used, only the max limit of the shader version */ FIXME("Cannot find a free uniform for vpos correction params\n"); - shader_addline(buffer, "const vec4 ycorrection = {%f, %f, 0.0, 0.0};\n", + shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n", device->render_offscreen ? 0.0 : ((IWineD3DSurfaceImpl *) device->render_targets[0])->currentDesc.Height, device->render_offscreen ? 1.0 : -1.0); } @@ -640,6 +646,15 @@ void shader_generate_glsl_declarations( shader_addline(buffer, "vec4 tmp0;\n"); shader_addline(buffer, "vec4 tmp1;\n"); + /* Hardcodeable local constants */ + if(!This->baseShader.load_local_constsF) { + LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { + float *value = (float *) lconst->value; + shader_addline(buffer, "const vec4 LC%u = vec4(%f, %f, %f, %f);\n", lconst->idx, + value[0], value[1], value[2], value[3]); + } + } + /* Start the main program */ shader_addline(buffer, "void main() {\n"); if(pshader && reg_maps->vpos) { @@ -734,6 +749,17 @@ static void shader_glsl_gen_modifier ( } } +static BOOL constant_is_local(IWineD3DBaseShaderImpl* This, DWORD reg) { + local_constant* lconst; + + if(This->baseShader.load_local_constsF) return FALSE; + LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { + if(lconst->idx == reg) return TRUE; + } + return FALSE; + +} + /** Writes the GLSL variable name that corresponds to the register that the * DX opcode parameter is trying to access */ static void shader_glsl_get_register_name( @@ -819,8 +845,13 @@ static void shader_glsl_get_register_name( } } - } else - sprintf(tmpStr, "%s[%u]", prefix, reg); + } else { + if(constant_is_local(This, reg)) { + sprintf(tmpStr, "LC%u", reg); + } else { + sprintf(tmpStr, "%s[%u]", prefix, reg); + } + } break; } @@ -1532,9 +1563,17 @@ void shader_glsl_compare(SHADER_OPCODE_ARG* arg) { } else { switch(arg->opcode->opcode) { case WINED3DSIO_SLT: - shader_addline(arg->buffer, "step(%s, %s));\n", src0_param.param_str, src1_param.param_str); + /* Step(src0, src1) is not suitable here because if src0 == src1 SLT is supposed, + * to return 0.0 but step returns 1.0 because step is not < x + * An alternative is a bvec compare padded with an unused secound component. + * step(src1 * -1.0, src0 * -1.0) is not an option because it suffers from the same + * issue. Playing with not() is not possible either because not() does not accept + * a scalar. + */ + shader_addline(arg->buffer, "(%s < %s) ? 1.0 : 0.0);\n", src0_param.param_str, src1_param.param_str); break; case WINED3DSIO_SGE: + /* Here we can use the step() function and safe a conditional */ shader_addline(arg->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str); break; default: @@ -3137,10 +3176,44 @@ static void shader_glsl_cleanup(IWineD3DDevice *iface) { GL_EXTCALL(glUseProgramObjectARB(0)); } +static void shader_glsl_destroy(IWineD3DBaseShader *iface) { + struct list *linked_programs; + IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface; + WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info; + + /* Note: Do not use QueryInterface here to find out which shader type this is because this code + * can be called from IWineD3DBaseShader::Release + */ + char pshader = shader_is_pshader_version(This->baseShader.hex_version); + + if(This->baseShader.prgId == 0) return; + linked_programs = &This->baseShader.linked_programs; + + TRACE("Deleting linked programs\n"); + if (linked_programs->next) { + struct glsl_shader_prog_link *entry, *entry2; + + if(pshader) { + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) { + delete_glsl_program_entry(This->baseShader.device, entry); + } + } else { + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, vshader_entry) { + delete_glsl_program_entry(This->baseShader.device, entry); + } + } + } + + TRACE("Deleting shader object %u\n", This->baseShader.prgId); + GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId)); + checkGLcall("glDeleteObjectARB"); +} + const shader_backend_t glsl_shader_backend = { &shader_glsl_select, &shader_glsl_select_depth_blt, &shader_glsl_load_constants, &shader_glsl_cleanup, - &shader_glsl_color_correction + &shader_glsl_color_correction, + &shader_glsl_destroy }; diff --git a/reactos/dll/directx/wine/wined3d/palette.c b/reactos/dll/directx/wine/wined3d/palette.c index a1dcc9f95f7..506b4fe0630 100644 --- a/reactos/dll/directx/wine/wined3d/palette.c +++ b/reactos/dll/directx/wine/wined3d/palette.c @@ -107,7 +107,7 @@ static HRESULT WINAPI IWineD3DPaletteImpl_GetEntries(IWineD3DPalette *iface, DW static HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt) { IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface; - ResourceList *res; + IWineD3DResourceImpl *res; TRACE("(%p)->(%08x,%d,%d,%p)\n",This,Flags,Start,Count,PalEnt); @@ -134,11 +134,11 @@ static HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, DW /* If the palette is attached to the render target, update all render targets */ - for(res = This->wineD3DDevice->resources; res != NULL; res=res->next) { - if(IWineD3DResource_GetType(res->resource) == WINED3DRTYPE_SURFACE) { - IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res->resource; + LIST_FOR_EACH_ENTRY(res, &This->wineD3DDevice->resources, IWineD3DResourceImpl, resource.resource_list_entry) { + if(IWineD3DResource_GetType((IWineD3DResource *) res) == WINED3DRTYPE_SURFACE) { + IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res; if(impl->palette == This) - IWineD3DSurface_RealizePalette( (IWineD3DSurface *) res->resource); + IWineD3DSurface_RealizePalette((IWineD3DSurface *) res); } } diff --git a/reactos/dll/directx/wine/wined3d/pixelshader.c b/reactos/dll/directx/wine/wined3d/pixelshader.c index 62a9fe6af28..b9fbd75482d 100644 --- a/reactos/dll/directx/wine/wined3d/pixelshader.c +++ b/reactos/dll/directx/wine/wined3d/pixelshader.c @@ -42,62 +42,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); #endif #define GLNAME_REQUIRE_GLSL ((const char *)1) -/* ******************************************* - IWineD3DPixelShader IUnknown parts follow - ******************************************* */ -static HRESULT WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) -{ - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; - TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); - if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IWineD3DBase) - || IsEqualGUID(riid, &IID_IWineD3DBaseShader) - || IsEqualGUID(riid, &IID_IWineD3DPixelShader)) { - IUnknown_AddRef(iface); - *ppobj = This; - return S_OK; - } - *ppobj = NULL; - return E_NOINTERFACE; + +static HRESULT WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) { + return IWineD3DBaseShaderImpl_QueryInterface((IWineD3DBaseShader *) iface, riid, ppobj); } static ULONG WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; - TRACE("(%p) : AddRef increasing from %d\n", This, This->ref); - return InterlockedIncrement(&This->ref); -} - -static void destroy_glsl_pshader(IWineD3DPixelShaderImpl *This) { - struct list *linked_programs = &This->baseShader.linked_programs; - - TRACE("Deleting linked programs\n"); - if (linked_programs->next) { - struct glsl_shader_prog_link *entry, *entry2; - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) { - delete_glsl_program_entry(This->baseShader.device, entry); - } - } - - TRACE("Deleting shader object %u\n", This->baseShader.prgId); - GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId)); - checkGLcall("glDeleteObjectARB"); + return IWineD3DBaseShaderImpl_AddRef((IWineD3DBaseShader *) iface); } static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; - ULONG ref; - TRACE("(%p) : Releasing from %d\n", This, This->ref); - ref = InterlockedDecrement(&This->ref); - if (ref == 0) { - if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) { - destroy_glsl_pshader(This); - } - shader_delete_constant_list(&This->baseShader.constantsF); - shader_delete_constant_list(&This->baseShader.constantsB); - shader_delete_constant_list(&This->baseShader.constantsI); - HeapFree(GetProcessHeap(), 0, This); - } - return ref; + return IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface); } /* ******************************************* @@ -586,6 +541,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i } } } + This->baseShader.load_local_constsF = FALSE; This->baseShader.shader_mode = deviceImpl->ps_selected_mode; @@ -675,9 +631,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader This->baseShader.recompile_count++; } - if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) { - destroy_glsl_pshader(This); - } + deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface); } /* We don't need to compile */ diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index 9faaea575b8..151af2c2838 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -248,12 +248,11 @@ HRESULT WINAPI IWineD3DResourceImpl_GetParent(IWineD3DResource *iface, IUnknown return WINED3D_OK; } -void dumpResources(ResourceList *resources) { - ResourceList *iterator = resources; +void dumpResources(struct list *list) { + IWineD3DResourceImpl *resource; - while(iterator) { - FIXME("Leftover resource %p with type %d,%s\n", iterator->resource, IWineD3DResource_GetType(iterator->resource), debug_d3dresourcetype(IWineD3DResource_GetType(iterator->resource))); - iterator = iterator->next; + LIST_FOR_EACH_ENTRY(resource, list, IWineD3DResourceImpl, resource.resource_list_entry) { + FIXME("Leftover resource %p with type %d,%s\n", resource, IWineD3DResource_GetType((IWineD3DResource *) resource), debug_d3dresourcetype(IWineD3DResource_GetType((IWineD3DResource *) resource))); } } diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 251e77f93bb..d5bf9924daf 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -107,6 +107,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { /* No z test without depth stencil buffers */ if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) { + TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ checkGLcall("glDisable GL_DEPTH_TEST"); return; @@ -1903,6 +1904,7 @@ static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0); DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit]; + BOOL generated; /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */ if(use_vs(stateblock->wineD3DDevice) || @@ -1924,15 +1926,24 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); return; } + generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU; set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], - (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU, + generated, context->last_was_rhw, stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ? stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType: WINED3DDECLTYPE_UNUSED); + /* The sampler applying function calls us if this changes */ + if(context->lastWasPow2Texture[texUnit] && stateblock->textures[texUnit]) { + if(generated) { + FIXME("Non-power2 texture being used with generated texture coords\n"); + } + TRACE("Non power two matrix multiply fixup\n"); + glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix); + } } static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) { @@ -2288,19 +2299,19 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont */ if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) { if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) { - if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 || - ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) { + if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[0] != 1.0 || + ((IWineD3DTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[5] != 1.0 ) { texIsPow2 = TRUE; } } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) { - if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) { + if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[0] != 1.0) { texIsPow2 = TRUE; } } if(texIsPow2 || context->lastWasPow2Texture[sampler]) { - transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context); context->lastWasPow2Texture[sampler] = texIsPow2; + transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context); } } @@ -3425,6 +3436,19 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W FIXME("Clipping not supported with vertex shaders\n"); warned = TRUE; } + if(wasrhw) { + /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex + * shaders themselves do not need it it, but the matrices are not reapplied automatically when + * switching back from vertex shaders to fixed function processing. So make sure we leave the + * fixed function vertex processing states back in a sane state before switching to shaders + */ + if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) { + transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context); + } + if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) { + transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context); + } + } } } @@ -3597,12 +3621,15 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex } static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) stateblock->wineD3DDevice->swapchains[0]; RECT *pRect = &stateblock->scissorRect; RECT windowRect; UINT winHeight; - GetClientRect(swapchain->win_handle, &windowRect); + windowRect.left = 0; + windowRect.top = 0; + windowRect.right = ((IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0])->currentDesc.Width; + windowRect.bottom = ((IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height; + /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply * Warning2: Even in windowed mode the coords are relative to the window, not the screen */ diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index 758606afaff..e0a40aff094 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -1055,7 +1055,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat TRACE("Render states\n"); /* Render states: */ - if (ThisDevice->depthStencilBuffer != NULL) { + if (ThisDevice->auto_depth_stencil_buffer != NULL) { IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_TRUE); } else { IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_FALSE); diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index d3cbc527bcb..df617dd1f45 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -57,7 +57,7 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { checkGLcall("glActiveTextureARB"); } IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(0)); - IWineD3DSurface_PreLoad((IWineD3DSurface *) This); + IWineD3DSurface_BindTexture((IWineD3DSurface *) This); if (This->resource.format == WINED3DFMT_DXT1 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || @@ -2186,6 +2186,30 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO return WINED3D_OK; } +static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) { + /* TODO: check for locks */ + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + IWineD3DBaseTexture *baseTexture = NULL; + IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + + TRACE("(%p)Checking to see if the container is a base texture\n", This); + if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { + TRACE("Passing to container\n"); + IWineD3DBaseTexture_BindTexture(baseTexture); + IWineD3DBaseTexture_Release(baseTexture); + } else { + TRACE("(%p) : Binding surface\n", This); + + if(!device->isInDraw) { + ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); + } + ENTER_GL(); + glBindTexture(This->glDescription.target, This->glDescription.textureName); + LEAVE_GL(); + } + return; +} + #include #include HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const char* filename) { @@ -3131,6 +3155,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * checkGLcall("glDisable(GL_ALPHA_TEST)"); } + /* Flush in case the drawable is used by multiple GL contexts */ + if(dstSwapchain && (dstSwapchain->num_contexts >= 2)) + glFlush(); + /* Unbind the texture */ glBindTexture(GL_TEXTURE_2D, 0); checkGLcall("glEnable glBindTexture"); @@ -3481,6 +3509,8 @@ struct coords { static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) { struct coords coords[4]; RECT rect; + IWineD3DSwapChain *swapchain = NULL; + HRESULT hr; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; if(rect_in) { @@ -3602,6 +3632,15 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT glDisable(GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); } + + hr = IWineD3DSurface_GetContainer((IWineD3DSurface*)This, &IID_IWineD3DSwapChain, (void **) &swapchain); + if(hr == WINED3D_OK && swapchain) { + /* Make sure to flush the buffers. This is needed in apps like Red Alert II and Tiberian SUN that use multiple WGL contexts. */ + if(((IWineD3DSwapChainImpl*)swapchain)->num_contexts >= 2) + glFlush(); + + IWineD3DSwapChain_Release(swapchain); + } LEAVE_GL(); } @@ -3830,6 +3869,7 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = /* Internal use: */ IWineD3DSurfaceImpl_AddDirtyRect, IWineD3DSurfaceImpl_LoadTexture, + IWineD3DSurfaceImpl_BindTexture, IWineD3DSurfaceImpl_SaveSnapshot, IWineD3DBaseSurfaceImpl_SetContainer, IWineD3DSurfaceImpl_SetGlTextureDesc, diff --git a/reactos/dll/directx/wine/wined3d/surface_base.c b/reactos/dll/directx/wine/wined3d/surface_base.c index 11a3d0b088d..f57b9f49ee3 100644 --- a/reactos/dll/directx/wine/wined3d/surface_base.c +++ b/reactos/dll/directx/wine/wined3d/surface_base.c @@ -1628,3 +1628,8 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL return WINED3D_OK; } + +void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface) { + ERR("Should not be called on base texture\n"); + return; +} diff --git a/reactos/dll/directx/wine/wined3d/surface_gdi.c b/reactos/dll/directx/wine/wined3d/surface_gdi.c index 03852f86c18..5f569a1c11b 100644 --- a/reactos/dll/directx/wine/wined3d/surface_gdi.c +++ b/reactos/dll/directx/wine/wined3d/surface_gdi.c @@ -805,6 +805,7 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl = /* Internal use: */ IWineGDISurfaceImpl_AddDirtyRect, IWineGDISurfaceImpl_LoadTexture, + IWineD3DBaseSurfaceImpl_BindTexture, IWineGDISurfaceImpl_SaveSnapshot, IWineD3DBaseSurfaceImpl_SetContainer, IWineGDISurfaceImpl_SetGlTextureDesc, diff --git a/reactos/dll/directx/wine/wined3d/swapchain.c b/reactos/dll/directx/wine/wined3d/swapchain.c index 81f17c35ed3..2eaa81258ef 100644 --- a/reactos/dll/directx/wine/wined3d/swapchain.c +++ b/reactos/dll/directx/wine/wined3d/swapchain.c @@ -106,6 +106,9 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB HeapFree(GetProcessHeap(), 0, This->backBuffer); } + for(i = 0; i < This->num_contexts; i++) { + DestroyContext(This->wineD3DDevice, This->context[i]); + } /* Restore the screen resolution if we rendered in fullscreen * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9 * this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution @@ -118,9 +121,6 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB mode.Format = This->orig_fmt; IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode); } - for(i = 0; i < This->num_contexts; i++) { - DestroyContext(This->wineD3DDevice, This->context[i]); - } HeapFree(GetProcessHeap(), 0, This->context); HeapFree(GetProcessHeap(), 0, This); diff --git a/reactos/dll/directx/wine/wined3d/texture.c b/reactos/dll/directx/wine/wined3d/texture.c index 1dcaee18f80..1bdd6640647 100644 --- a/reactos/dll/directx/wine/wined3d/texture.c +++ b/reactos/dll/directx/wine/wined3d/texture.c @@ -213,39 +213,8 @@ static UINT WINAPI IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *ifa static void WINAPI IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface, const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - float matrix[16]; + TRACE("(%p) : relay to BaseTexture\n", iface); IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates); - - /** non-power2 fixups using texture matrix **/ - if(This->pow2scalingFactorX != 1.0f || This->pow2scalingFactorY != 1.0f) { - /* Apply non-power2 mappings and texture offsets so long as the texture coords aren't projected or generated */ - if(((textureStates[WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) == WINED3DTSS_TCI_PASSTHRU) && - (~textureStates[WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) { - glMatrixMode(GL_TEXTURE); - memset(matrix, 0 , sizeof(matrix)); - matrix[0] = This->pow2scalingFactorX; - matrix[5] = This->pow2scalingFactorY; -#if 0 /* this isn't needed any more, I changed the translation in drawprim.c to 0.9/width instead of 1/width and everything lines up ok. left here as a reminder */ - matrix[12] = -0.25f / (float)This->width; - matrix[13] = -0.75f / (float)This->height; -#endif - matrix[10] = 1; - matrix[15] = 1; - TRACE("(%p) Setup Matrix:\n", This); - TRACE(" %f %f %f %f\n", matrix[0], matrix[1], matrix[2], matrix[3]); - TRACE(" %f %f %f %f\n", matrix[4], matrix[5], matrix[6], matrix[7]); - TRACE(" %f %f %f %f\n", matrix[8], matrix[9], matrix[10], matrix[11]); - TRACE(" %f %f %f %f\n", matrix[12], matrix[13], matrix[14], matrix[15]); - TRACE("\n"); - - glMultMatrixf(matrix); - } else { - /* I don't expect nonpower 2 textures to be used with generated texture coordinates, but if they are present a fixme. */ - FIXME("Non-power2 texture being used with generated texture coords\n"); - } - } - } /* ******************************************* diff --git a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c index bc22d899135..924db6a1c4f 100644 --- a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c @@ -120,7 +120,7 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte const WINED3DVERTEXELEMENT *elements, size_t element_count) { IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; HRESULT hr = WINED3D_OK; - int i; + int i, j; char isPreLoaded[MAX_STREAMS]; TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion); @@ -162,8 +162,35 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte This->num_streams++; isPreLoaded[This->pDeclarationWine[i].Stream] = 1; } + + /* Create a sorted array containing the attribute declarations that are of type + * D3DCOLOR. D3DCOLOR requires swizzling of the r and b component, and if the + * declaration of one attribute changes the vertex shader needs recompilation. + * Having a sorted array of the attributes allows efficient comparison of the + * declaration against a shader + */ + if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_D3DCOLOR) { + for(j = 0; j < This->num_swizzled_attribs; j++) { + if(This->swizzled_attribs[j].usage > This->pDeclarationWine[i].Usage || + (This->swizzled_attribs[j].usage == This->pDeclarationWine[i].Usage && + This->swizzled_attribs[j].idx > This->pDeclarationWine[i].UsageIndex)) { + memmove(&This->swizzled_attribs[j + 1], &This->swizzled_attribs[j], + sizeof(This->swizzled_attribs) - (sizeof(This->swizzled_attribs[0]) * (j - 1))); + break; + } + } + + This->swizzled_attribs[j].usage = This->pDeclarationWine[i].Usage; + This->swizzled_attribs[j].idx = This->pDeclarationWine[i].UsageIndex; + This->num_swizzled_attribs++; + } } + TRACE("Swizzled attributes found:\n"); + for(i = 0; i < This->num_swizzled_attribs; i++) { + TRACE("%u: %s%d\n", i, + debug_d3ddeclusage(This->swizzled_attribs[i].usage), This->swizzled_attribs[i].idx); + } TRACE("Returning\n"); return hr; } diff --git a/reactos/dll/directx/wine/wined3d/vertexshader.c b/reactos/dll/directx/wine/wined3d/vertexshader.c index 4e2a7c58dd6..bd4c2c11aa0 100644 --- a/reactos/dll/directx/wine/wined3d/vertexshader.c +++ b/reactos/dll/directx/wine/wined3d/vertexshader.c @@ -263,29 +263,95 @@ BOOL vshader_input_is_color( unsigned int regnum) { IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface; - IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; - IWineD3DVertexDeclarationImpl *vertexDeclaration = (IWineD3DVertexDeclarationImpl *)deviceImpl->stateBlock->vertexDecl; DWORD usage_token = This->semantics_in[regnum].usage; DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - if (vertexDeclaration) { - int i; - /* Find the declaration element that matches our register, then check - * if it has D3DCOLOR as it's type. This works for both d3d8 and d3d9. */ - for (i = 0; i < vertexDeclaration->declarationWNumElements-1; ++i) { - WINED3DVERTEXELEMENT *element = vertexDeclaration->pDeclarationWine + i; - if (match_usage(element->Usage, element->UsageIndex, usage, usage_idx)) { - return element->Type == WINED3DDECLTYPE_D3DCOLOR; + int i; + + for(i = 0; i < This->num_swizzled_attribs; i++) { + if(This->swizzled_attribs[i].usage == usage && + This->swizzled_attribs[i].idx == usage_idx) { + return TRUE; + } + } + return FALSE; +} + +static inline void find_swizzled_attribs(IWineD3DVertexDeclaration *declaration, IWineD3DVertexShaderImpl *This) { + UINT num = 0, i, j; + UINT numoldswizzles = This->num_swizzled_attribs; + IWineD3DVertexDeclarationImpl *decl = (IWineD3DVertexDeclarationImpl *) declaration; + + DWORD usage_token, usage, usage_idx; + BOOL found; + + attrib_declaration oldswizzles[sizeof(This->swizzled_attribs) / sizeof(This->swizzled_attribs[0])]; + + /* Back up the old swizzles to keep attributes that are undefined in the current declaration */ + memcpy(oldswizzles, This->swizzled_attribs, sizeof(oldswizzles)); + + memset(This->swizzled_attribs, 0, sizeof(This->swizzled_attribs[0]) * MAX_ATTRIBS); + + for(i = 0; i < decl->num_swizzled_attribs; i++) { + for(j = 0; j < MAX_ATTRIBS; j++) { + usage_token = This->semantics_in[j].usage; + usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; + usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + + if(decl->swizzled_attribs[i].usage == usage && + decl->swizzled_attribs[i].idx == usage_idx) { + This->swizzled_attribs[num].usage = usage; + This->swizzled_attribs[num].idx = usage_idx; + num++; } } } - ERR("Either no vertexdeclaration present, or register not matched. This should never happen.\n"); - return FALSE; -} + /* Add previously converted attributes back in if they are not defined in the current declaration */ + for(i = 0; i < numoldswizzles; i++) { + found = FALSE; + for(j = 0; j < decl->declarationWNumElements; j++) { + if(oldswizzles[i].usage == decl->pDeclarationWine[j].Usage && + oldswizzles[i].idx == decl->pDeclarationWine[j].UsageIndex) { + found = TRUE; + } + } + if(found) { + /* This previously converted attribute is declared in the current declaration. Either it is + * already in the new array, or it should not be there. Skip it + */ + continue; + } + /* We have a previously swizzled attribute that is not defined by the current vertex declaration. + * Insert it into the new conversion array to keep it in the old defined state. Otherwise we end up + * recompiling if the old decl is used again because undefined attributes are reset to no swizzling. + * In the reverse way(attribute was not swizzled and is not declared in new declaration) the attrib + * stays unswizzled as well because it isn't found in the oldswizzles array + */ + for(j = 0; j < num; j++) { + if(oldswizzles[i].usage > This->swizzled_attribs[j].usage || ( + oldswizzles[i].usage == This->swizzled_attribs[j].usage && + oldswizzles[i].idx > This->swizzled_attribs[j].idx)) { + memmove(&This->swizzled_attribs[j + 1], &This->swizzled_attribs[j], + sizeof(This->swizzled_attribs) - (sizeof(This->swizzled_attribs[0]) * (j - 1))); + break; + } + } + This->swizzled_attribs[j].usage = oldswizzles[i].usage; + This->swizzled_attribs[j].idx = oldswizzles[i].idx; + num++; + } + + TRACE("New swizzled attributes array\n"); + for(i = 0; i < num; i++) { + TRACE("%d: %s(%d), %d\n", i, debug_d3ddeclusage(This->swizzled_attribs[i].usage), + This->swizzled_attribs[i].usage, This->swizzled_attribs[i].idx); + } + This->num_swizzled_attribs = num; +} /** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB or GLSL and send it to the card */ static VOID IWineD3DVertexShaderImpl_GenerateShader( @@ -294,8 +360,11 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( CONST DWORD *pFunction) { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; + IWineD3DVertexDeclaration *decl = ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->vertexDecl; SHADER_BUFFER buffer; + find_swizzled_attribs(decl, This); + #if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */ if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) { @@ -349,9 +418,7 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( * before the homogenous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w, * which is the same as z = z / 2 - w. */ - shader_addline(&buffer, "tmp0 = gl_Position;\n"); - shader_addline(&buffer, "gl_Position.z = tmp0.z * 2.0;\n"); - shader_addline(&buffer, "gl_Position.z = gl_Position.z - gl_Position.w;\n"); + shader_addline(&buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"); shader_addline(&buffer, "}\n"); @@ -399,8 +466,8 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that. */ - shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;"); - shader_addline(&buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, posFixup.w;"); + shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;\n"); + shader_addline(&buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, posFixup.w;\n"); /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c * and the glsl equivalent @@ -439,56 +506,16 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( /* ******************************************* IWineD3DVertexShader IUnknown parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DVertexShaderImpl_QueryInterface(IWineD3DVertexShader *iface, REFIID riid, LPVOID *ppobj) -{ - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; - TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); - if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IWineD3DBase) - || IsEqualGUID(riid, &IID_IWineD3DBaseShader) - || IsEqualGUID(riid, &IID_IWineD3DVertexShader)) { - IUnknown_AddRef(iface); - *ppobj = This; - return S_OK; - } - *ppobj = NULL; - return E_NOINTERFACE; +static HRESULT WINAPI IWineD3DVertexShaderImpl_QueryInterface(IWineD3DVertexShader *iface, REFIID riid, LPVOID *ppobj) { + return IWineD3DBaseShaderImpl_QueryInterface((IWineD3DBaseShader *) iface, riid, ppobj); } -static ULONG WINAPI IWineD3DVertexShaderImpl_AddRef(IWineD3DVertexShader *iface) { - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; - TRACE("(%p) : AddRef increasing from %d\n", This, This->ref); - return InterlockedIncrement(&This->ref); +static ULONG WINAPI IWineD3DVertexShaderImpl_AddRef(IWineD3DVertexShader *iface) { + return IWineD3DBaseShaderImpl_AddRef((IWineD3DBaseShader *) iface); } static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface) { - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; - ULONG ref; - TRACE("(%p) : Releasing from %d\n", This, This->ref); - ref = InterlockedDecrement(&This->ref); - if (ref == 0) { - if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) { - struct list *linked_programs = &This->baseShader.linked_programs; - - TRACE("Deleting linked programs\n"); - if (linked_programs->next) { - struct glsl_shader_prog_link *entry, *entry2; - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, vshader_entry) { - delete_glsl_program_entry(This->baseShader.device, entry); - } - } - - TRACE("Deleting shader object %u\n", This->baseShader.prgId); - GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId)); - checkGLcall("glDeleteObjectARB"); - } - shader_delete_constant_list(&This->baseShader.constantsF); - shader_delete_constant_list(&This->baseShader.constantsB); - shader_delete_constant_list(&This->baseShader.constantsI); - HeapFree(GetProcessHeap(), 0, This); - - } - return ref; + return IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface); } /* ******************************************* @@ -587,6 +614,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader This->rel_offset = 0; } } + This->baseShader.load_local_constsF = This->baseShader.reg_maps.usesrelconstF && !list_empty(&This->baseShader.constantsF); /* copy the function ... because it will certainly be released by application */ if (NULL != pFunction) { @@ -641,14 +669,86 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex return WINED3D_OK; } +static inline BOOL swizzled_attribs_differ(IWineD3DVertexShaderImpl *This, IWineD3DVertexDeclarationImpl *vdecl) { + UINT i, j, k; + BOOL found; + + DWORD usage_token; + DWORD usage; + DWORD usage_idx; + + for(i = 0; i < vdecl->declarationWNumElements; i++) { + for(j = 0; j < MAX_ATTRIBS; j++) { + if(!This->baseShader.reg_maps.attributes) continue; + + usage_token = This->semantics_in[j].usage; + usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; + usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + + if(vdecl->pDeclarationWine[i].Usage != usage || + vdecl->pDeclarationWine[i].UsageIndex != usage_idx) { + continue; + } + + found = FALSE; + for(k = 0; k < This->num_swizzled_attribs; k++) { + if(This->swizzled_attribs[k].usage == usage && + This->swizzled_attribs[k].idx == usage_idx) { + found = TRUE; + } + } + if(!found && vdecl->pDeclarationWine[i].Type == WINED3DDECLTYPE_D3DCOLOR) { + TRACE("Attribute %s%d is D3DCOLOR now but wasn't before\n", + debug_d3ddeclusage(usage), usage_idx); + return TRUE; + } + if( found && vdecl->pDeclarationWine[i].Type != WINED3DDECLTYPE_D3DCOLOR) { + TRACE("Attribute %s%d was D3DCOLOR before but is not any more\n", + debug_d3ddeclusage(usage), usage_idx); + return TRUE; + } + } + } + return FALSE; +} + static HRESULT WINAPI IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; + IWineD3DVertexDeclarationImpl *vdecl; CONST DWORD *function = This->baseShader.function; + IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device; TRACE("(%p) : function %p\n", iface, function); /* We're already compiled. */ - if (This->baseShader.is_compiled) return WINED3D_OK; + if (This->baseShader.is_compiled) { + vdecl = (IWineD3DVertexDeclarationImpl *) deviceImpl->stateBlock->vertexDecl; + + if(This->num_swizzled_attribs != vdecl->num_swizzled_attribs || + memcmp(This->swizzled_attribs, vdecl->swizzled_attribs, sizeof(vdecl->swizzled_attribs[0]) * This->num_swizzled_attribs) != 0) { + + /* The swizzled attributes differ between shader and declaration. This doesn't necessarily mean + * we have to recompile, but we have to take a deeper look at see if the attribs that differ + * are declared in the decl and used in the shader + */ + if(swizzled_attribs_differ(This, vdecl)) { + WARN("Recompiling vertex shader %p due to D3DCOLOR input changes\n", This); + goto recompile; + } + WARN("Swizzled attribute validation required an expensive comparison\n"); + } + + return WINED3D_OK; + + recompile: + if(This->recompile_count < 50) { + This->recompile_count++; + } else { + FIXME("Vertexshader %p recompiled more than 50 times\n", This); + } + + deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface); + } /* We don't need to compile */ if (!function) { diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 60e586b098e..d006f876a40 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -44,11 +44,6 @@ #include "wine/list.h" #define ceilf(x) (float)ceil((double)x) -BOOL WINAPI -DllMain(IN HINSTANCE hinstDLL, - IN DWORD dwReason, - IN LPVOID lpvReserved); - /* Hash table functions */ typedef unsigned int (hash_function_t)(void *key); typedef BOOL (compare_function_t)(void *keya, void *keyb); @@ -217,6 +212,7 @@ typedef struct { void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS); void (*shader_cleanup)(IWineD3DDevice *iface); void (*shader_color_correction)(struct SHADER_OPCODE_ARG *arg); + void (*shader_destroy)(IWineD3DBaseShader *iface); } shader_backend_t; extern const shader_backend_t glsl_shader_backend; @@ -631,13 +627,8 @@ extern BOOL pbuffer_support; /* allocate one pbuffer per surface */ extern BOOL pbuffer_per_surface; -typedef struct ResourceList { - IWineD3DResource *resource; - struct ResourceList *next; -} ResourceList; - /* A helper function that dumps a resource list */ -void dumpResources(ResourceList *resources); +void dumpResources(struct list *list); /***************************************************************************** * IWineD3DDevice implementation structure @@ -687,11 +678,11 @@ struct IWineD3DDeviceImpl IWineD3DSwapChain **swapchains; UINT NumberOfSwapChains; - ResourceList *resources; /* a linked list to track resources created by the device */ + struct list resources; /* a linked list to track resources created by the device */ /* Render Target Support */ IWineD3DSurface **render_targets; - IWineD3DSurface *depthStencilBuffer; + IWineD3DSurface *auto_depth_stencil_buffer; IWineD3DSurface **fbo_color_attachments; IWineD3DSurface *fbo_depth_attachment; @@ -827,6 +818,7 @@ typedef struct IWineD3DResourceClass BYTE *allocatedMemory; /* Pointer to the real data location */ BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */ struct list privateData; + struct list resource_list_entry; } IWineD3DResourceClass; @@ -930,6 +922,7 @@ typedef struct IWineD3DBaseTextureClass BOOL is_srgb; UINT srgb_mode_change_count; WINED3DFORMAT shader_conversion_group; + float pow2Matrix[16]; } IWineD3DBaseTextureClass; typedef struct IWineD3DBaseTextureImpl @@ -956,8 +949,6 @@ typedef struct IWineD3DTextureImpl UINT width; UINT height; - float pow2scalingFactorX; - float pow2scalingFactorY; } IWineD3DTextureImpl; @@ -977,8 +968,6 @@ typedef struct IWineD3DCubeTextureImpl IWineD3DSurface *surfaces[6][MAX_LEVELS]; UINT edgeLength; - float pow2scalingFactor; - } IWineD3DCubeTextureImpl; extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl; @@ -1103,12 +1092,6 @@ struct IWineD3DSurfaceImpl /* PBO */ GLuint pbo; -#if 0 - /* precalculated x and y scalings for texture coords */ - float pow2scalingFactorX; /* = (Width / pow2Width ) */ - float pow2scalingFactorY; /* = (Height / pow2Height) */ -#endif - RECT lockedRect; RECT dirtyRect; int lockCount; @@ -1174,6 +1157,7 @@ HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter); HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans); HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags); +void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface); const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface); @@ -1252,6 +1236,13 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ /***************************************************************************** * IWineD3DVertexDeclaration implementation structure */ +typedef struct attrib_declaration { + DWORD usage; + DWORD idx; +} attrib_declaration; + +#define MAX_ATTRIBS 16 + typedef struct IWineD3DVertexDeclarationImpl { /* IUnknown Information */ const IWineD3DVertexDeclarationVtbl *lpVtbl; @@ -1266,6 +1257,10 @@ typedef struct IWineD3DVertexDeclarationImpl { DWORD streams[MAX_STREAMS]; UINT num_streams; BOOL position_transformed; + + /* Ordered array of declaration types that need swizzling in a vshader */ + attrib_declaration swizzled_attribs[MAX_ATTRIBS]; + UINT num_swizzled_attribs; } IWineD3DVertexDeclarationImpl; extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl; @@ -1641,7 +1636,6 @@ typedef struct { #define MAX_REG_TEXCRD 8 #define MAX_REG_INPUT 12 #define MAX_REG_OUTPUT 12 -#define MAX_ATTRIBS 16 #define MAX_CONST_I 16 #define MAX_CONST_B 16 @@ -1675,6 +1669,7 @@ typedef struct shader_reg_maps { DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; char bumpmat, luminanceparams; char usesnrm, vpos, usesdsy; + char usesrelconstF; /* Whether or not loops are used in this shader, and nesting depth */ unsigned loop_depth; @@ -1761,9 +1756,6 @@ extern const SHADER_OPCODE* shader_get_opcode( IWineD3DBaseShader *iface, const DWORD code); -extern void shader_delete_constant_list( - struct list* clist); - void delete_glsl_program_entry(IWineD3DDevice *iface, struct glsl_shader_prog_link *entry); /* Vertex shader utility functions */ @@ -1895,15 +1887,17 @@ extern void pshader_glsl_input_pack( */ typedef struct IWineD3DBaseShaderClass { + LONG ref; DWORD hex_version; SHADER_LIMITS limits; SHADER_PARSE_STATE parse_state; CONST SHADER_OPCODE *shader_ins; - CONST DWORD *function; + DWORD *function; UINT functionLength; GLuint prgId; BOOL is_compiled; UINT cur_loop_depth, cur_loop_regno; + BOOL load_local_constsF; /* Type of shader backend */ int shader_mode; @@ -1936,12 +1930,15 @@ typedef struct IWineD3DBaseShaderClass typedef struct IWineD3DBaseShaderImpl { /* IUnknown */ const IWineD3DBaseShaderVtbl *lpVtbl; - LONG ref; /* IWineD3DBaseShader */ IWineD3DBaseShaderClass baseShader; } IWineD3DBaseShaderImpl; +HRESULT WINAPI IWineD3DBaseShaderImpl_QueryInterface(IWineD3DBaseShader *iface, REFIID riid, LPVOID *ppobj); +ULONG WINAPI IWineD3DBaseShaderImpl_AddRef(IWineD3DBaseShader *iface); +ULONG WINAPI IWineD3DBaseShaderImpl_Release(IWineD3DBaseShader *iface); + extern HRESULT shader_get_registers_used( IWineD3DBaseShader *iface, shader_reg_maps* reg_maps, @@ -2050,7 +2047,6 @@ static inline BOOL shader_is_scalar(DWORD param) { typedef struct IWineD3DVertexShaderImpl { /* IUnknown parts*/ const IWineD3DVertexShaderVtbl *lpVtbl; - LONG ref; /* Note: Ref counting not required */ /* IWineD3DBaseShader */ IWineD3DBaseShaderClass baseShader; @@ -2064,11 +2060,16 @@ typedef struct IWineD3DVertexShaderImpl { semantic semantics_in [MAX_ATTRIBS]; semantic semantics_out [MAX_REG_OUTPUT]; + /* Ordered array of attributes that are swizzled */ + attrib_declaration swizzled_attribs [MAX_ATTRIBS]; + UINT num_swizzled_attribs; + /* run time datas... */ VSHADERDATA *data; UINT min_rel_offset, max_rel_offset; UINT rel_offset; + UINT recompile_count; #if 0 /* needs reworking */ /* run time datas */ VSHADERINPUTDATA input; @@ -2091,7 +2092,6 @@ enum vertexprocessing_mode { typedef struct IWineD3DPixelShaderImpl { /* IUnknown parts */ const IWineD3DPixelShaderVtbl *lpVtbl; - LONG ref; /* Note: Ref counting not required */ /* IWineD3DBaseShader */ IWineD3DBaseShaderClass baseShader;