mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
part 2/2
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:
parent
10d28df34a
commit
b7fb058e20
21 changed files with 638 additions and 406 deletions
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
TRACE("(%p) : Removing resource %p\n", This, resource);
|
||||
|
||||
resourceList = This->resources;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -805,6 +805,7 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
|
|||
/* Internal use: */
|
||||
IWineGDISurfaceImpl_AddDirtyRect,
|
||||
IWineGDISurfaceImpl_LoadTexture,
|
||||
IWineD3DBaseSurfaceImpl_BindTexture,
|
||||
IWineGDISurfaceImpl_SaveSnapshot,
|
||||
IWineD3DBaseSurfaceImpl_SetContainer,
|
||||
IWineGDISurfaceImpl_SetGlTextureDesc,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue