/* Define the default light parameters as specified by MSDN */
const WINED3DLIGHT WINED3D_default_light = {
- WINED3DLIGHT_DIRECTIONAL, /* Type */
- { 1.0, 1.0, 1.0, 0.0 }, /* Diffuse r,g,b,a */
- { 0.0, 0.0, 0.0, 0.0 }, /* Specular r,g,b,a */
- { 0.0, 0.0, 0.0, 0.0 }, /* Ambient r,g,b,a, */
- { 0.0, 0.0, 0.0 }, /* Position x,y,z */
- { 0.0, 0.0, 1.0 }, /* Direction x,y,z */
- 0.0, /* Range */
- 0.0, /* Falloff */
- 0.0, 0.0, 0.0, /* Attenuation 0,1,2 */
- 0.0, /* Theta */
- 0.0 /* Phi */
+ WINED3DLIGHT_DIRECTIONAL, /* Type */
+ { 1.0f, 1.0f, 1.0f, 0.0f }, /* Diffuse r,g,b,a */
+ { 0.0f, 0.0f, 0.0f, 0.0f }, /* Specular r,g,b,a */
+ { 0.0f, 0.0f, 0.0f, 0.0f }, /* Ambient r,g,b,a, */
+ { 0.0f, 0.0f, 0.0f }, /* Position x,y,z */
+ { 0.0f, 0.0f, 1.0f }, /* Direction x,y,z */
+ 0.0f, /* Range */
+ 0.0f, /* Falloff */
+ 0.0f, 0.0f, 0.0f, /* Attenuation 0,1,2 */
+ 0.0f, /* Theta */
+ 0.0f /* Phi */
};
-/* static function declarations */
-static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
-
/**********************************************************
* Global variable / Constants follow
**********************************************************/
-const float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; /* When needed for comparisons */
+const float identity[] =
+{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+}; /* When needed for comparisons */
/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
* actually have the same values in GL and D3D. */
return TRUE;
}
+/* Context activation is done by the caller. */
void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup)
{
const DWORD *streams = declaration->streams;
unsigned int i;
- memset(stream_info, 0, sizeof(*stream_info));
+ stream_info->use_map = 0;
+ stream_info->swizzle_map = 0;
/* Check for transformed vertices, disable vertex shader if present. */
stream_info->position_transformed = declaration->position_transformed;
struct wined3d_buffer_desc *desc, const void *data, IUnknown *parent, IWineD3DBuffer **buffer)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
struct wined3d_buffer *object;
HRESULT hr;
FIXME("Ignoring access flags (pool)\n");
- hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, desc->byte_width,
- desc->usage, WINED3DFMT_UNKNOWN, WINED3DPOOL_MANAGED, parent);
+ hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, desc->byte_width,
+ desc->usage, format_desc, WINED3DPOOL_MANAGED, parent);
if (FAILED(hr))
{
WARN("Failed to initialize resource, returning %#x\n", hr);
TRACE("Created resource %p\n", object);
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
TRACE("size %#x, usage=%#x, format %s, memory @ %p, iface @ %p\n", object->resource.size, object->resource.usage,
debug_d3dformat(object->resource.format_desc->format), object->resource.allocatedMemory, object);
}
object->vtbl = &wined3d_buffer_vtbl;
- hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent);
+ hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent);
if (FAILED(hr))
{
WARN("Failed to initialize resource, returning %#x\n", hr);
TRACE("(%p) : Created resource %p\n", This, object);
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object);
*ppVertexBuffer = (IWineD3DBuffer *)object;
}
object->vtbl = &wined3d_buffer_vtbl;
- hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
+ hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
if (FAILED(hr))
{
WARN("Failed to initialize resource, returning %#x\n", hr);
TRACE("(%p) : Created resource %p\n", This, object);
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
object->flags |= WINED3D_BUFFER_CREATEBO;
}
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface,
- UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level,
- IWineD3DSurface **ppSurface, WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool,
- WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, WINED3DSURFTYPE Impl, IUnknown *parent)
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height,
+ WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,
+ DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
+ WINED3DSURFTYPE Impl, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
- unsigned int Size = 1;
- const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(Format, &GLINFO_LOCATION);
- UINT mul_4w, mul_4h;
+ IWineD3DSurfaceImpl *object;
HRESULT hr;
TRACE("(%p) Create surface\n",This);
- if(MultisampleQuality > 0) {
- FIXME("MultisampleQuality set to %d, substituting 0\n", MultisampleQuality);
- MultisampleQuality=0;
- }
-
- /** FIXME: Check that the format is supported
- * by the device.
- *******************************/
-
- /** DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
- * it is based around 4x4 pixel blocks it requires padding, so allocate enough
- * space!
- *********************************/
- mul_4w = (Width + 3) & ~3;
- mul_4h = (Height + 3) & ~3;
- if (WINED3DFMT_UNKNOWN == Format) {
- Size = 0;
- } else if (Format == WINED3DFMT_DXT1) {
- /* DXT1 is half byte per pixel */
- Size = (mul_4w * glDesc->byte_count * mul_4h) >> 1;
-
- } else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 ||
- Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5 ||
- Format == WINED3DFMT_ATI2N) {
- Size = (mul_4w * glDesc->byte_count * mul_4h);
- } else {
- /* The pitch is a multiple of 4 bytes */
- Size = ((Width * glDesc->byte_count) + This->surface_alignment - 1) & ~(This->surface_alignment - 1);
- Size *= Height;
+ if (Impl == SURFACE_OPENGL && !This->adapter)
+ {
+ ERR("OpenGL surfaces are not available without OpenGL.\n");
+ return WINED3DERR_NOTAVAILABLE;
}
- if(glDesc->heightscale != 0.0) Size *= glDesc->heightscale;
-
- /** Create and initialise the surface resource **/
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
- ERR("Out of memory\n");
+ ERR("Failed to allocate surface memory.\n");
*ppSurface = NULL;
return WINED3DERR_OUTOFVIDEOMEMORY;
}
- /* Look at the implementation and set the correct Vtable */
- switch(Impl)
- {
- case SURFACE_OPENGL:
- /* Check if a 3D adapter is available when creating gl surfaces */
- if (!This->adapter)
- {
- ERR("OpenGL surfaces are not available without opengl\n");
- HeapFree(GetProcessHeap(), 0, object);
- return WINED3DERR_NOTAVAILABLE;
- }
- object->lpVtbl = &IWineD3DSurface_Vtbl;
- break;
-
- case SURFACE_GDI:
- object->lpVtbl = &IWineGDISurface_Vtbl;
- break;
-
- default:
- /* To be sure to catch this */
- ERR("Unknown requested surface implementation %d!\n", Impl);
- HeapFree(GetProcessHeap(), 0, object);
- return WINED3DERR_INVALIDCALL;
- }
-
- hr = resource_init(&object->resource, WINED3DRTYPE_SURFACE, This, Size, Usage, glDesc, Pool, parent);
+ hr = surface_init(object, Impl, This->surface_alignment, Width, Height, Level, Lockable,
+ Discard, MultiSample, MultisampleQuality, This, Usage, Format, Pool, parent);
if (FAILED(hr))
{
- WARN("Failed to initialize resource, returning %#x\n", hr);
+ WARN("Failed to initialize surface, returning %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
*ppSurface = NULL;
return hr;
}
- TRACE("(%p) : Created resource %p\n", This, object);
-
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+ TRACE("(%p) : Created surface %p\n", This, object);
*ppSurface = (IWineD3DSurface *)object;
- /* "Standalone" surface */
- IWineD3DSurface_SetContainer((IWineD3DSurface *)object, NULL);
-
- object->currentDesc.Width = Width;
- object->currentDesc.Height = Height;
- object->currentDesc.MultiSampleType = MultiSample;
- object->currentDesc.MultiSampleQuality = MultisampleQuality;
- object->glDescription.level = Level;
- list_init(&object->overlays);
-
- /* Flags */
- object->Flags = SFLAG_NORMCOORD; /* Default to normalized coords */
- object->Flags |= Discard ? SFLAG_DISCARD : 0;
- object->Flags |= (WINED3DFMT_D16_LOCKABLE == Format) ? SFLAG_LOCKABLE : 0;
- object->Flags |= Lockable ? SFLAG_LOCKABLE : 0;
-
- TRACE("Pool %d %d %d %d\n",Pool, WINED3DPOOL_DEFAULT, WINED3DPOOL_MANAGED, WINED3DPOOL_SYSTEMMEM);
-
- /** Quick lockable sanity check TODO: remove this after surfaces, usage and lockability have been debugged properly
- * this function is too deep to need to care about things like this.
- * Levels need to be checked too, and possibly Type since they all affect what can be done.
- * ****************************************/
- switch(Pool) {
- case WINED3DPOOL_SCRATCH:
- if(!Lockable)
- FIXME("Create surface called with a pool of SCRATCH and a Lockable of FALSE "
- "which are mutually exclusive, setting lockable to TRUE\n");
- Lockable = TRUE;
- break;
- case WINED3DPOOL_SYSTEMMEM:
- if(!Lockable) FIXME("Create surface called with a pool of SYSTEMMEM and a Lockable of FALSE, "
- "this is acceptable but unexpected (I can't know how the surface can be usable!)\n");
- case WINED3DPOOL_MANAGED:
- if(Usage == WINED3DUSAGE_DYNAMIC) FIXME("Create surface called with a pool of MANAGED and a "
- "Usage of DYNAMIC which are mutually exclusive, not doing "
- "anything just telling you.\n");
- break;
- case WINED3DPOOL_DEFAULT: /*TODO: Create offscreen plain can cause this check to fail..., find out if it should */
- if(!(Usage & WINED3DUSAGE_DYNAMIC) && !(Usage & WINED3DUSAGE_RENDERTARGET)
- && !(Usage && WINED3DUSAGE_DEPTHSTENCIL ) && Lockable)
- WARN("Creating a surface with a POOL of DEFAULT with Lockable true, that doesn't specify DYNAMIC usage.\n");
- break;
- default:
- FIXME("(%p) Unknown pool %d\n", This, Pool);
- break;
- };
-
- if (Usage & WINED3DUSAGE_RENDERTARGET && Pool != WINED3DPOOL_DEFAULT) {
- FIXME("Trying to create a render target that isn't in the default pool\n");
- }
-
- /* mark the texture as dirty so that it gets loaded first time around*/
- surface_add_dirty_rect(*ppSurface, NULL);
- TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n",
- This, Width, Height, Format, debug_d3dformat(Format),
- (WINED3DFMT_D16_LOCKABLE == Format), *ppSurface, object->resource.allocatedMemory, object->resource.size);
-
- list_init(&object->renderbuffers);
-
- /* Call the private setup routine */
- hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)object);
- if (FAILED(hr))
- {
- ERR("Private setup failed, returning %#x\n", hr);
- IWineD3DSurface_Release(*ppSurface);
- *ppSurface = NULL;
- return hr;
- }
-
return hr;
}
WINED3DPOOL Pool, IWineD3DTexture **ppTexture, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
IWineD3DTextureImpl *object;
- unsigned int i;
- UINT tmpW;
- UINT tmpH;
HRESULT hr;
- unsigned int pow2Width;
- unsigned int pow2Height;
TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#x\n", This, Width, Height, Levels, Usage);
TRACE("Format %#x (%s), Pool %#x, ppTexture %p, parent %p\n",
Format, debug_d3dformat(Format), Pool, ppTexture, parent);
- /* TODO: It should only be possible to create textures for formats
- that are reported as supported */
- if (WINED3DFMT_UNKNOWN >= Format) {
- WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
- return WINED3DERR_INVALIDCALL;
- }
-
- /* Non-power2 support */
- if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO))
- {
- pow2Width = Width;
- pow2Height = Height;
- }
- else
- {
- /* Find the nearest pow2 match */
- pow2Width = pow2Height = 1;
- while (pow2Width < Width) pow2Width <<= 1;
- while (pow2Height < Height) pow2Height <<= 1;
-
- if (pow2Width != Width || pow2Height != Height)
- {
- if (Levels > 1)
- {
- WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support\n");
- return WINED3DERR_INVALIDCALL;
- }
- Levels = 1;
- }
- }
-
- /* Calculate levels for mip mapping */
- if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
- {
- if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
- {
- WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- if (Levels > 1)
- {
- WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- Levels = 1;
- }
- else if (!Levels)
- {
- Levels = wined3d_log2i(max(Width, Height)) + 1;
- TRACE("Calculated levels = %d\n", Levels);
- }
-
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
}
object->lpVtbl = &IWineD3DTexture_Vtbl;
- hr = resource_init(&object->resource, WINED3DRTYPE_TEXTURE, This, 0, Usage, format_desc, Pool, parent);
+
+ hr = texture_init(object, Width, Height, Levels, This, Usage, Format, Pool, parent);
if (FAILED(hr))
{
- WARN("Failed to initialize resource, returning %#x\n", hr);
+ WARN("Failed to initialize texture, returning %#x\n", hr);
HeapFree(GetProcessHeap(), 0, object);
*ppTexture = NULL;
return hr;
}
- TRACE("(%p) : Created resource %p\n", This, object);
-
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
*ppTexture = (IWineD3DTexture *)object;
- basetexture_init(&object->baseTexture, Levels, Usage);
-
- if (object->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
- {
- object->baseTexture.minMipLookup = minMipLookup;
- object->baseTexture.magLookup = magLookup;
- } else {
- object->baseTexture.minMipLookup = minMipLookup_noFilter;
- object->baseTexture.magLookup = magLookup_noFilter;
- }
-
- /** 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.
- Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
- is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE
- doesn't work in combination with ARB_TEXTURE_RECTANGLE.
- */
- if(GL_SUPPORT(WINE_NORMALIZED_TEXRECT) && (Width != pow2Width || Height != pow2Height)) {
- object->baseTexture.pow2Matrix[0] = 1.0;
- object->baseTexture.pow2Matrix[5] = 1.0;
- object->baseTexture.pow2Matrix[10] = 1.0;
- object->baseTexture.pow2Matrix[15] = 1.0;
- object->target = GL_TEXTURE_2D;
- object->cond_np2 = TRUE;
- object->baseTexture.minMipLookup = minMipLookup_noFilter;
- } else if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE) &&
- (Width != pow2Width || Height != pow2Height) &&
- !((Format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE) && (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX)))
- {
- if ((Width != 1) || (Height != 1)) {
- object->baseTexture.pow2Matrix_identity = FALSE;
- }
-
- object->baseTexture.pow2Matrix[0] = (float)Width;
- object->baseTexture.pow2Matrix[5] = (float)Height;
- object->baseTexture.pow2Matrix[10] = 1.0;
- object->baseTexture.pow2Matrix[15] = 1.0;
- object->target = GL_TEXTURE_RECTANGLE_ARB;
- object->cond_np2 = TRUE;
- object->baseTexture.minMipLookup = minMipLookup_noFilter;
- } else {
- if ((Width != pow2Width) || (Height != pow2Height)) {
- object->baseTexture.pow2Matrix_identity = FALSE;
- object->baseTexture.pow2Matrix[0] = (((float)Width) / ((float)pow2Width));
- object->baseTexture.pow2Matrix[5] = (((float)Height) / ((float)pow2Height));
- } else {
- object->baseTexture.pow2Matrix[0] = 1.0;
- object->baseTexture.pow2Matrix[5] = 1.0;
- }
+ TRACE("(%p) : Created texture %p\n", This, object);
- object->baseTexture.pow2Matrix[10] = 1.0;
- object->baseTexture.pow2Matrix[15] = 1.0;
- object->target = GL_TEXTURE_2D;
- object->cond_np2 = FALSE;
- }
- TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], object->baseTexture.pow2Matrix[5]);
-
- /* Generate all the surfaces */
- tmpW = Width;
- tmpH = Height;
- for (i = 0; i < object->baseTexture.levels; i++)
- {
- /* use the callback to create the texture surface */
- hr = IWineD3DDeviceParent_CreateSurface(This->device_parent, parent, tmpW, tmpH, Format,
- Usage, Pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &object->surfaces[i]);
- if (hr!= WINED3D_OK || ( (IWineD3DSurfaceImpl *) object->surfaces[i])->Flags & SFLAG_OVERSIZE) {
- FIXME("Failed to create surface %p\n", object);
- /* clean up */
- object->surfaces[i] = NULL;
- IWineD3DTexture_Release((IWineD3DTexture *)object);
-
- *ppTexture = NULL;
- return hr;
- }
-
- IWineD3DSurface_SetContainer(object->surfaces[i], (IWineD3DBase *)object);
- TRACE("Created surface level %d @ %p\n", i, object->surfaces[i]);
- surface_set_texture_target(object->surfaces[i], object->target);
- /* calculate the next mipmap level */
- tmpW = max(1, tmpW >> 1);
- tmpH = max(1, tmpH >> 1);
- }
- object->baseTexture.internal_preload = texture_internal_preload;
-
- TRACE("(%p) : Created texture %p\n", This, object);
return WINED3D_OK;
}
WINED3DPOOL Pool, IWineD3DVolumeTexture **ppVolumeTexture, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
IWineD3DVolumeTextureImpl *object;
- unsigned int i;
- UINT tmpW;
- UINT tmpH;
- UINT tmpD;
HRESULT hr;
- /* TODO: It should only be possible to create textures for formats
- that are reported as supported */
- if (WINED3DFMT_UNKNOWN >= Format) {
- WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
- return WINED3DERR_INVALIDCALL;
- }
- if(!GL_SUPPORT(EXT_TEXTURE3D)) {
- WARN("(%p) : Texture cannot be created - no volume texture support\n", This);
- return WINED3DERR_INVALIDCALL;
- }
-
- /* Calculate levels for mip mapping */
- if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
- {
- if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
- {
- WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- if (Levels > 1)
- {
- WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- Levels = 1;
- }
- else if (!Levels)
- {
- Levels = wined3d_log2i(max(max(Width, Height), Depth)) + 1;
- TRACE("Calculated levels = %d\n", Levels);
- }
+ TRACE("(%p) : W(%u) H(%u) D(%u), Lvl(%u) Usage(%#x), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
+ Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
}
object->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
- hr = resource_init(&object->resource, WINED3DRTYPE_VOLUMETEXTURE, This, 0, Usage, format_desc, Pool, parent);
+ hr = volumetexture_init(object, Width, Height, Depth, Levels, This, Usage, Format, Pool, parent);
if (FAILED(hr))
{
- WARN("Failed to initialize resource, returning %#x\n", hr);
+ WARN("Failed to initialize volumetexture, returning %#x\n", hr);
HeapFree(GetProcessHeap(), 0, object);
*ppVolumeTexture = NULL;
return hr;
}
- TRACE("(%p) : Created resource %p\n", This, object);
-
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
- basetexture_init(&object->baseTexture, Levels, Usage);
-
- TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
- Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
-
- /* 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;
-
- if (object->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
- {
- object->baseTexture.minMipLookup = minMipLookup;
- object->baseTexture.magLookup = magLookup;
- } else {
- object->baseTexture.minMipLookup = minMipLookup_noFilter;
- object->baseTexture.magLookup = magLookup_noFilter;
- }
-
- /* Generate all the surfaces */
- tmpW = Width;
- tmpH = Height;
- tmpD = Depth;
+ TRACE("(%p) : Created volume texture %p.\n", This, object);
+ *ppVolumeTexture = (IWineD3DVolumeTexture *)object;
- for (i = 0; i < object->baseTexture.levels; i++)
- {
- HRESULT hr;
- /* Create the volume */
- hr = IWineD3DDeviceParent_CreateVolume(This->device_parent, parent,
- tmpW, tmpH, tmpD, Format, Pool, Usage, &object->volumes[i]);
- if(FAILED(hr)) {
- ERR("Creating a volume for the volume texture failed(%08x)\n", hr);
- IWineD3DVolumeTexture_Release((IWineD3DVolumeTexture *) object);
- *ppVolumeTexture = NULL;
- return hr;
- }
-
- /* Set its container to this object */
- IWineD3DVolume_SetContainer(object->volumes[i], (IWineD3DBase *)object);
-
- /* calculate the next mipmap level */
- tmpW = max(1, tmpW >> 1);
- tmpH = max(1, tmpH >> 1);
- tmpD = max(1, tmpD >> 1);
- }
- object->baseTexture.internal_preload = volumetexture_internal_preload;
-
- *ppVolumeTexture = (IWineD3DVolumeTexture *) object;
- TRACE("(%p) : Created volume texture %p\n", This, object);
return WINED3D_OK;
}
}
object->lpVtbl = &IWineD3DVolume_Vtbl;
- hr = resource_init(&object->resource, WINED3DRTYPE_VOLUME, This,
+ hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_VOLUME, This,
Width * Height * Depth * format_desc->byte_count, Usage, format_desc, Pool, parent);
if (FAILED(hr))
{
TRACE("(%p) : Created resource %p\n", This, object);
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
*ppVolume = (IWineD3DVolume *)object;
TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/
- unsigned int i, j;
- UINT tmpW;
HRESULT hr;
- unsigned int pow2EdgeLength;
-
- /* TODO: It should only be possible to create textures for formats
- that are reported as supported */
- if (WINED3DFMT_UNKNOWN >= Format) {
- WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
- return WINED3DERR_INVALIDCALL;
- }
-
- if (!GL_SUPPORT(ARB_TEXTURE_CUBE_MAP) && Pool != WINED3DPOOL_SCRATCH) {
- WARN("(%p) : Tried to create not supported cube texture\n", This);
- return WINED3DERR_INVALIDCALL;
- }
-
- /* Calculate levels for mip mapping */
- if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
- {
- if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
- {
- WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- if (Levels > 1)
- {
- WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- Levels = 1;
- }
- else if (!Levels)
- {
- Levels = wined3d_log2i(EdgeLength) + 1;
- TRACE("Calculated levels = %d\n", Levels);
- }
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
}
object->lpVtbl = &IWineD3DCubeTexture_Vtbl;
- hr = resource_init(&object->resource, WINED3DRTYPE_CUBETEXTURE, This, 0, Usage, format_desc, Pool, parent);
+ hr = cubetexture_init(object, EdgeLength, Levels, This, Usage, Format, Pool, parent);
if (FAILED(hr))
{
- WARN("Failed to initialize resource, returning %#x\n", hr);
+ WARN("Failed to initialize cubetexture, returning %#x\n", hr);
HeapFree(GetProcessHeap(), 0, object);
*ppCubeTexture = NULL;
return hr;
}
- TRACE("(%p) : Created resource %p\n", This, object);
-
- IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
- basetexture_init(&object->baseTexture, Levels, Usage);
-
- TRACE("(%p) Create Cube Texture\n", This);
-
- /* Find the nearest pow2 match */
- pow2EdgeLength = 1;
- while (pow2EdgeLength < EdgeLength) pow2EdgeLength <<= 1;
-
- if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || (EdgeLength == pow2EdgeLength)) {
- /* Precalculated scaling for 'faked' non power of two texture coords */
- object->baseTexture.pow2Matrix[ 0] = 1.0;
- object->baseTexture.pow2Matrix[ 5] = 1.0;
- object->baseTexture.pow2Matrix[10] = 1.0;
- object->baseTexture.pow2Matrix[15] = 1.0;
- } else {
- /* Precalculated scaling for 'faked' non power of two texture coords */
- 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;
- object->baseTexture.pow2Matrix_identity = FALSE;
- }
-
- if (object->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
- {
- object->baseTexture.minMipLookup = minMipLookup;
- object->baseTexture.magLookup = magLookup;
- } else {
- object->baseTexture.minMipLookup = minMipLookup_noFilter;
- object->baseTexture.magLookup = magLookup_noFilter;
- }
-
- /* Generate all the surfaces */
- tmpW = EdgeLength;
- for (i = 0; i < object->baseTexture.levels; i++) {
-
- /* Create the 6 faces */
- for (j = 0; j < 6; j++) {
- static const GLenum cube_targets[6] = {
- GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
- };
-
- hr = IWineD3DDeviceParent_CreateSurface(This->device_parent, parent, tmpW, tmpW,
- Format, Usage, Pool, i /* Level */, j, &object->surfaces[j][i]);
- if (FAILED(hr))
- {
- FIXME("(%p) Failed to create surface\n",object);
- IWineD3DCubeTexture_Release((IWineD3DCubeTexture *)object);
- *ppCubeTexture = NULL;
- return hr;
- }
- IWineD3DSurface_SetContainer(object->surfaces[j][i], (IWineD3DBase *)object);
- TRACE("Created surface level %d @ %p,\n", i, object->surfaces[j][i]);
- surface_set_texture_target(object->surfaces[j][i], cube_targets[j]);
- }
- tmpW = max(1, tmpW >> 1);
- }
- object->baseTexture.internal_preload = cubetexture_internal_preload;
-
TRACE("(%p) : Created Cube Texture %p\n", This, object);
- *ppCubeTexture = (IWineD3DCubeTexture *) object;
+ *ppCubeTexture = (IWineD3DCubeTexture *)object;
+
return WINED3D_OK;
}
/* allocated the 'extended' data based on the type of query requested */
switch(Type){
case WINED3DQUERYTYPE_OCCLUSION:
- object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryOcclusionData));
- ((WineQueryOcclusionData *)(object->extendedData))->ctx = This->activeContext;
-
- if(GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
- TRACE("(%p) Allocating data for an occlusion query\n", This);
+ object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
+ ((struct wined3d_occlusion_query *)object->extendedData)->context = NULL;
+ break;
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
- ENTER_GL();
- GL_EXTCALL(glGenQueriesARB(1, &((WineQueryOcclusionData *)(object->extendedData))->queryId));
- LEAVE_GL();
- break;
- }
case WINED3DQUERYTYPE_EVENT:
- object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
- ((WineQueryEventData *)(object->extendedData))->ctx = This->activeContext;
-
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
- ENTER_GL();
- if(GL_SUPPORT(APPLE_FENCE)) {
- GL_EXTCALL(glGenFencesAPPLE(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
- checkGLcall("glGenFencesAPPLE");
- } else if(GL_SUPPORT(NV_FENCE)) {
- GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
- checkGLcall("glGenFencesNV");
- }
- LEAVE_GL();
+ object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_event_query));
+ ((struct wined3d_event_query *)object->extendedData)->context = NULL;
break;
case WINED3DQUERYTYPE_VCACHE:
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD *pFunction, IWineD3DVertexShader **ppVertexShader, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
+ const DWORD *pFunction, const struct wined3d_shader_signature *output_signature,
+ IWineD3DVertexShader **ppVertexShader, IUnknown *parent)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexShaderImpl *object; /* NOTE: impl usage is ok, this is a create */
HRESULT hr = WINED3D_OK;
TRACE("(%p) : Created vertex shader %p\n", This, *ppVertexShader);
- if (vertex_declaration) {
- IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
- }
-
- hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, NULL);
+ hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, output_signature);
if (FAILED(hr))
{
WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
bm.bmHeight = 32;
}
- hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5,
- TRUE, FALSE, 0, &This->logo_surface, WINED3DRTYPE_SURFACE, 0,
- WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL, NULL);
+ hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5, TRUE,
+ FALSE, 0, &This->logo_surface, 0, WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL, NULL);
if(FAILED(hr)) {
ERR("Wine logo requested, but failed to create surface\n");
goto out;
return;
}
+/* Context activation is done by the caller. */
static void create_dummy_textures(IWineD3DDeviceImpl *This) {
unsigned int i;
/* Under DirectX you can have texture stage operations even if no texture is
This->texUnitMap[state] = state;
This->rev_tex_unit_map[state] = state;
} else {
- This->texUnitMap[state] = -1;
- This->rev_tex_unit_map[state] = -1;
+ This->texUnitMap[state] = WINED3D_UNMAPPED_STAGE;
+ This->rev_tex_unit_map[state] = WINED3D_UNMAPPED_STAGE;
}
}
- /* Setup the implicit swapchain */
+ /* Setup the implicit swapchain. This also initializes a context. */
TRACE("Creating implicit swapchain\n");
hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent,
pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
if(swapchain->backBuffer && swapchain->backBuffer[0]) {
TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
This->render_targets[0] = swapchain->backBuffer[0];
- This->lastActiveRenderTarget = swapchain->backBuffer[0];
}
else {
TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer);
This->render_targets[0] = swapchain->frontBuffer;
- This->lastActiveRenderTarget = swapchain->frontBuffer;
}
IWineD3DSurface_AddRef(This->render_targets[0]);
- This->activeContext = swapchain->context[0];
- This->lastThread = GetCurrentThreadId();
/* Depth Stencil support */
This->stencilBufferTarget = This->auto_depth_stencil_buffer;
case ORM_BACKBUFFER:
{
- if(This->activeContext->aux_buffers > 0) {
+ if (context_get_current()->aux_buffers > 0)
+ {
TRACE("Using auxilliary buffer for offscreen rendering\n");
This->offscreenBuffer = GL_AUX0;
} else {
/* Clear the screen */
IWineD3DDevice_Clear((IWineD3DDevice *) This, 0, NULL,
WINED3DCLEAR_TARGET | pPresentationParameters->EnableAutoDepthStencil ? WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL : 0,
- 0x00, 1.0, 0);
+ 0x00, 1.0f, 0);
This->d3d_initialized = TRUE;
/* I don't think that the interface guarantees that the device is destroyed from the same thread
* it was created. Thus make sure a context is active for the glDelete* calls
*/
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
* private data, it might contain opengl pointers
*/
if(This->depth_blt_texture) {
+ ENTER_GL();
glDeleteTextures(1, &This->depth_blt_texture);
+ LEAVE_GL();
This->depth_blt_texture = 0;
}
if (This->depth_blt_rb) {
+ ENTER_GL();
GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+ LEAVE_GL();
This->depth_blt_rb = 0;
This->depth_blt_rb_w = 0;
This->depth_blt_rb_h = 0;
/* Incorrect attenuation values can cause the gl driver to crash. Happens with Need for speed
* most wanted
*/
- if(pLight->Attenuation0 < 0.0 || pLight->Attenuation1 < 0.0 || pLight->Attenuation2 < 0.0) {
+ if (pLight->Attenuation0 < 0.0f || pLight->Attenuation1 < 0.0f || pLight->Attenuation2 < 0.0f)
+ {
WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
object->lightPosn[0] = -pLight->Direction.x;
object->lightPosn[1] = -pLight->Direction.y;
object->lightPosn[2] = -pLight->Direction.z;
- object->lightPosn[3] = 0.0;
+ object->lightPosn[3] = 0.0f;
object->exponent = 0.0f;
object->cutoff = 180.0f;
break;
object->lightPosn[0] = pLight->Position.x;
object->lightPosn[1] = pLight->Position.y;
object->lightPosn[2] = pLight->Position.z;
- object->lightPosn[3] = 1.0;
+ object->lightPosn[3] = 1.0f;
/* Direction */
object->lightDirn[0] = pLight->Direction.x;
object->lightDirn[1] = pLight->Direction.y;
object->lightDirn[2] = pLight->Direction.z;
- object->lightDirn[3] = 1.0;
+ object->lightDirn[3] = 1.0f;
/*
* opengl-ish and d3d-ish spot lights use too different models for the
* will always be 1.0 for both of them, and we don't have to care for the
* rest of the rather complex calculation
*/
- object->exponent = 0;
+ object->exponent = 0.0f;
} else {
rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
- if (rho < 0.0001) rho = 0.0001f;
- object->exponent = -0.3/log(cos(rho/2));
+ if (rho < 0.0001f) rho = 0.0001f;
+ object->exponent = -0.3f/logf(cosf(rho/2));
}
- if (object->exponent > 128.0) {
- object->exponent = 128.0;
+ if (object->exponent > 128.0f)
+ {
+ object->exponent = 128.0f;
}
object->cutoff = pLight->Phi*90/M_PI;
struct list *e;
TRACE("(%p) : Idx(%d), enable? %d\n", This, Index, Enable);
- /* Tests show true = 128...not clear why */
- Enable = Enable? 128: 0;
-
LIST_FOR_EACH(e, &This->updateStateBlock->lightMap[Hi]) {
lightInfo = LIST_ENTRY(e, PLIGHTINFOEL, entry);
if(lightInfo->OriginalIndex == Index) break;
}
}
-static void device_map_stage(IWineD3DDeviceImpl *This, int stage, int unit) {
- int i = This->rev_tex_unit_map[unit];
- int j = This->texUnitMap[stage];
+static void device_map_stage(IWineD3DDeviceImpl *This, DWORD stage, DWORD unit)
+{
+ DWORD i = This->rev_tex_unit_map[unit];
+ DWORD j = This->texUnitMap[stage];
This->texUnitMap[stage] = unit;
- if (i != -1 && i != stage) {
- This->texUnitMap[i] = -1;
+ if (i != WINED3D_UNMAPPED_STAGE && i != stage)
+ {
+ This->texUnitMap[i] = WINED3D_UNMAPPED_STAGE;
}
This->rev_tex_unit_map[unit] = stage;
- if (j != -1 && j != unit) {
- This->rev_tex_unit_map[j] = -1;
+ if (j != WINED3D_UNMAPPED_STAGE && j != unit)
+ {
+ This->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE;
}
}
}
static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshader_sampler_tokens,
- const DWORD *vshader_sampler_tokens, int unit)
+ const DWORD *vshader_sampler_tokens, DWORD unit)
{
- int current_mapping = This->rev_tex_unit_map[unit];
+ DWORD current_mapping = This->rev_tex_unit_map[unit];
- if (current_mapping == -1) {
- /* Not currently used */
- return TRUE;
- }
+ /* Not currently used */
+ if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE;
if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
/* Used by a fragment sampler */
}
/* Used by a vertex sampler */
- return !vshader_sampler_tokens[current_mapping];
+ return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
}
static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
- int start = GL_LIMITS(combined_samplers) - 1;
+ int start = min(MAX_COMBINED_SAMPLERS, GL_LIMITS(combined_samplers)) - 1;
int i;
if (ps) {
}
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
- int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
+ DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
if (vshader_sampler_type[i])
{
if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
return WINED3D_OK;
}
+/* Context activation is done by the caller. */
#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount,
const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags,
BOOL doClip;
DWORD numTextures;
- if (stream_info->elements[WINED3D_FFP_NORMAL].data)
+ if (stream_info->use_map & (1 << WINED3D_FFP_NORMAL))
{
WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
}
- if (!stream_info->elements[WINED3D_FFP_POSITION].data)
+ if (!(stream_info->use_map & (1 << WINED3D_FFP_POSITION)))
{
ERR("Source has no position mask\n");
return WINED3DERR_INVALIDCALL;
TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
/* Multiplication with world, view and projection matrix */
- x = (p[0] * mat.u.s._11) + (p[1] * mat.u.s._21) + (p[2] * mat.u.s._31) + (1.0 * mat.u.s._41);
- y = (p[0] * mat.u.s._12) + (p[1] * mat.u.s._22) + (p[2] * mat.u.s._32) + (1.0 * mat.u.s._42);
- z = (p[0] * mat.u.s._13) + (p[1] * mat.u.s._23) + (p[2] * mat.u.s._33) + (1.0 * mat.u.s._43);
- rhw = (p[0] * mat.u.s._14) + (p[1] * mat.u.s._24) + (p[2] * mat.u.s._34) + (1.0 * mat.u.s._44);
+ x = (p[0] * mat.u.s._11) + (p[1] * mat.u.s._21) + (p[2] * mat.u.s._31) + (1.0f * mat.u.s._41);
+ y = (p[0] * mat.u.s._12) + (p[1] * mat.u.s._22) + (p[2] * mat.u.s._32) + (1.0f * mat.u.s._42);
+ z = (p[0] * mat.u.s._13) + (p[1] * mat.u.s._23) + (p[2] * mat.u.s._33) + (1.0f * mat.u.s._43);
+ rhw = (p[0] * mat.u.s._14) + (p[1] * mat.u.s._24) + (p[2] * mat.u.s._34) + (1.0f * mat.u.s._44);
TRACE("x=%f y=%f z=%f rhw=%f\n", x, y, z, rhw);
if( !doClip ||
( (-rhw -eps < x) && (-rhw -eps < y) && ( -eps < z) &&
- (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) &&
+ (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) &&
( rhw > eps ) ) ) {
/* "Normal" viewport transformation (not clipped)
if (DestFVF & WINED3DFVF_DIFFUSE) {
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE];
const DWORD *color_d = (const DWORD *)(element->data + i * element->stride);
- if(!color_d) {
+ if (!(stream_info->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ {
static BOOL warned = FALSE;
if(!warned) {
}
}
- if (DestFVF & WINED3DFVF_SPECULAR) {
+ if (DestFVF & WINED3DFVF_SPECULAR)
+ {
/* What's the color value in the feedback buffer? */
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR];
const DWORD *color_s = (const DWORD *)(element->data + i * element->stride);
- if(!color_s) {
+ if (!(stream_info->use_map & (1 << WINED3D_FFP_SPECULAR)))
+ {
static BOOL warned = FALSE;
if(!warned) {
for (tex_index = 0; tex_index < numTextures; tex_index++) {
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index];
const float *tex_coord = (const float *)(element->data + i * element->stride);
- if(!tex_coord) {
+ if (!(stream_info->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + tex_index))))
+ {
ERR("No source texture, but destination requests one\n");
dest_ptr+=GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
if(dest_conv) dest_conv += GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
}
/* Need any context to write to the vbo. */
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
/* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP
* control the streamIsUP flag, thus restore it afterwards.
*/
for (i = 0; i < (sizeof(stream_info.elements) / sizeof(*stream_info.elements)); ++i)
{
- struct wined3d_stream_info_element *e = &stream_info.elements[i];
+ struct wined3d_stream_info_element *e;
+
+ if (!(stream_info.use_map & (1 << i))) continue;
+
+ e = &stream_info.elements[i];
if (e->buffer_object)
{
struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
return WINED3DERR_INVALIDCALL;
}
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
/* We only have to do this if we need to read the, swapbuffers performs a flush for us */
- glFlush();
+ wglFlush();
/* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever
* fails
*/
UINT drawable_width, drawable_height;
IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
IWineD3DSwapChainImpl *swapchain = NULL;
+ struct wined3d_context *context;
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
* drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
}
}
- target->get_drawable_size(target, &drawable_width, &drawable_height);
+ context = ActivateContext(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR);
+
+ target->get_drawable_size(context, &drawable_width, &drawable_height);
- ActivateContext(This, (IWineD3DSurface *) target, CTXUSAGE_CLEAR);
ENTER_GL();
/* Only set the values up once, as they are not changing */
}
if (Flags & WINED3DCLEAR_ZBUFFER) {
- DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+ DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
glDepthMask(GL_TRUE);
glClearDepth(Z);
checkGLcall("glClearDepth");
if (vp->X != 0 || vp->Y != 0 ||
vp->Width < depth_stencil->currentDesc.Width || vp->Height < depth_stencil->currentDesc.Height) {
- surface_load_ds_location(This->stencilBufferTarget, location);
+ surface_load_ds_location(This->stencilBufferTarget, context, location);
}
else if (This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && (
This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 ||
This->stateBlock->scissorRect.right < depth_stencil->currentDesc.Width ||
This->stateBlock->scissorRect.bottom < depth_stencil->currentDesc.Height)) {
- surface_load_ds_location(This->stencilBufferTarget, location);
+ surface_load_ds_location(This->stencilBufferTarget, context, location);
}
else if (Count > 0 && pRects && (
pRects[0].x1 > 0 || pRects[0].y1 > 0 ||
pRects[0].x2 < depth_stencil->currentDesc.Width ||
pRects[0].y2 < depth_stencil->currentDesc.Height)) {
- surface_load_ds_location(This->stencilBufferTarget, location);
+ surface_load_ds_location(This->stencilBufferTarget, context, location);
}
}
if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect);
}
- if(This->render_offscreen) {
+ if (context->render_offscreen)
+ {
glScissor(vp_rect.left, vp_rect.top,
vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top);
} else {
continue;
}
- if(This->render_offscreen) {
+ if (context->render_offscreen)
+ {
glScissor(curRect.x1, curRect.y1,
curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
} else {
/* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists,
* it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it
*/
- IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
}
if (Flags & WINED3DCLEAR_ZBUFFER) {
/* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */
- DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+ DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
surface_modify_ds_location(This->stencilBufferTarget, location);
}
if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
if (target == (IWineD3DSurfaceImpl*) swapchain->frontBuffer) {
- glFlush();
+ wglFlush();
}
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
}
* NOTE: move code to surface to accomplish this
****************************************/
IWineD3DSurfaceImpl *pSrcSurface = (IWineD3DSurfaceImpl *)pSourceSurface;
+ IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)pDestinationSurface;
int srcWidth, srcHeight;
unsigned int srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, destSurfaceHeight;
WINED3DFORMAT destFormat, srcFormat;
WINED3DPOOL srcPool, destPool;
int offset = 0;
int rowoffset = 0; /* how many bytes to add onto the end of a row to wraparound to the beginning of the next */
- glDescriptor *glDescription = NULL;
const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc;
GLenum dummy;
- int sampler;
+ DWORD sampler;
int bpp;
CONVERT_TYPES convert = NO_CONVERSION;
WINED3DSURFACE_DESC winedesc;
TRACE("(%p) : Source (%p) Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
- memset(&winedesc, 0, sizeof(winedesc));
- winedesc.Width = &srcSurfaceWidth;
- winedesc.Height = &srcSurfaceHeight;
- winedesc.Pool = &srcPool;
- winedesc.Format = &srcFormat;
IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
-
- winedesc.Width = &destSurfaceWidth;
- winedesc.Height = &destSurfaceHeight;
- winedesc.Pool = &destPool;
- winedesc.Format = &destFormat;
- winedesc.Size = &destSize;
+ srcSurfaceWidth = winedesc.width;
+ srcSurfaceHeight = winedesc.height;
+ srcPool = winedesc.pool;
+ srcFormat = winedesc.format;
IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
+ destSurfaceWidth = winedesc.width;
+ destSurfaceHeight = winedesc.height;
+ destPool = winedesc.pool;
+ destFormat = winedesc.format;
+ destSize = winedesc.size;
if(srcPool != WINED3DPOOL_SYSTEMMEM || destPool != WINED3DPOOL_DEFAULT){
WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface);
* destination's sysmem copy. If surface conversion is needed, use BltFast instead to
* copy in sysmem and use regular surface loading.
*/
- d3dfmt_get_conv((IWineD3DSurfaceImpl *) pDestinationSurface, FALSE, TRUE,
- &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
+ d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
if(convert != NO_CONVERSION) {
return IWineD3DSurface_BltFast(pDestinationSurface,
pDestPoint ? pDestPoint->x : 0,
IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
}
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
surface_internal_preload(pDestinationSurface, SRGB_RGB);
IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
- IWineD3DSurface_GetGlDesc(pDestinationSurface, &glDescription);
-
src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc;
- dst_format_desc = ((IWineD3DSurfaceImpl *)pDestinationSurface)->resource.format_desc;
+ dst_format_desc = dst_impl->resource.format_desc;
/* this needs to be done in lines if the sourceRect != the sourceWidth */
srcWidth = pSourceRect ? pSourceRect->right - pSourceRect->left : srcSurfaceWidth;
offset += pSourceRect->top * srcSurfaceWidth * src_format_desc->byte_count;
}
TRACE("(%p) glTexSubImage2D, level %d, left %d, top %d, width %d, height %d, fmt %#x, type %#x, memory %p+%#x\n",
- This, glDescription->level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
+ This, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset);
/* Sanity check */
for (j = destTop; j < (srcHeight + destTop); ++j)
{
- glTexSubImage2D(glDescription->target, glDescription->level, destLeft, j,
+ glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j,
srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data);
data += rowoffset;
}
} else { /* Full width, so just write out the whole texture */
const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
- if (WINED3DFMT_DXT1 == destFormat ||
- WINED3DFMT_DXT2 == destFormat ||
- WINED3DFMT_DXT3 == destFormat ||
- WINED3DFMT_DXT4 == destFormat ||
- WINED3DFMT_DXT5 == destFormat) {
- if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
- if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth) {
- /* FIXME: The easy way to do this is to lock the destination, and copy the bits across */
- FIXME("Updating part of a compressed texture is not supported at the moment\n");
- } if (destFormat != srcFormat) {
- FIXME("Updating mixed format compressed texture is not curretly support\n");
- } else {
- GL_EXTCALL(glCompressedTexImage2DARB(glDescription->target, glDescription->level,
- dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data));
- }
- } else {
- FIXME("Attempting to update a DXT compressed texture without hardware support\n");
+ if (dst_format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth)
+ {
+ /* FIXME: The easy way to do this is to lock the destination, and copy the bits across. */
+ FIXME("Updating part of a compressed texture is not supported.\n");
}
-
-
- } else {
- glTexSubImage2D(glDescription->target, glDescription->level, destLeft, destTop,
+ if (destFormat != srcFormat)
+ {
+ FIXME("Updating mixed format compressed textures is not supported.\n");
+ }
+ else
+ {
+ GL_EXTCALL(glCompressedTexImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
+ dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data));
+ }
+ }
+ else
+ {
+ glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop,
srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data);
}
}
IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE);
sampler = This->rev_tex_unit_map[0];
- if (sampler != -1) {
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ {
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
}
const WINED3DRECT *rect, const float color[4])
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+ struct wined3d_context *context;
IWineD3DSwapChain *swapchain;
swapchain = get_swapchain(surface);
TRACE("Surface %p is onscreen\n", surface);
- ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
+ context = ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
- GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+ context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
buffer = surface_get_gl_buffer(surface, swapchain);
glDrawBuffer(buffer);
checkGLcall("glDrawBuffer()");
} else {
TRACE("Surface %p is offscreen\n", surface);
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
- context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
- context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, surface);
- GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
- checkGLcall("glFramebufferRenderbufferEXT");
+ context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
+ context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, surface);
+ context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE);
}
if (rect) {
glClear(GL_COLOR_BUFFER_BIT);
checkGLcall("glClear");
- if (This->activeContext->current_fbo) {
- context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->current_fbo->id);
- } else {
- GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
- checkGLcall("glBindFramebuffer()");
- }
-
if (swapchain && surface == ((IWineD3DSwapChainImpl *)swapchain)->frontBuffer
&& ((IWineD3DSwapChainImpl *)swapchain)->backBuffer) {
glDrawBuffer(GL_BACK);
BltFx.dwSize = sizeof(BltFx);
BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format);
return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL,
- WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+ WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
}
}
WARN("Converting to WINED3DCOLOR, this might give incorrect results\n");
- c = ((DWORD)(color[2] * 255.0));
- c |= ((DWORD)(color[1] * 255.0)) << 8;
- c |= ((DWORD)(color[0] * 255.0)) << 16;
- c |= ((DWORD)(color[3] * 255.0)) << 24;
+ c = ((DWORD)(color[2] * 255.0f));
+ c |= ((DWORD)(color[1] * 255.0f)) << 8;
+ c |= ((DWORD)(color[0] * 255.0f)) << 16;
+ c |= ((DWORD)(color[3] * 255.0f)) << 24;
/* Just forward this to the DirectDraw blitting engine */
memset(&BltFx, 0, sizeof(BltFx));
BltFx.dwSize = sizeof(BltFx);
BltFx.u5.dwFillColor = argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format);
- hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+ hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
if (FAILED(hr))
{
ERR("Blt failed, hr %#x\n", hr);
/* What to do about the context here in the case of multithreading? Not sure.
* This function is called by IDirect3D7::CreateDevice so in theory its initialization code
*/
+ WARN("No active context?\n");
+
ENTER_GL();
if(!Swapchain->backBuffer[0]) {
/* GL was told to draw to the front buffer at creation,
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
IWineD3DSwapChain *src_swapchain, *dst_swapchain;
+ struct wined3d_context *context;
GLenum gl_filter;
POINT offset = {0, 0};
/* Attach src surface to src fbo */
src_swapchain = get_swapchain(src_surface);
+ dst_swapchain = get_swapchain(dst_surface);
+
+ if (src_swapchain) context = ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD);
+ else if (dst_swapchain) context = ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);
+ else context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
if (src_swapchain) {
GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
TRACE("Source surface %p is onscreen\n", src_surface);
- ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD);
/* Make sure the drawable is up to date. In the offscreen case
* attach_surface_fbo() implicitly takes care of this. */
IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
}
ENTER_GL();
- GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
+ context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL);
glReadBuffer(buffer);
checkGLcall("glReadBuffer()");
} else {
TRACE("Source surface %p is offscreen\n", src_surface);
ENTER_GL();
- context_bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
- context_attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
+ context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, &context->src_fbo);
+ context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
checkGLcall("glReadBuffer()");
- GL_EXTCALL(glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
- checkGLcall("glFramebufferRenderbufferEXT");
+ context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL, FALSE);
}
LEAVE_GL();
/* Attach dst surface to dst fbo */
- dst_swapchain = get_swapchain(dst_surface);
if (dst_swapchain) {
GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
TRACE("Destination surface %p is onscreen\n", dst_surface);
- ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);
/* Make sure the drawable is up to date. In the offscreen case
* attach_surface_fbo() implicitly takes care of this. */
IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
}
ENTER_GL();
- GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
+ context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL);
glDrawBuffer(buffer);
checkGLcall("glDrawBuffer()");
} else {
TRACE("Destination surface %p is offscreen\n", dst_surface);
- /* No src or dst swapchain? Make sure some context is active(multithreading) */
- if(!src_swapchain) {
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
- }
-
ENTER_GL();
- context_bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
- context_attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
+ context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, &context->dst_fbo);
+ context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
checkGLcall("glDrawBuffer()");
- GL_EXTCALL(glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
- checkGLcall("glFramebufferRenderbufferEXT");
+ context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL, FALSE);
}
glDisable(GL_SCISSOR_TEST);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
- if (This->activeContext->current_fbo) {
- context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->current_fbo->id);
- } else {
- GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
- checkGLcall("glBindFramebuffer()");
- }
-
/* If we switched from GL_BACK to GL_FRONT above, we need to switch back here */
if (dst_swapchain && dst_surface == ((IWineD3DSwapChainImpl *)dst_swapchain)->frontBuffer
&& ((IWineD3DSwapChainImpl *)dst_swapchain)->backBuffer) {
viewport.MaxZ = 1.0f;
viewport.MinZ = 0.0f;
IWineD3DDeviceImpl_SetViewport(iface, &viewport);
- /* Make sure the viewport state is dirty, because the render_offscreen thing affects it.
- * SetViewport may catch NOP viewport changes, which would occur when switching between equally sized targets
- */
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VIEWPORT);
}
return WINED3D_OK;
}
|| ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) {
surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED);
} else {
- ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
- surface_load_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
+ struct wined3d_context *context = ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
+ surface_load_ds_location(This->stencilBufferTarget, context, SFLAG_DS_OFFSCREEN);
surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
}
}
/* some basic validation checks */
if(This->cursorTexture) {
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
glDeleteTextures(1, &This->cursorTexture);
LEAVE_GL();
INT height = This->cursorHeight;
INT width = This->cursorWidth;
INT bpp = glDesc->byte_count;
- INT i, sampler;
+ DWORD sampler;
+ INT i;
/* Reformat the texture memory (pitch and width can be
* different) */
for(i = 0; i < height; i++)
memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp);
IWineD3DSurface_UnlockRect(pCursorBitmap);
+
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
ENTER_GL();
if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
checkGLcall("glActiveTextureARB");
sampler = This->rev_tex_unit_map[0];
- if (sampler != -1) {
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ {
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
}
/* Create a new cursor texture */
return WINED3DERR_DRIVERINTERNALERROR;
}
+static HRESULT WINAPI evict_managed_resource(IWineD3DResource *resource, void *data) {
+ TRACE("checking resource %p for eviction\n", resource);
+ if(((IWineD3DResourceImpl *) resource)->resource.pool == WINED3DPOOL_MANAGED) {
+ TRACE("Evicting %p\n", resource);
+ IWineD3DResource_UnLoad(resource);
+ }
+ IWineD3DResource_Release(resource);
+ return S_OK;
+}
static HRESULT WINAPI IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice* iface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
- /** FIXME: Resource tracking needs to be done,
- * The closes we can do to this is set the priorities of all managed textures low
- * and then reset them.
- ***********************************************************/
- FIXME("(%p) : stub\n", This);
+ TRACE("(%p)\n", This);
+
+ IWineD3DDevice_EnumResources(iface, evict_managed_resource, NULL);
return WINED3D_OK;
}
surface->glRect.right = surface->pow2Width;
surface->glRect.bottom = surface->pow2Height;
- if(surface->glDescription.textureName) {
- ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ if (surface->texture_name)
+ {
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
- glDeleteTextures(1, &surface->glDescription.textureName);
+ glDeleteTextures(1, &surface->texture_name);
LEAVE_GL();
- surface->glDescription.textureName = 0;
+ surface->texture_name = 0;
surface->Flags &= ~SFLAG_CLIENT;
}
if(surface->pow2Width != pPresentationParameters->BackBufferWidth ||
UINT i;
IWineD3DBaseShaderImpl *shader;
+ ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) {
This->shader_backend->shader_destroy((IWineD3DBaseShader *) shader);
while(This->numContexts) {
DestroyContext(This, This->contexts[0]);
}
- This->activeContext = NULL;
HeapFree(GetProcessHeap(), 0, swapchain->context);
swapchain->context = NULL;
swapchain->num_contexts = 0;
swapchain->context[0] = CreateContext(This, target, swapchain->win_handle, FALSE,
&swapchain->presentParms);
swapchain->num_contexts = 1;
- This->activeContext = swapchain->context[0];
create_dummy_textures(This);
* any handles to other resource held by the caller must be closed
* (e.g. a texture should release all held surfaces because telling the device that it's been released.)
*****************************************************/
-static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource){
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
+{
+ TRACE("(%p) : Adding resource %p\n", This, resource);
- TRACE("(%p) : Adding Resource %p\n", This, resource);
list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
}
-static void IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWineD3DResource *resource){
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
+static void device_resource_remove(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
+{
TRACE("(%p) : Removing resource %p\n", This, resource);
list_remove(&((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
}
-
-static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DResource *resource){
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
+{
WINED3DRESOURCETYPE type = IWineD3DResource_GetType(resource);
int counter;
TRACE("(%p) : resource %p\n", This, resource);
- context_resource_released(iface, resource, type);
+ context_resource_released((IWineD3DDevice *)This, resource, type);
switch (type) {
/* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */
case WINED3DRTYPE_SURFACE: {
unsigned int i;
- /* Cleanup any FBO attachments if d3d is enabled */
- if(This->d3d_initialized) {
- if((IWineD3DSurface *)resource == This->lastActiveRenderTarget) {
- IWineD3DSwapChainImpl *swapchain = This->swapchains ? (IWineD3DSwapChainImpl *) This->swapchains[0] : NULL;
-
- TRACE("Last active render target destroyed\n");
- /* Find a replacement surface for the currently active back buffer. The context manager does not do NULL
- * checks, so switch to a valid target as long as the currently set surface is still valid. Use the
- * surface of the implicit swpchain. If that is the same as the destroyed surface the device is destroyed
- * and the lastActiveRenderTarget member shouldn't matter
- */
- if(swapchain) {
- if(swapchain->backBuffer && swapchain->backBuffer[0] != (IWineD3DSurface *)resource) {
- TRACE("Activating primary back buffer\n");
- ActivateContext(This, swapchain->backBuffer[0], CTXUSAGE_RESOURCELOAD);
- } else if(!swapchain->backBuffer && swapchain->frontBuffer != (IWineD3DSurface *)resource) {
- /* Single buffering environment */
- TRACE("Activating primary front buffer\n");
- ActivateContext(This, swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD);
- } else {
- TRACE("Device is being destroyed, setting lastActiveRenderTarget = 0xdeadbabe\n");
- /* Implicit render target destroyed, that means the device is being destroyed
- * whatever we set here, it shouldn't matter
- */
- This->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadbabe;
- }
- } else {
- /* May happen during ddraw uninitialization */
- TRACE("Render target set, but swapchain does not exist!\n");
- This->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadcafe;
- }
- }
-
+ if (This->d3d_initialized)
+ {
for (i = 0; i < GL_LIMITS(buffers); ++i) {
if (This->render_targets[i] == (IWineD3DSurface *)resource) {
This->render_targets[i] = NULL;
/* Remove the resource from the resourceStore */
- IWineD3DDeviceImpl_RemoveResource(iface, resource);
+ device_resource_remove(This, resource);
TRACE("Resource released\n");
IWineD3DDeviceImpl_UpdateSurface,
IWineD3DDeviceImpl_GetFrontBufferData,
/*** object tracking ***/
- IWineD3DDeviceImpl_ResourceReleased,
IWineD3DDeviceImpl_EnumResources
};
void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
DWORD rep = This->StateTable[state].representative;
+ struct wined3d_context *context;
DWORD idx;
BYTE shift;
UINT i;
- WineD3DContext *context;
- if(!rep) return;
for(i = 0; i < This->numContexts; i++) {
context = This->contexts[i];
if(isStateDirty(context, rep)) continue;
}
}
-void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
- IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice;
- /* The drawable size of a pbuffer render target is the current pbuffer size
- */
- *width = dev->pbufferWidth;
- *height = dev->pbufferHeight;
+void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height)
+{
+ IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.wineD3DDevice;
+ /* The drawable size of a pbuffer render target is the current pbuffer size. */
+ *width = device->pbufferWidth;
+ *height = device->pbufferHeight;
}
-void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
- /* The drawable size of a fbo target is the opengl texture size, which is the power of two size
- */
- *width = This->pow2Width;
- *height = This->pow2Height;
+void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height)
+{
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt;
+ /* The drawable size of a fbo target is the opengl texture size, which is the power of two size. */
+ *width = surface->pow2Width;
+ *height = surface->pow2Height;
}
-void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
- IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice;
+void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height)
+{
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface;
/* The drawable size of a backbuffer / aux buffer offscreen target is the size of the
* current context's drawable, which is the size of the back buffer of the swapchain
* the active context belongs to. The back buffer of the swapchain is stored as the
- * surface the context belongs to.
- */
- *width = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Width;
- *height = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Height;
+ * surface the context belongs to. */
+ *width = surface->currentDesc.Width;
+ *height = surface->currentDesc.Height;
}