Updating wined3d from winehq.org cvs/git date 27/11-2007
this update solv allot of bugs in wined3d
------------------------------------------
Include one ReactOS specify hack. do not use gdi32.dll use opengl32.dll instead. 

svn path=/trunk/; revision=30814
This commit is contained in:
Magnus Olsen 2007-11-27 11:16:57 +00:00
parent 10d28df34a
commit b7fb058e20
21 changed files with 638 additions and 406 deletions

View file

@ -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
};

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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");
}
}
}

View file

@ -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);
}

View file

@ -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
}

View file

@ -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;

View file

@ -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; i<max_constants; ++i) {
if (NULL == constants_set || constants_set[i]) {
TRACE_(d3d_constants)("Loading constants %i: %i;\n", i, constants[i*4]);
TRACE_(d3d_constants)("Loading constants %i: %i;\n", i, constants[i]);
/* TODO: Benchmark and see if it would be beneficial to store the
* locations of the constants to avoid looking up each time */
@ -296,7 +301,7 @@ static void shader_glsl_load_constantsB(
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
if (tmp_loc != -1) {
/* We found this uniform name in the program - go ahead and send the data */
GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i*4]));
GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i]));
checkGLcall("glUniform1ivARB");
}
}
@ -464,6 +469,7 @@ void shader_generate_glsl_declarations(
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.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
};

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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)));
}
}

View file

@ -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
*/

View file

@ -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);

View file

@ -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 <errno.h>
#include <stdio.h>
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,

View file

@ -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;
}

View file

@ -805,6 +805,7 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
/* Internal use: */
IWineGDISurfaceImpl_AddDirtyRect,
IWineGDISurfaceImpl_LoadTexture,
IWineD3DBaseSurfaceImpl_BindTexture,
IWineGDISurfaceImpl_SaveSnapshot,
IWineD3DBaseSurfaceImpl_SetContainer,
IWineGDISurfaceImpl_SetGlTextureDesc,

View file

@ -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);

View file

@ -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");
}
}
}
/* *******************************************

View file

@ -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;
}

View file

@ -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) {

View file

@ -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;