if (t->free_entries)
{
+ DWORD index = t->free_entries - t->entries;
/* Use a free handle */
entry = t->free_entries;
if (entry->type != D3D8_HANDLE_FREE)
{
- ERR("Handle %u(%p) is in the free list, but has type %#x.\n", (entry - t->entries), entry, entry->type);
+ ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type);
return D3D8_INVALID_HANDLE;
}
t->free_entries = entry->object;
entry->object = object;
entry->type = type;
- return entry - t->entries;
+ return index;
}
if (!(t->entry_count < t->table_size))
HeapFree(GetProcessHeap(), 0, This->decls);
IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroySwapChain);
+ IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice);
IWineD3DDevice_Release(This->WineD3DDevice);
HeapFree(GetProcessHeap(), 0, This->handle_table.entries);
HeapFree(GetProcessHeap(), 0, This);
device_parent_CreateSwapChain,
};
+static void setup_fpu(void)
+{
+ WORD cw;
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ __asm__ volatile ("fnstcw %0" : "=m" (cw));
+ cw = (cw & ~0xf3f) | 0x3f;
+ __asm__ volatile ("fldcw %0" : : "m" (cw));
+#else
+ FIXME("FPU setup not implemented for this platform.\n");
+#endif
+}
+
HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapter,
D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
{
}
device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
+ if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
+
wined3d_mutex_lock();
hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device,
(IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice);
return hr;
}
+ if (!parameters->Windowed)
+ {
+ if (!focus_window) focus_window = parameters->hDeviceWindow;
+ if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window)))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ IWineD3DDevice_Release(device->WineD3DDevice);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ return hr;
+ }
+ }
+
if (flags & D3DCREATE_MULTITHREADED) IWineD3DDevice_SetMultithreaded(device->WineD3DDevice);
wined3d_parameters.BackBufferWidth = parameters->BackBufferWidth;
if (FAILED(hr))
{
WARN("Failed to initialize 3D, hr %#x.\n", hr);
+ IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
IWineD3DDevice_Release(device->WineD3DDevice);
wined3d_mutex_unlock();
HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
err:
wined3d_mutex_lock();
IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D8CB_DestroySwapChain);
+ IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
IWineD3DDevice_Release(device->WineD3DDevice);
wined3d_mutex_unlock();
HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
HeapFree(GetProcessHeap(), 0, This->convertedDecls);
IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroySwapChain);
+ IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice);
IWineD3DDevice_Release(This->WineD3DDevice);
wined3d_mutex_unlock();
device_parent_CreateSwapChain,
};
+static void setup_fpu(void)
+{
+ WORD cw;
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ __asm__ volatile ("fnstcw %0" : "=m" (cw));
+ cw = (cw & ~0xf3f) | 0x3f;
+ __asm__ volatile ("fldcw %0" : : "m" (cw));
+#else
+ FIXME("FPU setup not implemented for this platform.\n");
+#endif
+}
+
HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type,
HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
{
device->device_parent_vtbl = &d3d9_wined3d_device_parent_vtbl;
device->ref = 1;
+ if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
+
wined3d_mutex_lock();
hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device,
(IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice);
return hr;
}
+ if (!parameters->Windowed)
+ {
+ if (!focus_window) focus_window = parameters->hDeviceWindow;
+ if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window)))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ IWineD3DDevice_Release(device->WineD3DDevice);
+ wined3d_mutex_unlock();
+ return hr;
+ }
+ }
+
if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
{
WINED3DCAPS caps;
if (FAILED(hr))
{
WARN("Failed to initialize 3D, hr %#x.\n", hr);
+ IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
HeapFree(GetProcessHeap(), 0, wined3d_parameters);
IWineD3DDevice_Release(device->WineD3DDevice);
wined3d_mutex_unlock();
ERR("Failed to allocate FVF vertex declaration map memory.\n");
wined3d_mutex_lock();
IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D9CB_DestroySwapChain);
+ IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
IWineD3DDevice_Release(device->WineD3DDevice);
wined3d_mutex_unlock();
return E_OUTOFMEMORY;
void
IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
{
- /* Clear the cooplevel to restore window and display mode */
IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)This, NULL, DDSCL_NORMAL);
+ IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)This);
/* Destroy the device window if we created one */
if(This->devicewindow != 0)
/* Switching from fullscreen? */
if(This->cooperative_level & DDSCL_FULLSCREEN)
{
- /* Restore the display mode */
- IDirectDraw7_RestoreDisplayMode(iface);
-
This->cooperative_level &= ~DDSCL_FULLSCREEN;
This->cooperative_level &= ~DDSCL_EXCLUSIVE;
This->cooperative_level &= ~DDSCL_ALLOWMODEX;
+
+ IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice);
}
/* Don't override focus windows or private device windows */
!(This->devicewindow) &&
(hwnd != window) )
{
+ HRESULT hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd);
+ if (FAILED(hr))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ LeaveCriticalSection(&ddraw_cs);
+ return hr;
+ }
This->dest_window = hwnd;
}
}
IDirectDrawSurface7 **Surface)
{
IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
- FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface);
+ IWineD3DSurface *wined3d_surface;
+ HRESULT hr;
+
+ TRACE("iface %p, dc %p, surface %p.\n", iface, hdc, Surface);
- /* Implementation idea if needed: Loop through all surfaces and compare
- * their hdc with hdc. Implement it in WineD3D! */
- return DDERR_NOTFOUND;
+ if (!Surface) return E_INVALIDARG;
+
+ hr = IWineD3DDevice_GetSurfaceFromDC(This->wineD3DDevice, hdc, &wined3d_surface);
+ if (FAILED(hr))
+ {
+ TRACE("No surface found for dc %p.\n", hdc);
+ *Surface = NULL;
+ return DDERR_NOTFOUND;
+ }
+
+ IWineD3DSurface_GetParent(wined3d_surface, (IUnknown **)Surface);
+ TRACE("Returning surface %p.\n", Surface);
+ return DD_OK;
}
/*****************************************************************************
set_surf_version(impl, 1);
IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This));
impl->ifaceToRelease = NULL;
+
return hr;
}
*ppSurface = NULL;
return hr;
}
+
impl = (IDirectDrawSurfaceImpl *)pSurface7;
*ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
set_surf_version(impl, 2);
IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This));
impl->ifaceToRelease = NULL;
+
return hr;
}
case D3DRENDERSTATE_TEXTUREMIN:
{
WINED3DTEXTUREFILTERTYPE tex_min;
+ WINED3DTEXTUREFILTERTYPE tex_mip;
hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
- 0, WINED3DSAMP_MINFILTER,
- &tex_min);
+ 0, WINED3DSAMP_MINFILTER, &tex_min);
+ if (FAILED(hr))
+ {
+ LeaveCriticalSection(&ddraw_cs);
+ return hr;
+ }
+ hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
+ 0, WINED3DSAMP_MIPFILTER, &tex_mip);
switch (tex_min)
{
case WINED3DTEXF_POINT:
- *Value = D3DFILTER_NEAREST;
+ switch (tex_mip)
+ {
+ case WINED3DTEXF_NONE:
+ *Value = D3DFILTER_NEAREST;
+ break;
+ case WINED3DTEXF_POINT:
+ *Value = D3DFILTER_MIPNEAREST;
+ break;
+ case WINED3DTEXF_LINEAR:
+ *Value = D3DFILTER_LINEARMIPNEAREST;
+ break;
+ default:
+ ERR("Unhandled mip filter %#x.\n", tex_mip);
+ *Value = D3DFILTER_NEAREST;
+ break;
+ }
break;
case WINED3DTEXF_LINEAR:
- *Value = D3DFILTER_LINEAR;
+ switch (tex_mip)
+ {
+ case WINED3DTEXF_NONE:
+ *Value = D3DFILTER_LINEAR;
+ break;
+ case WINED3DTEXF_POINT:
+ *Value = D3DFILTER_MIPLINEAR;
+ break;
+ case WINED3DTEXF_LINEAR:
+ *Value = D3DFILTER_LINEARMIPLINEAR;
+ break;
+ default:
+ ERR("Unhandled mip filter %#x.\n", tex_mip);
+ *Value = D3DFILTER_LINEAR;
+ break;
+ }
break;
default:
- ERR("Unhandled texture mag %d !\n",tex_min);
- *Value = 0;
+ ERR("Unhandled texture min filter %#x.\n",tex_min);
+ *Value = D3DFILTER_NEAREST;
+ break;
}
break;
}
Value);
break;
+ case D3DRENDERSTATE_BORDERCOLOR:
+ FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
+ hr = E_NOTIMPL;
+ break;
+
default:
- /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
+ if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
+ && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
+ {
+ FIXME("Unhandled stipple pattern render state (%#x).\n",
+ RenderStateType);
+ hr = E_NOTIMPL;
+ break;
+ }
hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
RenderStateType,
Value);
/* Some render states need special care */
switch(RenderStateType)
{
+ /*
+ * The ddraw texture filter mapping works like this:
+ * D3DFILTER_NEAREST Point min/mag, no mip
+ * D3DFILTER_MIPNEAREST Point min/mag, point mip
+ * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
+ *
+ * D3DFILTER_LINEAR Linear min/mag, no mip
+ * D3DFILTER_MIPLINEAR Linear min/mag, point mip
+ * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
+ *
+ * This is the opposite of the GL naming convention,
+ * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
+ */
case D3DRENDERSTATE_TEXTUREMAG:
{
- WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT;
+ WINED3DTEXTUREFILTERTYPE tex_mag;
- switch ((D3DTEXTUREFILTER) Value)
+ switch (Value)
{
case D3DFILTER_NEAREST:
+ case D3DFILTER_MIPNEAREST:
case D3DFILTER_LINEARMIPNEAREST:
tex_mag = WINED3DTEXF_POINT;
break;
case D3DFILTER_LINEAR:
+ case D3DFILTER_MIPLINEAR:
case D3DFILTER_LINEARMIPLINEAR:
tex_mag = WINED3DTEXF_LINEAR;
break;
default:
+ tex_mag = WINED3DTEXF_POINT;
ERR("Unhandled texture mag %d !\n",Value);
+ break;
}
hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
case D3DRENDERSTATE_TEXTUREMIN:
{
- WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT;
- WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
+ WINED3DTEXTUREFILTERTYPE tex_min;
+ WINED3DTEXTUREFILTERTYPE tex_mip;
switch ((D3DTEXTUREFILTER) Value)
{
case D3DFILTER_NEAREST:
tex_min = WINED3DTEXF_POINT;
+ tex_mip = WINED3DTEXF_NONE;
break;
case D3DFILTER_LINEAR:
tex_min = WINED3DTEXF_LINEAR;
+ tex_mip = WINED3DTEXF_NONE;
break;
case D3DFILTER_MIPNEAREST:
tex_min = WINED3DTEXF_POINT;
tex_mip = WINED3DTEXF_POINT;
break;
case D3DFILTER_MIPLINEAR:
- tex_min = WINED3DTEXF_POINT;
- tex_mip = WINED3DTEXF_LINEAR;
+ tex_min = WINED3DTEXF_LINEAR;
+ tex_mip = WINED3DTEXF_POINT;
break;
case D3DFILTER_LINEARMIPNEAREST:
tex_min = WINED3DTEXF_POINT;
default:
ERR("Unhandled texture min %d !\n",Value);
+ tex_min = WINED3DTEXF_POINT;
+ tex_mip = WINED3DTEXF_NONE;
+ break;
}
- IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
- 0, WINED3DSAMP_MIPFILTER,
- tex_mip);
+ IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
+ 0, WINED3DSAMP_MIPFILTER, tex_mip);
hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
0, WINED3DSAMP_MINFILTER,
tex_min);
Value);
break;
- default:
+ case D3DRENDERSTATE_BORDERCOLOR:
+ /* This should probably just forward to the corresponding sampler
+ * state. Needs tests. */
+ FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
+ hr = E_NOTIMPL;
+ break;
- /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
+ default:
+ if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
+ && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
+ {
+ FIXME("Unhandled stipple pattern render state (%#x).\n",
+ RenderStateType);
+ hr = E_NOTIMPL;
+ break;
+ }
hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
RenderStateType,
/* Copy the results into the d3d7 and d3d3 structures */
Desc7->dwDevCaps = WCaps.DevCaps;
+ Desc7->dpcLineCaps.dwMiscCaps = WCaps.PrimitiveMiscCaps;
Desc7->dpcLineCaps.dwRasterCaps = WCaps.RasterCaps;
Desc7->dpcLineCaps.dwZCmpCaps = WCaps.ZCmpCaps;
Desc7->dpcLineCaps.dwSrcBlendCaps = WCaps.SrcBlendCaps;
memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX));
} else {
- ERR("Unhandled vertex processing !\n");
+ ERR("Unhandled vertex processing flag %#x.\n", ci->dwFlags);
}
instr += size;
TRACE("(%p)->(%p)\n", This, lpDesc);
dwSize = lpDesc->dwSize;
- memset(lpDesc, 0, dwSize);
memcpy(lpDesc, &This->desc, dwSize);
if (TRACE_ON(d3d7)) {
TRACE("(%p)->(%p): stub!\n", This, lpData);
dwSize = lpData->dwSize;
- memset(lpData, 0, dwSize);
memcpy(lpData, &This->data, dwSize);
if (TRACE_ON(d3d7)) {
/* Let's hope we never need this ;) */
if(wineD3DDevice) IWineD3DDevice_Release(wineD3DDevice);
if(wineD3D) IWineD3D_Release(wineD3D);
- if(This) HeapFree(GetProcessHeap(), 0, This->decls);
+ HeapFree(GetProcessHeap(), 0, This->decls);
HeapFree(GetProcessHeap(), 0, This);
return hr;
}
/* Copies the material structure */
EnterCriticalSection(&ddraw_cs);
dwSize = lpMat->dwSize;
- memset(lpMat, 0, dwSize);
memcpy(lpMat, &This->mat, dwSize);
LeaveCriticalSection(&ddraw_cs);
DDPixelFormat->u2.dwRBitMask = 0x00E0;
DDPixelFormat->u3.dwGBitMask = 0x001C;
DDPixelFormat->u4.dwBBitMask = 0x0003;
- DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000;
+ DDPixelFormat->u5.dwRGBAlphaBitMask = 0xFF00;
break;
case WINED3DFMT_B4G4R4X4_UNORM:
DDPixelFormat->u3.dwGBitMask = 0x00F0;
DDPixelFormat->u4.dwBBitMask = 0x000F;
DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
- return;
+ break;
/* How are Z buffer bit depth and Stencil buffer bit depth related?
*/
DDPixelFormat->u3.dwZBitMask = 0x00FFFFFFFF;
DDPixelFormat->u4.dwStencilBitMask = 0x00000000;
DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0;
-
break;
+
case WINED3DFMT_S1_UINT_D15_UNORM:
DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER;
DDPixelFormat->dwFourCC = 0;
WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION (*gl_info)
-
/* Extract a line. Note that this modifies the source string. */
static char *get_line(char **ptr)
{
static void shader_arb_dump_program_source(const char *source)
{
- unsigned long source_size;
+ ULONG source_size;
char *ptr, *line, *tmp;
source_size = strlen(source) + 1;
tmp = HeapAlloc(GetProcessHeap(), 0, source_size);
if (!tmp)
{
- ERR("Failed to allocate %lu bytes for shader source.\n", source_size);
+ ERR("Failed to allocate %u bytes for shader source.\n", source_size);
return;
}
memcpy(tmp, source, source_size);
}
/* GL locking for state handlers is done by the caller. */
-static BOOL need_mova_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info)
+static BOOL need_rel_addr_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info)
{
- IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) shader;
- if(!This->baseShader.reg_maps.usesmova) return FALSE;
+ if (shader->baseShader.reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX)
+ {
+ if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) return TRUE;
+ }
+ if (!shader->baseShader.reg_maps.usesmova) return FALSE;
return !gl_info->supported[NV_VERTEX_PROGRAM2_OPTION];
}
&& !(gl_info->quirks & WINED3D_QUIRK_NV_CLIP_BROKEN);
}
-static BOOL need_helper_const(const struct wined3d_gl_info *gl_info)
+static BOOL need_helper_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info)
{
- if (!gl_info->supported[NV_VERTEX_PROGRAM] /* Need to init colors. */
- || gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT /* Load the immval offset. */
- || gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W /* Have to init texcoords. */
- || (!use_nv_clip(gl_info)) /* Init the clip texcoord */)
- {
- return TRUE;
- }
+ if (need_rel_addr_const(shader, gl_info)) return TRUE;
+ if (!gl_info->supported[NV_VERTEX_PROGRAM]) return TRUE; /* Need to init colors. */
+ if (gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT) return TRUE; /* Load the immval offset. */
+ if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) return TRUE; /* Have to init texcoords. */
+ if (!use_nv_clip(gl_info)) return TRUE; /* Init the clip texcoord */
+ if (shader->baseShader.reg_maps.usesnrm) return TRUE; /* 0.0 */
+ if (shader->baseShader.reg_maps.usesrcp) return TRUE; /* EPS */
return FALSE;
}
-static unsigned int reserved_vs_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info)
+static unsigned int reserved_vs_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info)
{
unsigned int ret = 1;
/* We use one PARAM for the pos fixup, and in some cases one to load
* some immediate values into the shader
*/
- if(need_helper_const(gl_info)) ret++;
- if(need_mova_const(shader, gl_info)) ret++;
+ if(need_helper_const(shader, gl_info)) ret++;
+ if(need_rel_addr_const(shader, gl_info)) ret++;
return ret;
}
+enum arb_helper_value
+{
+ ARB_ZERO,
+ ARB_ONE,
+ ARB_TWO,
+ ARB_0001,
+ ARB_EPS,
+
+ ARB_VS_REL_OFFSET
+};
+
+static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum arb_helper_value value)
+{
+ if (shader == WINED3D_SHADER_TYPE_GEOMETRY)
+ {
+ ERR("Geometry shaders are unsupported\n");
+ return "bad";
+ }
+
+ if (shader == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ switch (value)
+ {
+ case ARB_ZERO: return "ps_helper_const.x";
+ case ARB_ONE: return "ps_helper_const.y";
+ case ARB_TWO: return "coefmul.x";
+ case ARB_0001: return "helper_const.xxxy";
+ case ARB_EPS: return "ps_helper_const.z";
+ default: break;
+ }
+ }
+ else
+ {
+ switch (value)
+ {
+ case ARB_ZERO: return "helper_const.x";
+ case ARB_ONE: return "helper_const.y";
+ case ARB_TWO: return "helper_const.z";
+ case ARB_EPS: return "helper_const.w";
+ case ARB_0001: return "helper_const.xxxy";
+ case ARB_VS_REL_OFFSET: return "rel_addr_const.y";
+ }
+ }
+ FIXME("Unmanaged %s shader helper constant requested: %u\n",
+ shader == WINED3D_SHADER_TYPE_PIXEL ? "pixel" : "vertex", value);
+ switch (value)
+ {
+ case ARB_ZERO: return "0.0";
+ case ARB_ONE: return "1.0";
+ case ARB_TWO: return "2.0";
+ case ARB_0001: return "{0.0, 0.0, 0.0, 1.0}";
+ case ARB_EPS: return "1e-8";
+ default: return "bad";
+ }
+}
+
static inline BOOL ffp_clip_emul(IWineD3DStateBlockImpl *stateblock)
{
return stateblock->lowest_disabled_stage < 7;
const struct arb_ps_compiled_shader *compiled_fprog;
const struct arb_vs_compiled_shader *compiled_vprog;
GLuint depth_blt_vprogram_id;
- GLuint depth_blt_fprogram_id[tex_type_count];
+ GLuint depth_blt_fprogram_id_full[tex_type_count];
+ GLuint depth_blt_fprogram_id_masked[tex_type_count];
BOOL use_arbfp_fixed_func;
struct wine_rb_tree fragment_shaders;
BOOL last_ps_const_clamped;
*/
float val[4];
val[0] = context->render_offscreen ? 0.0f
- : ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height;
+ : deviceImpl->render_targets[0]->currentDesc.Height;
val[1] = context->render_offscreen ? 1.0f : -1.0f;
val[2] = 1.0f;
val[3] = 0.0f;
/* GL locking is done by the caller (state handler) */
static void shader_arb_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
+ IWineD3DDeviceImpl *device = context->swapchain->device;
IWineD3DStateBlockImpl* stateBlock = device->stateBlock;
const struct wined3d_gl_info *gl_info = context->gl_info;
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
- if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return;
+ if (!context || context->swapchain->device != This) return;
memset(context->vshader_const_dirty + start, 1, sizeof(*context->vshader_const_dirty) * count);
This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count);
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
- if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return;
+ if (!context || context->swapchain->device != This) return;
memset(context->pshader_const_dirty + start, 1, sizeof(*context->pshader_const_dirty) * count);
This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count);
if (pshader)
{
max_constantsF = gl_info->limits.arb_ps_native_constants;
+ /* 24 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value. */
+ if (max_constantsF < 24)
+ max_constantsF = gl_info->limits.arb_ps_float_constants;
}
else
{
+ max_constantsF = gl_info->limits.arb_vs_native_constants;
+ /* 96 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value.
+ * Also prevents max_constantsF from becoming less than 0 and
+ * wrapping . */
+ if (max_constantsF < 96)
+ max_constantsF = gl_info->limits.arb_vs_float_constants;
+
if(This->baseShader.reg_maps.usesrelconstF) {
DWORD highest_constf = 0, clip_limit;
- max_constantsF = gl_info->limits.arb_vs_native_constants - reserved_vs_const(iface, gl_info);
+
+ max_constantsF -= reserved_vs_const(This, gl_info);
max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants);
for(i = 0; i < This->baseShader.limits.constant_float; i++)
{
if (ctx->target_version >= NV2) *num_clipplanes = gl_info->limits.clipplanes;
else *num_clipplanes = min(gl_info->limits.clipplanes, 4);
- max_constantsF = gl_info->limits.arb_vs_native_constants;
}
}
if (pshader)
{
gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
- "one", "coefmul.x", priv->cur_ps_args->super.color_fixup[sampler_idx]);
+ arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_ONE),
+ arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_TWO),
+ priv->cur_ps_args->super.color_fixup[sampler_idx]);
}
}
int insert_line;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+ const char *two = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_TWO);
/* Assume a new line will be added */
insert_line = 1;
shader_addline(buffer, "ADD T%c, -%s, coefdiv.x;\n", 'A' + tmpreg, regstr);
break;
case WINED3DSPSM_SIGN:
- shader_addline(buffer, "MAD T%c, %s, coefmul.x, -one.x;\n", 'A' + tmpreg, regstr);
+ shader_addline(buffer, "MAD T%c, %s, %s, -%s;\n", 'A' + tmpreg, regstr, two, one);
break;
case WINED3DSPSM_SIGNNEG:
- shader_addline(buffer, "MAD T%c, %s, -coefmul.x, one.x;\n", 'A' + tmpreg, regstr);
+ shader_addline(buffer, "MAD T%c, %s, %s, %s;\n", 'A' + tmpreg, regstr, two, one);
break;
case WINED3DSPSM_COMP:
- shader_addline(buffer, "SUB T%c, one.x, %s;\n", 'A' + tmpreg, regstr);
+ shader_addline(buffer, "SUB T%c, %s, %s;\n", 'A' + tmpreg, one, regstr);
break;
case WINED3DSPSM_X2:
shader_addline(buffer, "ADD T%c, %s, %s;\n", 'A' + tmpreg, regstr, regstr);
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
BOOL pshader = shader_is_pshader_version(shader->baseShader.reg_maps.shader_version.type);
struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+ const char *zero = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_ONE);
+ const char *two = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_TWO);
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
char src0_param[256];
if(ins->handler_idx == WINED3DSIH_MOVA) {
char write_mask[6];
+ const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET);
if(ctx->target_version >= NV2) {
shader_hw_map2gl(ins);
* The ARL is performed when A0 is used - the requested component is read from A0_SHADOW into
* A0.x. We can use the overwritten component of A0_shadow as temporary storage for the sign.
*/
- shader_addline(buffer, "SGE A0_SHADOW%s, %s, mova_const.y;\n", write_mask, src0_param);
- shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, mova_const.z, -mova_const.w;\n", write_mask);
+ shader_addline(buffer, "SGE A0_SHADOW%s, %s, %s;\n", write_mask, src0_param, zero);
+ shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, %s, -%s;\n", write_mask, two, one);
shader_addline(buffer, "ABS TA%s, %s;\n", write_mask, src0_param);
- shader_addline(buffer, "ADD TA%s, TA, mova_const.x;\n", write_mask);
+ shader_addline(buffer, "ADD TA%s, TA, rel_addr_const.x;\n", write_mask);
shader_addline(buffer, "FLR TA%s, TA;\n", write_mask);
if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
{
- shader_addline(buffer, "ADD TA%s, TA, helper_const.z;\n", write_mask);
+ shader_addline(buffer, "ADD TA%s, TA, %s;\n", write_mask, offset);
}
shader_addline(buffer, "MUL A0_SHADOW%s, TA, A0_SHADOW;\n", write_mask);
src0_param[0] = '\0';
if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
{
+ const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET);
shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
- shader_addline(buffer, "ADD TA.x, %s, helper_const.z;\n", src0_param);
+ shader_addline(buffer, "ADD TA.x, %s, %s;\n", src0_param, offset);
shader_addline(buffer, "ARL A0.x, TA.x;\n");
}
else
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
char dst_name[50];
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
/* texdepth has an implicit destination, the fragment depth value. It's only parameter,
* which is essentially an input, is the destination register because it is the first
/* According to the msdn, the source register(must be r5) is unusable after
* the texdepth instruction, so we're free to modify it
*/
- shader_addline(buffer, "MIN %s.y, %s.y, one.y;\n", dst_name, dst_name);
+ shader_addline(buffer, "MIN %s.y, %s.y, %s;\n", dst_name, dst_name, one);
/* How to deal with the special case dst_name.g == 0? if r != 0, then
* the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
*/
shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
shader_addline(buffer, "MUL TA.x, %s.x, %s.y;\n", dst_name, dst_name);
- shader_addline(buffer, "MIN TA.x, TA.x, one.x;\n");
- shader_addline(buffer, "MAX result.depth, TA.x, 0.0;\n");
+ shader_addline(buffer, "MIN TA.x, TA.x, %s;\n", one);
+ shader_addline(buffer, "MAX result.depth, TA.x, %s;\n", zero);
}
/** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
char src0[50], dst_name[50];
BOOL is_color;
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
*/
shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
shader_addline(buffer, "MUL %s.x, %s.x, %s.y;\n", dst_name, dst_name, dst_name);
- shader_addline(buffer, "MIN %s.x, %s.x, one.x;\n", dst_name, dst_name);
- shader_addline(buffer, "MAX result.depth, %s.x, 0.0;\n", dst_name);
+ shader_addline(buffer, "MIN %s.x, %s.x, %s;\n", dst_name, dst_name, one);
+ shader_addline(buffer, "MAX result.depth, %s.x, %s;\n", dst_name, zero);
}
/** Handles transforming all WINED3DSIO_M?x? opcodes for
}
}
+static void shader_hw_rcp(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const char *flt_eps = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_EPS);
+
+ char dst[50];
+ char src[50];
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src);
+ if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE)
+ {
+ /* Dx sdk says .x is used if no swizzle is given, but our test shows that
+ * .w is used
+ */
+ strcat(src, ".w");
+ }
+
+ /* TODO: If the destination is readable, and not the same as the source, the destination
+ * can be used instead of TA
+ */
+ if (priv->target_version >= NV2)
+ {
+ shader_addline(buffer, "MOVC TA.x, %s;\n", src);
+ shader_addline(buffer, "MOV TA.x (EQ.x), %s;\n", flt_eps);
+ shader_addline(buffer, "RCP%s %s, TA.x;\n", shader_arb_get_modifier(ins), dst);
+ }
+ else
+ {
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+ shader_addline(buffer, "ABS TA.x, %s;\n", src);
+ shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero);
+ shader_addline(buffer, "MAD TA.x, TA.y, %s, %s;\n", flt_eps, src);
+ shader_addline(buffer, "RCP%s %s, TA.x;\n", shader_arb_get_modifier(ins), dst);
+ }
+}
+
static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins)
{
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
char src_name[50];
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
shader_arb_get_src_param(ins, &ins->src[0], 1 /* Use TB */, src_name);
+ /* In D3D, NRM of a vector with length zero returns zero. Catch this situation, as
+ * otherwise NRM or RSQ would return NaN */
if(pshader && priv->target_version >= NV3)
{
+ /* GL_NV_fragment_program2's NRM needs protection against length zero vectors too
+ *
+ * TODO: Find out if DP3+NRM+MOV is really faster than DP3+RSQ+MUL
+ */
+ shader_addline(buffer, "DP3C TA, %s, %s;\n", src_name, src_name);
shader_addline(buffer, "NRM%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name);
+ shader_addline(buffer, "MOV %s (EQ), %s;\n", dst_name, zero);
+ }
+ else if(priv->target_version >= NV2)
+ {
+ shader_addline(buffer, "DP3C TA.x, %s, %s;\n", src_name, src_name);
+ shader_addline(buffer, "RSQ TA.x (NE), TA.x;\n");
+ shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name,
+ src_name);
}
else
{
- shader_addline(buffer, "DP3 TA, %s, %s;\n", src_name, src_name);
- shader_addline(buffer, "RSQ TA, TA.x;\n");
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+
+ shader_addline(buffer, "DP3 TA.x, %s, %s;\n", src_name, src_name);
+ /* Pass any non-zero value to RSQ if the input vector has a length of zero. The
+ * RSQ result doesn't matter, as long as multiplying it by 0 returns 0.
+ */
+ shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero);
+ shader_addline(buffer, "MAD TA.x, %s, TA.y, TA.x;\n", one);
+
+ shader_addline(buffer, "RSQ TA.x, TA.x;\n");
/* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
- shader_addline(buffer, "MUL%s %s, %s, TA;\n", shader_arb_get_modifier(ins), dst_name,
+ shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name,
src_name);
}
}
{
unsigned int cur_clip = 0;
char component[4] = {'x', 'y', 'z', 'w'};
+ const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO);
for (i = 0; i < gl_info->limits.clipplanes; ++i)
{
switch(cur_clip)
{
case 0:
- shader_addline(buffer, "MOV TA, -helper_const.w;\n");
+ shader_addline(buffer, "MOV TA, %s;\n", zero);
break;
case 1:
- shader_addline(buffer, "MOV TA.yzw, -helper_const.w;\n");
+ shader_addline(buffer, "MOV TA.yzw, %s;\n", zero);
break;
case 2:
- shader_addline(buffer, "MOV TA.zw, -helper_const.w;\n");
+ shader_addline(buffer, "MOV TA.zw, %s;\n", zero);
break;
case 3:
- shader_addline(buffer, "MOV TA.w, -helper_const.w;\n");
+ shader_addline(buffer, "MOV TA.w, %s;\n", zero);
break;
}
shader_addline(buffer, "MOV result.texcoord[%u], TA;\n",
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
* and the glsl equivalent
*/
- if(need_helper_const(gl_info)) {
- shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, helper_const.x, -TMP_OUT.w;\n");
+ if(need_helper_const((IWineD3DBaseShaderImpl *) This, gl_info)) {
+ const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO);
+ shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two);
} else {
shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n");
shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n");
}
/* GL locking is done by the caller */
-static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, enum tex_types tex_type)
+static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info,
+ enum tex_types tex_type, BOOL masked)
{
GLuint program_id = 0;
+ const char *fprogram;
GLint pos;
- static const char * const blt_fprograms[tex_type_count] =
+ static const char * const blt_fprograms_full[tex_type_count] =
+ {
+ /* tex_1d */
+ NULL,
+ /* tex_2d */
+ "!!ARBfp1.0\n"
+ "TEMP R0;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ /* tex_3d */
+ NULL,
+ /* tex_cube */
+ "!!ARBfp1.0\n"
+ "TEMP R0;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ /* tex_rect */
+ "!!ARBfp1.0\n"
+ "TEMP R0;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ };
+
+ static const char * const blt_fprograms_masked[tex_type_count] =
{
/* tex_1d */
NULL,
/* tex_2d */
"!!ARBfp1.0\n"
+ "PARAM mask = program.local[0];\n"
"TEMP R0;\n"
+ "SLT R0.xy, fragment.position, mask.zwzw;\n"
+ "MUL R0.x, R0.x, R0.y;\n"
+ "KIL -R0.x;\n"
"TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n"
"MOV result.depth.z, R0.x;\n"
"END\n",
NULL,
/* tex_cube */
"!!ARBfp1.0\n"
+ "PARAM mask = program.local[0];\n"
"TEMP R0;\n"
+ "SLT R0.xy, fragment.position, mask.zwzw;\n"
+ "MUL R0.x, R0.x, R0.y;\n"
+ "KIL -R0.x;\n"
"TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
"MOV result.depth.z, R0.x;\n"
"END\n",
/* tex_rect */
"!!ARBfp1.0\n"
+ "PARAM mask = program.local[0];\n"
"TEMP R0;\n"
+ "SLT R0.xy, fragment.position, mask.zwzw;\n"
+ "MUL R0.x, R0.x, R0.y;\n"
+ "KIL -R0.x;\n"
"TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n"
"MOV result.depth.z, R0.x;\n"
"END\n",
};
- if (!blt_fprograms[tex_type])
+ fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type];
+ if (!fprogram)
{
- FIXME("tex_type %#x not supported\n", tex_type);
+ FIXME("tex_type %#x not supported, falling back to tex_2d\n", tex_type);
tex_type = tex_2d;
+ fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type];
}
GL_EXTCALL(glGenProgramsARB(1, &program_id));
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id));
- GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(blt_fprograms[tex_type]), blt_fprograms[tex_type]));
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fprogram), fprogram));
checkGLcall("glProgramStringARB()");
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
{
FIXME("Fragment program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
- shader_arb_dump_program_source(blt_fprograms[tex_type]);
+ shader_arb_dump_program_source(fprogram);
}
else
{
char fragcolor[16];
DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This), next_local, cur;
struct shader_arb_ctx_priv priv_ctx;
- BOOL dcl_tmp = args->super.srgb_correction, dcl_td = FALSE;
+ BOOL dcl_td = FALSE;
BOOL want_nv_prog = FALSE;
struct arb_pshader_private *shader_priv = This->baseShader.backend_data;
GLint errPos;
}
switch(found) {
- case 4: dcl_tmp = FALSE; break;
case 0:
sprintf(srgbtmp[0], "TA");
sprintf(srgbtmp[1], "TB");
case 3:
sprintf(srgbtmp[3], "TA");
break;
+ case 4:
+ break;
}
/* Create the hw ARB shader */
if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */
shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
- shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
+ shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %1.10f, 0.0 };\n", eps);
if (reg_maps->shader_version.major < 2)
{
}
shader_addline(buffer, "TEMP TMP_OUT;\n");
- if(need_helper_const(gl_info)) {
- shader_addline(buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset);
+ if(need_helper_const((IWineD3DBaseShaderImpl *) This, gl_info)) {
+ shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %1.10f};\n", eps);
}
- if(need_mova_const((IWineD3DBaseShader *) This, gl_info)) {
- shader_addline(buffer, "PARAM mova_const = { 0.5, 0.0, 2.0, 1.0 };\n");
+ if(need_rel_addr_const((IWineD3DBaseShaderImpl *) This, gl_info)) {
+ shader_addline(buffer, "PARAM rel_addr_const = { 0.5, %d.0, 0.0, 0.0 };\n", This->rel_offset);
shader_addline(buffer, "TEMP A0_SHADOW;\n");
}
*/
if (!gl_info->supported[NV_VERTEX_PROGRAM])
{
- shader_addline(buffer, "MOV result.color.secondary, -helper_const.wwwy;\n");
+ const char *color_init = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_0001);
+ shader_addline(buffer, "MOV result.color.secondary, %s;\n", color_init);
if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W && !device->frag_pipe->ffp_proj_control)
{
int i;
- for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) {
- if(This->baseShader.reg_maps.texcoord_mask[i] != 0 &&
+ const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE);
+ for(i = 0; i < min(8, MAX_REG_TEXCRD); i++)
+ {
+ if (This->baseShader.reg_maps.texcoord_mask[i] != 0 &&
This->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) {
- shader_addline(buffer, "MOV result.texcoord[%u].w, -helper_const.y;\n", i);
+ shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one);
}
}
}
/* GL locking is done by the caller */
static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS)
{
- IWineD3DDeviceImpl *This = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
+ IWineD3DDeviceImpl *This = context->swapchain->device;
struct shader_arb_priv *priv = This->shader_priv;
const struct wined3d_gl_info *gl_info = context->gl_info;
int i;
}
/* GL locking is done by the caller */
-static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
+static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size)
+{
+ const float mask[] = {0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy};
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ BOOL masked = ds_mask_size->cx && ds_mask_size->cy;
struct shader_arb_priv *priv = This->shader_priv;
- GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+ GLuint *blt_fprogram;
if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info);
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id));
glEnable(GL_VERTEX_PROGRAM_ARB);
- if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type);
+ blt_fprogram = masked ? &priv->depth_blt_fprogram_id_masked[tex_type] : &priv->depth_blt_fprogram_id_full[tex_type];
+ if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type, masked);
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *blt_fprogram));
+ if (masked) GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, mask));
glEnable(GL_FRAGMENT_PROGRAM_ARB);
}
if (shader_data->num_gl_shaders)
{
- struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ struct wined3d_context *context = context_acquire(device, NULL);
ENTER_GL();
for (i = 0; i < shader_data->num_gl_shaders; ++i)
if (shader_data->num_gl_shaders)
{
- struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ struct wined3d_context *context = context_acquire(device, NULL);
ENTER_GL();
for (i = 0; i < shader_data->num_gl_shaders; ++i)
if(priv->depth_blt_vprogram_id) {
GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id));
}
- for (i = 0; i < tex_type_count; ++i) {
- if (priv->depth_blt_fprogram_id[i]) {
- GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i]));
+ for (i = 0; i < tex_type_count; ++i)
+ {
+ if (priv->depth_blt_fprogram_id_full[i])
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_full[i]));
+ }
+ if (priv->depth_blt_fprogram_id_masked[i])
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_masked[i]));
}
}
LEAVE_GL();
static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
{
- DWORD vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants);
- DWORD ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants);
-
- /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
- * then overwrite the shader specific ones
- */
- none_shader_backend.shader_get_caps(gl_info, pCaps);
-
if (gl_info->supported[ARB_VERTEX_PROGRAM])
{
+ DWORD vs_consts;
+
+ /* 96 is the minimum allowed value of MAX_PROGRAM_ENV_PARAMETERS_ARB
+ * for vertex programs. If the native limit is less than that it's
+ * not very useful, and e.g. Mesa swrast returns 0, probably to
+ * indicate it's a software implementation. */
+ if (gl_info->limits.arb_vs_native_constants < 96)
+ vs_consts = gl_info->limits.arb_vs_float_constants;
+ else
+ vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants);
+
if (gl_info->supported[NV_VERTEX_PROGRAM3])
{
pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
}
pCaps->MaxVertexShaderConst = vs_consts;
}
+ else
+ {
+ pCaps->VertexShaderVersion = 0;
+ pCaps->MaxVertexShaderConst = 0;
+ }
if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
{
+ DWORD ps_consts;
+
+ /* Similar as above for vertex programs, but the minimum for fragment
+ * programs is 24. */
+ if (gl_info->limits.arb_ps_native_constants < 24)
+ ps_consts = gl_info->limits.arb_ps_float_constants;
+ else
+ ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants);
+
if (gl_info->supported[NV_FRAGMENT_PROGRAM2])
{
pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
pCaps->PixelShader1xMaxValue = 8.0f;
pCaps->MaxPixelShaderConst = ps_consts;
}
+ else
+ {
+ pCaps->PixelShaderVersion = 0;
+ pCaps->PixelShader1xMaxValue = 0.0f;
+ pCaps->MaxPixelShaderConst = 0;
+ }
pCaps->VSClipping = use_nv_clip(gl_info);
}
/* WINED3DSIH_NRM */ shader_hw_nrm,
/* WINED3DSIH_PHASE */ NULL,
/* WINED3DSIH_POW */ shader_hw_log_pow,
- /* WINED3DSIH_RCP */ shader_hw_scalar_op,
+ /* WINED3DSIH_RCP */ shader_hw_rcp,
/* WINED3DSIH_REP */ shader_hw_rep,
/* WINED3DSIH_RET */ shader_hw_ret,
/* WINED3DSIH_RSQ */ shader_hw_scalar_op,
static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
WINED3DTEXOPCAPS_SELECTARG1 |
WINED3DTEXOPCAPS_SELECTARG2 |
caps->MaxTextureBlendStages = 8;
caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8);
-
- caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
}
-#undef GLINFO_LOCATION
-#define GLINFO_LOCATION stateblock->device->adapter->gl_info
static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *device = stateblock->device;
float col[4];
static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *device = stateblock->device;
float col[4];
static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *device = stateblock->device;
float mat[2][2];
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
* anyway
*/
- if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) {
- device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context);
- }
+ if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT))
+ stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context);
}
if(device->shader_backend == &arb_program_shader_backend) {
static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *device = stateblock->device;
float param[4];
/* The pixel shader has to know the luminance offset. Do a constants update if it
* isn't scheduled anyway
*/
- if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) {
- device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context);
- }
+ if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT))
+ stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context);
}
if(device->shader_backend == &arb_program_shader_backend) {
}
}
-/* The stateblock is passed for GLINFO_LOCATION */
static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock)
{
+ const struct wined3d_gl_info *gl_info = &stateblock->device->adapter->gl_info;
unsigned int stage;
struct wined3d_shader_buffer buffer;
BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *device = stateblock->device;
struct shader_arb_priv *priv = device->fragment_priv;
BOOL use_pshader = use_ps(stateblock);
return;
}
new_desc->num_textures_used = 0;
- for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < gl_info->limits.texture_stages; ++i)
{
if(settings.op[i].cop == WINED3DTOP_DISABLE) break;
new_desc->num_textures_used = i;
if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
device->shader_backend->shader_select(context, use_pshader, use_vshader);
- if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
- device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
- }
- }
- if(use_pshader) {
- device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context);
+ if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
+ stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context);
}
+ if (use_pshader) stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context);
}
/* We can't link the fog states to the fragment state directly since the vertex pipeline links them
}
}
-#undef GLINFO_LOCATION
-
static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {
{STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
{STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
{STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
{STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
{STATE_PIXELSHADER, { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, WINED3D_GL_EXT_NONE },
TRUE /* We can disable projected textures */
};
-#define GLINFO_LOCATION device->adapter->gl_info
-
struct arbfp_blit_priv {
GLenum yuy2_rect_shader, yuy2_2d_shader;
GLenum uyvy_rect_shader, uyvy_2d_shader;
GLenum yv12_rect_shader, yv12_2d_shader;
GLenum p8_rect_shader, p8_2d_shader;
+ GLuint palette_texture;
};
static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) {
/* Context activation is done by the caller. */
static void arbfp_blit_free(IWineD3DDevice *iface) {
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct arbfp_blit_priv *priv = device->blit_priv;
ENTER_GL();
GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader));
checkGLcall("Delete yuv and p8 programs");
+
+ if(priv->palette_texture) glDeleteTextures(1, &priv->palette_texture);
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, device->blit_priv);
static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype)
{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
GLenum shader;
struct wined3d_shader_buffer buffer;
struct arbfp_blit_priv *priv = device->blit_priv;
return shader;
}
+/* Context activation is done by the caller. */
+static void upload_palette(IWineD3DSurfaceImpl *surface)
+{
+ BYTE table[256][4];
+ IWineD3DDeviceImpl *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct arbfp_blit_priv *priv = device->blit_priv;
+ BOOL colorkey = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) ? TRUE : FALSE;
+
+ d3dfmt_p8_init_palette(surface, table, colorkey);
+
+ ENTER_GL();
+ if (!priv->palette_texture)
+ glGenTextures(1, &priv->palette_texture);
+
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
+ glBindTexture(GL_TEXTURE_1D, priv->palette_texture);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ /* Make sure we have discrete color levels. */
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ /* Upload the palette */
+ /* TODO: avoid unneeed uploads in the future by adding some SFLAG_PALETTE_DIRTY mechanism */
+ glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table);
+
+ /* Switch back to unit 0 in which the 2D texture will be stored. */
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0));
+ LEAVE_GL();
+}
+
/* Context activation is done by the caller. */
static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_fixup, GLenum textype)
{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
GLenum shader;
struct wined3d_shader_buffer buffer;
char luminance_component;
}
/* Context activation is done by the caller. */
-static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
- GLenum textype, UINT width, UINT height)
+static HRESULT arbfp_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface)
{
GLenum shader;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
- float size[4] = {width, height, 1, 1};
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ float size[4] = {surface->pow2Width, surface->pow2Height, 1, 1};
struct arbfp_blit_priv *priv = device->blit_priv;
enum complex_fixup fixup;
+ GLenum textype = surface->texture_target;
- if (!is_complex_fixup(format_desc->color_fixup))
+ if (!is_complex_fixup(surface->resource.format_desc->color_fixup))
{
TRACE("Fixup:\n");
- dump_color_fixup_desc(format_desc->color_fixup);
+ dump_color_fixup_desc(surface->resource.format_desc->color_fixup);
/* Don't bother setting up a shader for unconverted formats */
ENTER_GL();
glEnable(textype);
return WINED3D_OK;
}
- fixup = get_complex_fixup(format_desc->color_fixup);
+ fixup = get_complex_fixup(surface->resource.format_desc->color_fixup);
switch(fixup)
{
case COMPLEX_FIXUP_P8:
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader;
if (!shader) shader = gen_p8_shader(device, textype);
+
+ upload_palette(surface);
break;
default:
LEAVE_GL();
}
-static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup)
+static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+ const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+ const struct wined3d_format_desc *src_format_desc,
+ const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+ const struct wined3d_format_desc *dst_format_desc)
{
- enum complex_fixup complex_fixup;
+ enum complex_fixup src_fixup;
+
+ if (blit_op != BLIT_OP_BLIT)
+ {
+ TRACE("Unsupported blit_op=%d\n", blit_op);
+ return FALSE;
+ }
+ src_fixup = get_complex_fixup(src_format_desc->color_fixup);
if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
- dump_color_fixup_desc(fixup);
+ dump_color_fixup_desc(src_format_desc->color_fixup);
}
- if (is_identity_fixup(fixup))
+ if (!is_identity_fixup(dst_format_desc->color_fixup))
+ {
+ TRACE("Destination fixups are not supported\n");
+ return FALSE;
+ }
+
+ if (is_identity_fixup(src_format_desc->color_fixup))
{
TRACE("[OK]\n");
return TRUE;
}
- /* We only support YUV conversions. */
- if (!is_complex_fixup(fixup))
+ /* We only support YUV conversions. */
+ if (!is_complex_fixup(src_format_desc->color_fixup))
{
TRACE("[FAILED]\n");
return FALSE;
}
- complex_fixup = get_complex_fixup(fixup);
- switch(complex_fixup)
+ switch(src_fixup)
{
case COMPLEX_FIXUP_YUY2:
case COMPLEX_FIXUP_UYVY:
return TRUE;
default:
- FIXME("Unsupported YUV fixup %#x\n", complex_fixup);
+ FIXME("Unsupported YUV fixup %#x\n", src_fixup);
TRACE("[FAILED]\n");
return FALSE;
}
}
+HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect,
+ IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op,
+ DWORD Filter)
+{
+ IWineD3DSwapChainImpl *dst_swapchain;
+ struct wined3d_context *context;
+ RECT dst_rect = *dst_rect_in;
+
+ /* Now load the surface */
+ surface_internal_preload(src_surface, SRGB_RGB);
+
+ /* Activate the destination context, set it up for blitting */
+ context = context_acquire(device, dst_surface);
+ context_apply_blit_state(context, device);
+
+ /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates',
+ * while OpenGL coordinates are window relative.
+ * Also beware of the origin difference(top left vs bottom left).
+ * Also beware that the front buffer's surface size is screen width x screen height,
+ * whereas the real gl drawable size is the size of the window. */
+ dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL;
+ if (dst_swapchain && dst_surface == dst_swapchain->front_buffer)
+ surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect);
+
+ arbfp_blit_set((IWineD3DDevice *)device, src_surface);
+
+ ENTER_GL();
+
+ /* Draw a textured quad */
+ draw_textured_quad(src_surface, src_rect, &dst_rect, Filter);
+
+ LEAVE_GL();
+
+ /* Leave the opengl state valid for blitting */
+ arbfp_blit_unset((IWineD3DDevice *)device);
+
+ if (wined3d_settings.strict_draw_ordering || (dst_swapchain
+ && (dst_surface == dst_swapchain->front_buffer
+ || dst_swapchain->num_contexts > 1)))
+ wglFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE);
+ return WINED3D_OK;
+}
+
+static HRESULT arbfp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color)
+{
+ FIXME("Color filling not implemented by arbfp_blit\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
const struct blit_shader arbfp_blit = {
arbfp_blit_alloc,
arbfp_blit_free,
arbfp_blit_set,
arbfp_blit_unset,
- arbfp_blit_color_fixup_supported,
+ arbfp_blit_supported,
+ arbfp_blit_color_fill
};
-
-#undef GLINFO_LOCATION
default: return "Unexpected writemask";
}
}
-#define GLINFO_LOCATION (*gl_info)
static void wrap_op1(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
GLuint arg1, GLuint arg1Rep, GLuint arg1Mod)
checkGLcall("GL_EXTCALL(glEndFragmentShaderATI())");
return ret;
}
-#undef GLINFO_LOCATION
-#define GLINFO_LOCATION stateblock->device->adapter->gl_info
static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *This = stateblock->device;
const struct atifs_ffp_desc *desc;
struct ffp_frag_settings settings;
return;
}
new_desc->num_textures_used = 0;
- for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < gl_info->limits.texture_stages; ++i)
{
if(settings.op[i].cop == WINED3DTOP_DISABLE) break;
new_desc->num_textures_used = i;
}
memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
- new_desc->shader = gen_ati_shader(settings.op, context->gl_info);
+ new_desc->shader = gen_ati_shader(settings.op, gl_info);
add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent);
TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
desc = new_desc;
static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
float mat[2][2];
mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]);
if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
device->shader_backend->shader_select(context, FALSE, use_vshader);
- if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) {
- device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
- }
+ if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader)
+ stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context);
}
}
-#undef GLINFO_LOCATION
-
static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
{STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor_atifs }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
- {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
- {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
WINED3DTEXOPCAPS_SELECTARG1 |
WINED3DTEXOPCAPS_SELECTARG2 |
*/
caps->MaxTextureBlendStages = 8;
caps->MaxSimultaneousTextures = 6;
-
- caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
}
static HRESULT atifs_alloc(IWineD3DDevice *iface) {
return WINED3D_OK;
}
-#define GLINFO_LOCATION This->adapter->gl_info
/* Context activation is done by the caller. */
static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *context)
{
IWineD3DDeviceImpl *This = context;
+ const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry);
ENTER_GL();
HeapFree(GetProcessHeap(), 0, priv);
This->fragment_priv = NULL;
}
-#undef GLINFO_LOCATION
static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
{
WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
-HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type,
- IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
- WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
+HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count,
+ WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage,
+ const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent,
+ const struct wined3d_parent_ops *parent_ops)
{
HRESULT hr;
return hr;
}
- texture->baseTexture.levels = levels;
+ texture->baseTexture.sub_resources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ level_count * layer_count * sizeof(*texture->baseTexture.sub_resources));
+ if (!texture->baseTexture.sub_resources)
+ {
+ ERR("Failed to allocate sub-resource array.\n");
+ resource_cleanup((IWineD3DResource *)texture);
+ return E_OUTOFMEMORY;
+ }
+
+ texture->baseTexture.layer_count = layer_count;
+ texture->baseTexture.level_count = level_count;
texture->baseTexture.filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE;
texture->baseTexture.LOD = 0;
texture->baseTexture.texture_rgb.dirty = TRUE;
void basetexture_cleanup(IWineD3DBaseTexture *iface)
{
basetexture_unload(iface);
+ HeapFree(GetProcessHeap(), 0, ((IWineD3DBaseTextureImpl *)iface)->baseTexture.sub_resources);
resource_cleanup((IWineD3DResource *)iface);
}
+IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, UINT layer, UINT level)
+{
+ if (layer >= texture->baseTexture.layer_count)
+ {
+ WARN("layer %u >= layer_count %u.\n", layer, texture->baseTexture.layer_count);
+ return NULL;
+ }
+
+ if (level >= texture->baseTexture.level_count)
+ {
+ WARN("level %u >= level_count %u.\n", level, texture->baseTexture.level_count);
+ return NULL;
+ }
+
+ return texture->baseTexture.sub_resources[layer * texture->baseTexture.level_count + level];
+}
+
/* A GL context is provided by the caller */
static void gltexture_delete(struct gl_texture *tex)
{
if (This->baseTexture.texture_rgb.name || This->baseTexture.texture_srgb.name)
{
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
}
if(This->baseTexture.texture_rgb.name) {
return 0;
}
- if(LODNew >= This->baseTexture.levels)
- LODNew = This->baseTexture.levels - 1;
+ if (LODNew >= This->baseTexture.level_count)
+ LODNew = This->baseTexture.level_count - 1;
if(This->baseTexture.LOD != LODNew) {
This->baseTexture.LOD = LODNew;
DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface)
{
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
- TRACE("(%p) : returning %d\n", This, This->baseTexture.levels);
- return This->baseTexture.levels;
+ TRACE("iface %p, returning %u.\n", iface, This->baseTexture.level_count);
+ return This->baseTexture.level_count;
}
HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType)
* Or should we delay the applying until the texture is used for drawing? For now, apply
* immediately.
*/
- struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ struct wined3d_context *context = context_acquire(device, NULL);
ENTER_GL();
glBindTexture(textureDimensions, This->baseTexture.texture_rgb.name);
gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
- gl_tex->states[WINED3DTEXSTA_ELEMENTINDEX] = 0;
- gl_tex->states[WINED3DTEXSTA_DMAPOFFSET] = 0;
- gl_tex->states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
IWineD3DBaseTexture_SetDirty(iface, TRUE);
isNewTexture = TRUE;
* relying on the partial GL_ARB_texture_non_power_of_two emulation with texture rectangles
* (ie, do not care for cond_np2 here, just look for GL_TEXTURE_RECTANGLE_ARB)
*/
- if(textureDimensions != GL_TEXTURE_RECTANGLE_ARB) {
- TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
- glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
- checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
+ if (textureDimensions != GL_TEXTURE_RECTANGLE_ARB)
+ {
+ TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", This->baseTexture.level_count - 1);
+ glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count - 1);
+ checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count)");
}
if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
/* Cubemaps are always set to clamp, regardless of the sampler state. */
glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
- if(!cond_np2) {
- if(gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
+ if (!cond_np2)
+ {
+ if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE)
glValue = This->baseTexture.LOD;
- } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
- glValue = This->baseTexture.levels - 1;
- } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) {
+ else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.level_count)
+ glValue = This->baseTexture.level_count - 1;
+ else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD)
/* baseTexture.LOD is already clamped in the setter */
glValue = This->baseTexture.LOD;
- } else {
+ else
glValue = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL];
- }
+
/* Note that D3DSAMP_MAXMIPLEVEL specifies the biggest mipmap(default 0), while
* GL_TEXTURE_MAX_LEVEL specifies the smallest mimap used(default 1000).
* So D3DSAMP_MAXMIPLEVEL is the same as GL_TEXTURE_BASE_LEVEL.
}
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
}
+
+ if (!(This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW)
+ != !gl_tex->states[WINED3DTEXSTA_SHADOW])
+ {
+ if (This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW)
+ {
+ glTexParameteri(textureDimensions, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
+ glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
+ checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)");
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE;
+ }
+ else
+ {
+ glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)");
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+ }
+ }
}
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION This->resource.device->adapter->gl_info
-
#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */
#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */
#define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */
return FALSE;
}
+/* Context activation is done by the caller */
+static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
+{
+ if(!This->buffer_object) return;
+
+ ENTER_GL();
+ GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
+ checkGLcall("glDeleteBuffersARB");
+ LEAVE_GL();
+ This->buffer_object = 0;
+
+ if(This->query)
+ {
+ wined3d_event_query_destroy(This->query);
+ This->query = NULL;
+ }
+ This->flags &= ~WINED3D_BUFFER_APPLESYNC;
+}
+
/* Context activation is done by the caller. */
-static void buffer_create_buffer_object(struct wined3d_buffer *This)
+static void buffer_create_buffer_object(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
{
GLenum error, gl_usage;
- const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n",
This, debug_d3dusage(This->resource.usage));
GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)");
This->flags |= WINED3D_BUFFER_FLUSH;
+
+ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
+ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)");
+ This->flags |= WINED3D_BUFFER_APPLESYNC;
}
/* No setup is needed here for GL_ARB_map_buffer_range */
}
fail:
/* Clean up all vbo init, but continue because we can work without a vbo :-) */
ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n");
- if (This->buffer_object)
- {
- ENTER_GL();
- GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
- LEAVE_GL();
- }
- This->buffer_object = 0;
+ delete_gl_buffer(This, gl_info);
buffer_clear_dirty_areas(This);
}
attrib_size = attrib->format_desc->component_count * attrib->format_desc->component_size;
for (i = 0; i < attrib_size; ++i)
{
- if (This->conversion_map[data + i] != conversion_type)
+ DWORD_PTR idx = (data + i) % This->stride;
+ if (This->conversion_map[idx] != conversion_type)
{
- TRACE("Byte %ld in vertex changed\n", i + data);
- TRACE("It was type %d, is %d now\n", This->conversion_map[data + i], conversion_type);
+ TRACE("Byte %ld in vertex changed\n", idx);
+ TRACE("It was type %d, is %d now\n", This->conversion_map[idx], conversion_type);
ret = TRUE;
- This->conversion_map[data + i] = conversion_type;
+ This->conversion_map[idx] = conversion_type;
}
}
}
/* Context activation is done by the caller. */
-static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
+static void buffer_check_buffer_object_size(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
{
UINT size = This->conversion_stride ?
This->conversion_stride * (This->resource.size / This->stride) : This->resource.size;
/* Rescue the data before resizing the buffer object if we do not have our backup copy */
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
- buffer_get_sysmem(This);
+ buffer_get_sysmem(This, gl_info);
}
ENTER_GL();
}
/* Context activation is done by the caller. */
-const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object)
+const BYTE *buffer_get_memory(IWineD3DBuffer *iface, const struct wined3d_gl_info *gl_info, GLuint *buffer_object)
{
struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
{
if (This->flags & WINED3D_BUFFER_CREATEBO)
{
- buffer_create_buffer_object(This);
+ buffer_create_buffer_object(This, gl_info);
This->flags &= ~WINED3D_BUFFER_CREATEBO;
if (This->buffer_object)
{
*buffer_object = This->buffer_object;
- return (const BYTE *)offset;
+ return NULL;
}
}
- return This->resource.allocatedMemory + offset;
+ return This->resource.allocatedMemory;
}
else
{
- return (const BYTE *)offset;
+ return NULL;
}
}
}
/* Context activation is done by the caller. */
-BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
+BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
{
/* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
IWineD3DDeviceImpl *device = This->resource.device;
struct wined3d_context *context;
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
/* Download the buffer, but don't permanently enable double buffering */
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
- buffer_get_sysmem(This);
+ buffer_get_sysmem(This, context->gl_info);
This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER;
}
- ENTER_GL();
- GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
- checkGLcall("glDeleteBuffersARB");
- LEAVE_GL();
- This->buffer_object = 0;
+ delete_gl_buffer(This, context->gl_info);
This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
buffer_clear_dirty_areas(This);
return resource_get_priority((IWineD3DResource *)iface);
}
+/* The caller provides a context and binds the buffer */
+static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const struct wined3d_gl_info *gl_info)
+{
+ enum wined3d_event_query_result ret;
+
+ /* No fencing needs to be done if the app promises not to overwrite
+ * existing data */
+ if(flags & WINED3DLOCK_NOOVERWRITE) return;
+ if(flags & WINED3DLOCK_DISCARD)
+ {
+ ENTER_GL();
+ GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
+ checkGLcall("glBufferDataARB\n");
+ LEAVE_GL();
+ return;
+ }
+
+ if(!This->query)
+ {
+ TRACE("Creating event query for buffer %p\n", This);
+
+ if (!wined3d_event_query_supported(gl_info))
+ {
+ FIXME("Event queries not supported, dropping async buffer locks.\n");
+ goto drop_query;
+ }
+
+ This->query = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->query));
+ if (!This->query)
+ {
+ ERR("Failed to allocate event query memory, dropping async buffer locks.\n");
+ goto drop_query;
+ }
+
+ /* Since we don't know about old draws a glFinish is needed once */
+ wglFinish();
+ return;
+ }
+ TRACE("Synchronizing buffer %p\n", This);
+ ret = wined3d_event_query_finish(This->query, This->resource.device);
+ switch(ret)
+ {
+ case WINED3D_EVENT_QUERY_NOT_STARTED:
+ case WINED3D_EVENT_QUERY_OK:
+ /* All done */
+ return;
+
+ case WINED3D_EVENT_QUERY_WRONG_THREAD:
+ WARN("Cannot synchronize buffer lock due to a thread conflict\n");
+ goto drop_query;
+
+ default:
+ ERR("wined3d_event_query_finish returned %u, dropping async buffer locks\n", ret);
+ goto drop_query;
+ }
+
+drop_query:
+ if(This->query)
+ {
+ wined3d_event_query_destroy(This->query);
+ This->query = NULL;
+ }
+
+ wglFinish();
+ ENTER_GL();
+ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE));
+ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)");
+ LEAVE_GL();
+ This->flags &= ~WINED3D_BUFFER_APPLESYNC;
+}
+
+/* The caller provides a GL context */
+static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags)
+{
+ BYTE *map;
+ UINT start = 0, len = 0;
+
+ ENTER_GL();
+ GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+ checkGLcall("glBindBufferARB");
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GLbitfield mapflags;
+ mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
+ if (flags & WINED3D_BUFFER_DISCARD)
+ {
+ mapflags |= GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
+ }
+ else if (flags & WINED3D_BUFFER_NOSYNC)
+ {
+ mapflags |= GL_MAP_UNSYNCHRONIZED_BIT;
+ }
+ map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0,
+ This->resource.size, mapflags));
+ checkGLcall("glMapBufferRange");
+ }
+ else
+ {
+ if (This->flags & WINED3D_BUFFER_APPLESYNC)
+ {
+ DWORD syncflags = 0;
+ if (flags & WINED3D_BUFFER_DISCARD) syncflags |= WINED3DLOCK_DISCARD;
+ if (flags & WINED3D_BUFFER_NOSYNC) syncflags |= WINED3DLOCK_NOOVERWRITE;
+ LEAVE_GL();
+ buffer_sync_apple(This, syncflags, gl_info);
+ ENTER_GL();
+ }
+ map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB));
+ checkGLcall("glMapBufferARB");
+ }
+ if (!map)
+ {
+ LEAVE_GL();
+ ERR("Failed to map opengl buffer\n");
+ return;
+ }
+
+ while(This->modified_areas)
+ {
+ This->modified_areas--;
+ start = This->maps[This->modified_areas].offset;
+ len = This->maps[This->modified_areas].size;
+
+ memcpy(map + start, This->resource.allocatedMemory + start, len);
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len));
+ checkGLcall("glFlushMappedBufferRange");
+ }
+ else if (This->flags & WINED3D_BUFFER_FLUSH)
+ {
+ GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len));
+ checkGLcall("glFlushMappedBufferRangeAPPLE");
+ }
+ }
+ GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+ checkGLcall("glUnmapBufferARB");
+ LEAVE_GL();
+}
+
static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
{
struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
IWineD3DDeviceImpl *device = This->resource.device;
UINT start = 0, end = 0, len = 0, vertices;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
BOOL decl_changed = FALSE;
unsigned int i, j;
BYTE *data;
+ DWORD flags = This->flags & (WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD);
TRACE("iface %p\n", iface);
+ This->flags &= ~(WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD);
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
if (!This->buffer_object)
{
/* TODO: Make converting independent from VBOs */
if (This->flags & WINED3D_BUFFER_CREATEBO)
{
- buffer_create_buffer_object(This);
+ buffer_create_buffer_object(This, gl_info);
This->flags &= ~WINED3D_BUFFER_CREATEBO;
}
else
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
goto end;
}
- buffer_check_buffer_object_size(This);
+ buffer_check_buffer_object_size(This, gl_info);
+
+ /* The declaration changed, reload the whole buffer */
+ WARN("Reloading buffer because of decl change\n");
+ buffer_clear_dirty_areas(This);
+ if(!buffer_add_dirty_area(This, 0, 0))
+ {
+ ERR("buffer_add_dirty_area failed, this is not expected\n");
+ return;
+ }
+ /* Avoid unfenced updates, we might overwrite more areas of the buffer than the application
+ * cleared for unsynchronized updates
+ */
+ flags = 0;
}
else
{
}
}
- if (decl_changed)
- {
- /* The declaration changed, reload the whole buffer */
- WARN("Reloading buffer because of decl change\n");
- buffer_clear_dirty_areas(This);
- if(!buffer_add_dirty_area(This, 0, 0))
- {
- ERR("buffer_add_dirty_area failed, this is not expected\n");
- return;
- }
- }
-
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER);
return;
}
- ENTER_GL();
- GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
- checkGLcall("glBindBufferARB");
- while(This->modified_areas)
- {
- This->modified_areas--;
- start = This->maps[This->modified_areas].offset;
- len = This->maps[This->modified_areas].size;
- GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, len, This->resource.allocatedMemory + start));
- checkGLcall("glBufferSubDataARB");
- }
- LEAVE_GL();
+ buffer_direct_upload(This, context->gl_info, flags);
context_release(context);
return;
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
- buffer_get_sysmem(This);
+ buffer_get_sysmem(This, gl_info);
}
/* Now for each vertex in the buffer that needs conversion */
/* IWineD3DBuffer methods */
-static DWORD buffer_sanitize_flags(DWORD flags)
+static DWORD buffer_sanitize_flags(struct wined3d_buffer *buffer, DWORD flags)
{
/* Not all flags make sense together, but Windows never returns an error. Catch the
* cases that could cause issues */
WARN("WINED3DLOCK_DISCARD and WINED3DLOCK_NOOVERWRITE used together, ignoring\n");
return 0;
}
+ else if (flags & (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE) && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
+ {
+ WARN("DISCARD or NOOVERWRITE lock on non-dynamic buffer, ignoring\n");
+ return 0;
+ }
return flags;
}
{
struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
LONG count;
+ BOOL dirty = buffer_is_dirty(This);
TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags);
- flags = buffer_sanitize_flags(flags);
+ flags = buffer_sanitize_flags(This, flags);
if (!(flags & WINED3DLOCK_READONLY))
{
if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY;
count = InterlockedIncrement(&This->lock_count);
- if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
+ if (This->buffer_object)
{
- if(count == 1)
+ if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
- IWineD3DDeviceImpl *device = This->resource.device;
- struct wined3d_context *context;
- const struct wined3d_gl_info *gl_info;
-
- if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ if(count == 1)
{
- IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER);
- }
+ IWineD3DDeviceImpl *device = This->resource.device;
+ struct wined3d_context *context;
+ const struct wined3d_gl_info *gl_info;
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
- gl_info = context->gl_info;
- ENTER_GL();
- GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+ if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ {
+ IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER);
+ }
- if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+ ENTER_GL();
+ GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GLbitfield mapflags = buffer_gl_map_flags(flags);
+ This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0,
+ This->resource.size, mapflags));
+ checkGLcall("glMapBufferRange");
+ }
+ else
+ {
+ if(This->flags & WINED3D_BUFFER_APPLESYNC)
+ {
+ LEAVE_GL();
+ buffer_sync_apple(This, flags, gl_info);
+ ENTER_GL();
+ }
+ This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
+ checkGLcall("glMapBufferARB");
+ }
+ LEAVE_GL();
+
+ if (((DWORD_PTR) This->resource.allocatedMemory) & (RESOURCE_ALIGNMENT - 1))
+ {
+ WARN("Pointer %p is not %u byte aligned, falling back to double buffered operation\n",
+ This->resource.allocatedMemory, RESOURCE_ALIGNMENT);
+
+ ENTER_GL();
+ GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+ checkGLcall("glUnmapBufferARB");
+ LEAVE_GL();
+ This->resource.allocatedMemory = NULL;
+
+ buffer_get_sysmem(This, gl_info);
+ TRACE("New pointer is %p\n", This->resource.allocatedMemory);
+ }
+ context_release(context);
+ }
+ }
+ else
+ {
+ if (dirty)
{
- GLbitfield mapflags = buffer_gl_map_flags(flags);
- This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0,
- This->resource.size, mapflags));
+ if (This->flags & WINED3D_BUFFER_NOSYNC && !(flags & WINED3DLOCK_NOOVERWRITE))
+ {
+ This->flags &= ~WINED3D_BUFFER_NOSYNC;
+ }
}
- else
+ else if(flags & WINED3DLOCK_NOOVERWRITE)
{
- This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
+ This->flags |= WINED3D_BUFFER_NOSYNC;
+ }
+
+ if (flags & WINED3DLOCK_DISCARD)
+ {
+ This->flags |= WINED3D_BUFFER_DISCARD;
}
- LEAVE_GL();
- context_release(context);
}
}
IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER);
}
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
gl_info = context->gl_info;
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint,
const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info);
HRESULT hr;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
BOOL dynamic_buffer_ok;
TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage,
debug_d3dformat(buffer->resource.format_desc->format), buffer->resource.allocatedMemory, buffer);
- dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE];
+ /* GL_ARB_map_buffer_range is disabled for now due to numerous bugs and no gains */
+ dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE];
/* Observations show that drawStridedSlow is faster on dynamic VBs than converting +
* drawStridedFast (half-life 2 and others).
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION (*gl_info)
-
static DWORD wined3d_context_tls_idx;
/* FBO helper functions */
}
/* GL locking is done by the caller */
-static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info)
+static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info, GLenum target)
{
unsigned int i;
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
+ gl_info->fbo_ops.glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
}
- gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ gl_info->fbo_ops.glFramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
- gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ gl_info->fbo_ops.glFramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
}
const struct wined3d_gl_info *gl_info = context->gl_info;
context_bind_fbo(context, GL_FRAMEBUFFER, fbo);
- context_clean_fbo_attachments(gl_info);
+ context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER);
context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
gl_info->fbo_ops.glDeleteFramebuffers(1, fbo);
}
/* GL locking is done by the caller */
-static void context_apply_attachment_filter_states(IWineD3DSurface *surface)
+static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface)
{
- const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
- IWineD3DDeviceImpl *device = surface_impl->resource.device;
IWineD3DBaseTextureImpl *texture_impl;
- BOOL update_minfilter = FALSE;
- BOOL update_magfilter = FALSE;
/* Update base texture states array */
- if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
+ if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
+ &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
{
+ IWineD3DDeviceImpl *device = surface->resource.device;
+ BOOL update_minfilter = FALSE;
+ BOOL update_magfilter = FALSE;
+
if (texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] != WINED3DTEXF_POINT
|| texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] != WINED3DTEXF_NONE)
{
}
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
- }
-
- if (update_minfilter || update_magfilter)
- {
- GLenum target, bind_target;
- GLint old_binding;
- target = surface_impl->texture_target;
- if (target == GL_TEXTURE_2D)
+ if (update_minfilter || update_magfilter)
{
- bind_target = GL_TEXTURE_2D;
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
- } else if (target == GL_TEXTURE_RECTANGLE_ARB) {
- bind_target = GL_TEXTURE_RECTANGLE_ARB;
- glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
- } else {
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
+ GLenum target, bind_target;
+ GLint old_binding;
+
+ target = surface->texture_target;
+ if (target == GL_TEXTURE_2D)
+ {
+ bind_target = GL_TEXTURE_2D;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
+ }
+ else if (target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ bind_target = GL_TEXTURE_RECTANGLE_ARB;
+ glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
+ }
+ else
+ {
+ bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
+ }
+
+ glBindTexture(bind_target, surface->texture_name);
+ if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glBindTexture(bind_target, old_binding);
}
- glBindTexture(bind_target, surface_impl->texture_name);
- if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glBindTexture(bind_target, old_binding);
+ checkGLcall("apply_attachment_filter_states()");
}
-
- checkGLcall("apply_attachment_filter_states()");
}
/* GL locking is done by the caller */
void context_attach_depth_stencil_fbo(struct wined3d_context *context,
- GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer)
+ GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer)
{
- IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Attach depth stencil %p\n", depth_stencil);
if (depth_stencil)
{
- DWORD format_flags = depth_stencil_impl->resource.format_desc->Flags;
+ DWORD format_flags = depth_stencil->resource.format_desc->Flags;
- if (use_render_buffer && depth_stencil_impl->current_renderbuffer)
+ if (use_render_buffer && depth_stencil->current_renderbuffer)
{
if (format_flags & WINED3DFMT_FLAG_DEPTH)
{
gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id);
+ GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id);
checkGLcall("glFramebufferRenderbuffer()");
}
if (format_flags & WINED3DFMT_FLAG_STENCIL)
{
gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id);
+ GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id);
checkGLcall("glFramebufferRenderbuffer()");
}
}
else
{
- surface_prepare_texture(depth_stencil_impl, FALSE);
+ surface_prepare_texture(depth_stencil, gl_info, FALSE);
context_apply_attachment_filter_states(depth_stencil);
if (format_flags & WINED3DFMT_FLAG_DEPTH)
{
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
- depth_stencil_impl->texture_target, depth_stencil_impl->texture_name,
- depth_stencil_impl->texture_level);
+ depth_stencil->texture_target, depth_stencil->texture_name,
+ depth_stencil->texture_level);
checkGLcall("glFramebufferTexture2D()");
}
if (format_flags & WINED3DFMT_FLAG_STENCIL)
{
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
- depth_stencil_impl->texture_target, depth_stencil_impl->texture_name,
- depth_stencil_impl->texture_level);
+ depth_stencil->texture_target, depth_stencil->texture_name,
+ depth_stencil->texture_level);
checkGLcall("glFramebufferTexture2D()");
}
}
}
/* GL locking is done by the caller */
-void context_attach_surface_fbo(const struct wined3d_context *context,
- GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
+static void context_attach_surface_fbo(const struct wined3d_context *context,
+ GLenum fbo_target, DWORD idx, IWineD3DSurfaceImpl *surface)
{
- IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Attach surface %p to %u\n", surface, idx);
if (surface)
{
- surface_prepare_texture(surface_impl, FALSE);
+ surface_prepare_texture(surface, gl_info, FALSE);
context_apply_attachment_filter_states(surface);
- gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface_impl->texture_target,
- surface_impl->texture_name, surface_impl->texture_level);
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface->texture_target,
+ surface->texture_name, surface->texture_level);
checkGLcall("glFramebufferTexture2D()");
}
else
}
/* GL locking is done by the caller */
-static void context_check_fbo_status(struct wined3d_context *context)
+static void context_check_fbo_status(struct wined3d_context *context, GLenum target)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum status;
- status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(target);
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("FBO complete\n");
/* Dump the FBO attachments */
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- attachment = (IWineD3DSurfaceImpl *)context->current_fbo->render_targets[i];
+ attachment = context->current_fbo->render_targets[i];
if (attachment)
{
FIXME("\tColor attachment %d: (%p) %s %ux%u\n",
attachment->pow2Width, attachment->pow2Height);
}
}
- attachment = (IWineD3DSurfaceImpl *)context->current_fbo->depth_stencil;
+ attachment = context->current_fbo->depth_stencil;
if (attachment)
{
FIXME("\tDepth attachment: (%p) %s %ux%u\n",
}
}
-static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context)
+static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context,
+ IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry;
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets));
- memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
- entry->depth_stencil = device->stencilBufferTarget;
+ memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
+ entry->depth_stencil = depth_stencil;
entry->attached = FALSE;
entry->id = 0;
}
/* GL locking is done by the caller */
-static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
+static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
+ IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil,
+ struct fbo_entry *entry)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
- context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id);
- context_clean_fbo_attachments(gl_info);
+ context_bind_fbo(context, target, &entry->id);
+ context_clean_fbo_attachments(gl_info, target);
- memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
- entry->depth_stencil = device->stencilBufferTarget;
+ memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
+ entry->depth_stencil = depth_stencil;
entry->attached = FALSE;
}
/* GL locking is done by the caller */
-static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context)
+static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
+ IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry;
LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
{
if (!memcmp(entry->render_targets,
- device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets))
- && entry->depth_stencil == device->stencilBufferTarget)
+ render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets))
+ && entry->depth_stencil == depth_stencil)
{
list_remove(&entry->entry);
list_add_head(&context->fbo_list, &entry->entry);
if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES)
{
- entry = context_create_fbo_entry(context);
+ entry = context_create_fbo_entry(context, render_targets, depth_stencil);
list_add_head(&context->fbo_list, &entry->entry);
++context->fbo_entry_count;
}
else
{
entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry);
- context_reuse_fbo_entry(context, entry);
+ context_reuse_fbo_entry(context, target, render_targets, depth_stencil, entry);
list_remove(&entry->entry);
list_add_head(&context->fbo_list, &entry->entry);
}
}
/* GL locking is done by the caller */
-static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
+static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int i;
- context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id);
+ context_bind_fbo(context, target, &entry->id);
if (!entry->attached)
{
/* Apply render targets */
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- IWineD3DSurface *render_target = device->render_targets[i];
- context_attach_surface_fbo(context, GL_FRAMEBUFFER, i, render_target);
+ context_attach_surface_fbo(context, target, i, entry->render_targets[i]);
}
/* Apply depth targets */
- if (device->stencilBufferTarget)
+ if (entry->depth_stencil)
{
- unsigned int w = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Width;
- unsigned int h = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Height;
-
- surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h);
+ surface_set_compatible_renderbuffer(entry->depth_stencil,
+ entry->render_targets[0]->pow2Width, entry->render_targets[0]->pow2Height);
}
- context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, device->stencilBufferTarget, TRUE);
+ context_attach_depth_stencil_fbo(context, target, entry->depth_stencil, TRUE);
entry->attached = TRUE;
}
{
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- if (device->render_targets[i])
- context_apply_attachment_filter_states(device->render_targets[i]);
+ if (entry->render_targets[i])
+ context_apply_attachment_filter_states(entry->render_targets[i]);
}
- if (device->stencilBufferTarget)
- context_apply_attachment_filter_states(device->stencilBufferTarget);
- }
-
- for (i = 0; i < gl_info->limits.buffers; ++i)
- {
- if (device->render_targets[i])
- device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
- else
- device->draw_buffers[i] = GL_NONE;
+ if (entry->depth_stencil)
+ context_apply_attachment_filter_states(entry->depth_stencil);
}
}
/* GL locking is done by the caller */
-static void context_apply_fbo_state(struct wined3d_context *context)
+static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
+ IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil)
{
struct fbo_entry *entry, *entry2;
context_destroy_fbo_entry(context, entry);
}
- if (context->render_offscreen)
+ if (context->rebind_fbo)
{
- context->current_fbo = context_find_fbo_entry(context);
- context_apply_fbo_entry(context, context->current_fbo);
- } else {
- context->current_fbo = NULL;
context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ context->rebind_fbo = FALSE;
+ }
+
+ if (render_targets)
+ {
+ context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil);
+ context_apply_fbo_entry(context, target, context->current_fbo);
+ }
+ else
+ {
+ context->current_fbo = NULL;
+ context_bind_fbo(context, target, NULL);
}
- context_check_fbo_status(context);
+ context_check_fbo_status(context, target);
+}
+
+/* GL locking is done by the caller */
+void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
+ IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil)
+{
+ if (surface_is_offscreen(render_target))
+ {
+ context->blit_targets[0] = render_target;
+ context_apply_fbo_state(context, target, context->blit_targets, depth_stencil);
+ }
+ else
+ {
+ context_apply_fbo_state(context, target, NULL, NULL);
+ }
}
/* Context activation is done by the caller. */
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry, *entry2;
- if (context->current_rt == (IWineD3DSurface *)resource) context->current_rt = NULL;
+ if (context->current_rt == (IWineD3DSurfaceImpl *)resource) context->current_rt = NULL;
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
{
UINT j;
- if (entry->depth_stencil == (IWineD3DSurface *)resource)
+ if (entry->depth_stencil == (IWineD3DSurfaceImpl *)resource)
{
list_remove(&entry->entry);
list_add_head(&context->fbo_destroy_list, &entry->entry);
for (j = 0; j < gl_info->limits.buffers; ++j)
{
- if (entry->render_targets[j] == (IWineD3DSurface *)resource)
+ if (entry->render_targets[j] == (IWineD3DSurfaceImpl *)resource)
{
list_remove(&entry->entry);
list_add_head(&context->fbo_destroy_list, &entry->entry);
}
}
+void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct fbo_entry *entry = context->current_fbo;
+ unsigned int i;
+
+ if (!entry || context->rebind_fbo) return;
+
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ {
+ if (surface == entry->render_targets[i])
+ {
+ TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i);
+ context->rebind_fbo = TRUE;
+ return;
+ }
+ }
+
+ if (surface == entry->depth_stencil)
+ {
+ TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface);
+ context->rebind_fbo = TRUE;
+ }
+}
+
+static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format)
+{
+ int current = GetPixelFormat(dc);
+
+ if (current == format) return TRUE;
+
+ if (!current)
+ {
+ if (!SetPixelFormat(dc, format, NULL))
+ {
+ ERR("Failed to set pixel format %d on device context %p, last error %#x.\n",
+ format, dc, GetLastError());
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* By default WGL doesn't allow pixel format adjustments but we need it
+ * here. For this reason there's a Wine specific wglSetPixelFormat()
+ * which allows us to set the pixel format multiple times. Only use it
+ * when really needed. */
+ if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
+ {
+ if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format, NULL)))
+ {
+ ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n",
+ format, dc);
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* OpenGL doesn't allow pixel format adjustments. Print an error and
+ * continue using the old format. There's a big chance that the old
+ * format works although with a performance hit and perhaps rendering
+ * errors. */
+ ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n",
+ format, dc, current);
+ return TRUE;
+}
+
+static void context_update_window(struct wined3d_context *context)
+{
+ TRACE("Updating context %p window from %p to %p.\n",
+ context, context->win_handle, context->swapchain->win_handle);
+
+ if (context->valid)
+ {
+ if (!ReleaseDC(context->win_handle, context->hdc))
+ {
+ ERR("Failed to release device context %p, last error %#x.\n",
+ context->hdc, GetLastError());
+ }
+ }
+ else context->valid = 1;
+
+ context->win_handle = context->swapchain->win_handle;
+
+ if (!(context->hdc = GetDC(context->win_handle)))
+ {
+ ERR("Failed to get a device context for window %p.\n", context->win_handle);
+ goto err;
+ }
+
+ if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format))
+ {
+ ERR("Failed to set pixel format %d on device context %p.\n",
+ context->pixel_format, context->hdc);
+ goto err;
+ }
+
+ if (!pwglMakeCurrent(context->hdc, context->glCtx))
+ {
+ ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
+ context->glCtx, context->hdc, GetLastError());
+ goto err;
+ }
+
+ return;
+
+err:
+ context->valid = 0;
+}
+
static void context_validate(struct wined3d_context *context)
{
HWND wnd = WindowFromDC(context->hdc);
context->hdc, wnd, context->win_handle);
context->valid = 0;
}
+
+ if (context->win_handle != context->swapchain->win_handle)
+ context_update_window(context);
}
static void context_destroy_gl_resources(struct wined3d_context *context)
if (context->valid)
{
- if (context->src_fbo)
- {
- TRACE("Destroy src FBO %d\n", context->src_fbo);
- context_destroy_fbo(context, &context->src_fbo);
- }
if (context->dst_fbo)
{
TRACE("Destroy dst FBO %d\n", context->dst_fbo);
ERR("Failed to disable GL context.\n");
}
- if (context->pbuffer)
- {
- GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc));
- GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer));
- }
- else
- {
- ReleaseDC(context->win_handle, context->hdc);
- }
+ ReleaseDC(context->win_handle, context->hdc);
if (!pwglDeleteContext(context->glCtx))
{
context->isStateDirty[idx] |= (1 << shift);
}
-/*****************************************************************************
- * AddContextToArray
- *
- * Adds a context to the context array. Helper function for context_create().
- *
- * This method is not called in performance-critical code paths, only when a
- * new render target or swapchain is created. Thus performance is not an issue
- * here.
- *
- * Params:
- * This: Device to add the context for
- * hdc: device context
- * glCtx: WGL context to add
- * pbuffer: optional pbuffer used with this context
- *
- *****************************************************************************/
-static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This,
- HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer)
-{
- struct wined3d_context **oldArray = This->contexts;
- DWORD state;
-
- This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1));
- if(This->contexts == NULL) {
- ERR("Unable to grow the context array\n");
- This->contexts = oldArray;
- return NULL;
- }
- if(oldArray) {
- memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts);
- }
-
- This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**This->contexts));
- if(This->contexts[This->numContexts] == NULL) {
- ERR("Unable to allocate a new context\n");
- HeapFree(GetProcessHeap(), 0, This->contexts);
- This->contexts = oldArray;
- return NULL;
- }
-
- This->contexts[This->numContexts]->hdc = hdc;
- This->contexts[This->numContexts]->glCtx = glCtx;
- This->contexts[This->numContexts]->pbuffer = pbuffer;
- This->contexts[This->numContexts]->win_handle = win_handle;
- HeapFree(GetProcessHeap(), 0, oldArray);
-
- /* Mark all states dirty to force a proper initialization of the states on the first use of the context
- */
- for(state = 0; state <= STATE_HIGHEST; state++) {
- if (This->StateTable[state].representative)
- Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
- }
-
- This->numContexts++;
- TRACE("Created context %p\n", This->contexts[This->numContexts - 1]);
- return This->contexts[This->numContexts - 1];
-}
-
/* This function takes care of WineD3D pixel format selection. */
static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc,
- const struct GlPixelFormatDesc *color_format_desc, const struct GlPixelFormatDesc *ds_format_desc,
- BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible)
+ const struct wined3d_format_desc *color_format_desc, const struct wined3d_format_desc *ds_format_desc,
+ BOOL auxBuffers, int numSamples, BOOL findCompatible)
{
int iPixelFormat=0;
unsigned int matchtry;
int i = 0;
int nCfgs = This->adapter->nCfgs;
- TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, pbuffer=%d, findCompatible=%d\n",
+ TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, findCompatible=%d\n",
debug_d3dformat(color_format_desc->format), debug_d3dformat(ds_format_desc->format),
- auxBuffers, numSamples, pbuffer, findCompatible);
+ auxBuffers, numSamples, findCompatible);
if (!getColorBits(color_format_desc, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits))
{
return 0;
}
- /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
- * You are able to add a depth + stencil surface at a later stage when you need it.
- * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
- * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
- * context, need torecreate shaders, textures and other resources.
- *
- * The context manager already takes care of the state problem and for the other tasks code from Reset
- * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
- * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
- * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
- * issue needs to be fixed. */
- if (ds_format_desc->format != WINED3DFMT_D24_UNORM_S8_UINT)
- {
- FIXME("Add OpenGL context recreation support to SetDepthStencilSurface\n");
- ds_format_desc = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, &This->adapter->gl_info);
- }
-
getDepthStencilBits(ds_format_desc, &depthBits, &stencilBits);
for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])) && !iPixelFormat; matchtry++) {
if(cfg->iPixelType != WGL_TYPE_RGBA_ARB)
continue;
- /* In window mode (!pbuffer) we need a window drawable format and double buffering. */
- if(!pbuffer && !(cfg->windowDrawable && cfg->doubleBuffer))
+ /* In window mode we need a window drawable format and double buffering. */
+ if(!(cfg->windowDrawable && cfg->doubleBuffer))
continue;
/* We like to have aux buffers in backbuffer mode */
if(auxBuffers && !cfg->auxBuffers && matches[matchtry].require_aux)
continue;
- /* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */
- if(pbuffer && (!cfg->pbufferDrawable || cfg->doubleBuffer))
- continue;
-
if(matches[matchtry].exact_color) {
if(cfg->redSize != redBits)
continue;
/*****************************************************************************
* context_create
*
- * Creates a new context for a window, or a pbuffer context.
+ * Creates a new context.
*
* * Params:
* This: Device to activate the context for
* target: Surface this context will render to
* win_handle: handle to the window which we are drawing to
- * create_pbuffer: tells whether to create a pbuffer or not
* pPresentParameters: contains the pixelformats to use for onscreen rendering
*
*****************************************************************************/
-struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target,
- HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms)
+struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
+ const struct wined3d_format_desc *ds_format_desc)
{
- const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
- struct wined3d_context *ret = NULL;
- HPBUFFERARB pbuffer = NULL;
+ IWineD3DDeviceImpl *device = swapchain->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format_desc *color_format_desc;
+ struct wined3d_context *ret;
+ PIXELFORMATDESCRIPTOR pfd;
+ BOOL auxBuffers = FALSE;
+ int numSamples = 0;
+ int pixel_format;
unsigned int s;
+ DWORD state;
HGLRC ctx;
HDC hdc;
- TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
+ TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
- if(create_pbuffer) {
- HDC hdc_parent = GetDC(win_handle);
- int iPixelFormat = 0;
-
- IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
- const struct GlPixelFormatDesc *ds_format_desc = StencilSurface
- ? ((IWineD3DSurfaceImpl *)StencilSurface)->resource.format_desc
- : getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
-
- /* Try to find a pixel format with pbuffer support. */
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format_desc,
- ds_format_desc, FALSE /* auxBuffers */, 0 /* numSamples */, TRUE /* PBUFFER */,
- FALSE /* findCompatible */);
- if(!iPixelFormat) {
- TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
-
- /* For some reason we weren't able to find a format, try to find something instead of crashing.
- * A reason for failure could have been wglChoosePixelFormatARB strictness. */
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format_desc,
- ds_format_desc, FALSE /* auxBuffer */, 0 /* numSamples */, TRUE /* PBUFFER */,
- TRUE /* findCompatible */);
- }
+ ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
+ if (!ret)
+ {
+ ERR("Failed to allocate context memory.\n");
+ return NULL;
+ }
- /* This shouldn't happen as ChoosePixelFormat always returns something */
- if(!iPixelFormat) {
- ERR("Unable to locate a pixel format for a pbuffer\n");
- ReleaseDC(win_handle, hdc_parent);
- goto out;
- }
+ if (!(hdc = GetDC(swapchain->win_handle)))
+ {
+ ERR("Failed to retrieve a device context.\n");
+ goto out;
+ }
- TRACE("Creating a pBuffer drawable for the new context\n");
- pbuffer = GL_EXTCALL(wglCreatePbufferARB(hdc_parent, iPixelFormat, target->currentDesc.Width, target->currentDesc.Height, 0));
- if(!pbuffer) {
- ERR("Cannot create a pbuffer\n");
- ReleaseDC(win_handle, hdc_parent);
- goto out;
- }
+ color_format_desc = target->resource.format_desc;
- /* In WGL a pbuffer is 'wrapped' inside a HDC to 'fool' wglMakeCurrent */
- hdc = GL_EXTCALL(wglGetPbufferDCARB(pbuffer));
- if(!hdc) {
- ERR("Cannot get a HDC for pbuffer (%p)\n", pbuffer);
- GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
- ReleaseDC(win_handle, hdc_parent);
- goto out;
- }
- ReleaseDC(win_handle, hdc_parent);
- } else {
- PIXELFORMATDESCRIPTOR pfd;
- int iPixelFormat;
- int res;
- const struct GlPixelFormatDesc *color_format_desc = target->resource.format_desc;
- const struct GlPixelFormatDesc *ds_format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN,
- &This->adapter->gl_info);
- BOOL auxBuffers = FALSE;
- int numSamples = 0;
-
- hdc = GetDC(win_handle);
- if(hdc == NULL) {
- ERR("Cannot retrieve a device context!\n");
- goto out;
- }
-
- /* In case of ORM_BACKBUFFER, make sure to request an alpha component for X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */
- if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
- auxBuffers = TRUE;
-
- if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM)
- color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, &This->adapter->gl_info);
- else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM)
- color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->adapter->gl_info);
- }
-
- /* DirectDraw supports 8bit paletted render targets and these are used by old games like Starcraft and C&C.
- * Most modern hardware doesn't support 8bit natively so we perform some form of 8bit -> 32bit conversion.
- * The conversion (ab)uses the alpha component for storing the palette index. For this reason we require
- * a format with 8bit alpha, so request A8R8G8B8. */
- if (color_format_desc->format == WINED3DFMT_P8_UINT)
- color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->adapter->gl_info);
-
- /* Retrieve the depth stencil format from the present parameters.
- * The choice of the proper format can give a nice performance boost
- * in case of GPU limited programs. */
- if(pPresentParms->EnableAutoDepthStencil) {
- TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat));
- ds_format_desc = getFormatDescEntry(pPresentParms->AutoDepthStencilFormat, &This->adapter->gl_info);
- }
-
- /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD */
- if(pPresentParms->MultiSampleType && (pPresentParms->SwapEffect == WINED3DSWAPEFFECT_DISCARD)) {
- if (!gl_info->supported[ARB_MULTISAMPLE])
- ERR("The program is requesting multisampling without support!\n");
- else
- {
- TRACE("Requesting multisample type %#x.\n", pPresentParms->MultiSampleType);
- numSamples = pPresentParms->MultiSampleType;
- }
- }
+ /* In case of ORM_BACKBUFFER, make sure to request an alpha component for
+ * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */
+ if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
+ {
+ auxBuffers = TRUE;
- /* Try to find a pixel format which matches our requirements */
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, color_format_desc, ds_format_desc,
- auxBuffers, numSamples, FALSE /* PBUFFER */, FALSE /* findCompatible */);
+ if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM)
+ color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, gl_info);
+ else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM)
+ color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
+ }
- /* Try to locate a compatible format if we weren't able to find anything */
- if(!iPixelFormat) {
- TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
- iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, color_format_desc, ds_format_desc,
- auxBuffers, 0 /* numSamples */, FALSE /* PBUFFER */, TRUE /* findCompatible */ );
- }
+ /* DirectDraw supports 8bit paletted render targets and these are used by
+ * old games like Starcraft and C&C. Most modern hardware doesn't support
+ * 8bit natively so we perform some form of 8bit -> 32bit conversion. The
+ * conversion (ab)uses the alpha component for storing the palette index.
+ * For this reason we require a format with 8bit alpha, so request
+ * A8R8G8B8. */
+ if (color_format_desc->format == WINED3DFMT_P8_UINT)
+ color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
- /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
- if(!iPixelFormat) {
- ERR("Can't find a suitable iPixelFormat\n");
- return NULL;
+ /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD. */
+ if (swapchain->presentParms.MultiSampleType && (swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD))
+ {
+ if (!gl_info->supported[ARB_MULTISAMPLE])
+ WARN("The application is requesting multisampling without support.\n");
+ else
+ {
+ TRACE("Requesting multisample type %#x.\n", swapchain->presentParms.MultiSampleType);
+ numSamples = swapchain->presentParms.MultiSampleType;
}
+ }
- DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
- res = SetPixelFormat(hdc, iPixelFormat, NULL);
- if(!res) {
- int oldPixelFormat = GetPixelFormat(hdc);
+ /* Try to find a pixel format which matches our requirements. */
+ pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc,
+ auxBuffers, numSamples, FALSE /* findCompatible */);
- /* By default WGL doesn't allow pixel format adjustments but we need it here.
- * For this reason there is a WINE-specific wglSetPixelFormat which allows you to
- * set the pixel format multiple times. Only use it when it is really needed. */
+ /* Try to locate a compatible format if we weren't able to find anything. */
+ if (!pixel_format)
+ {
+ TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
+ pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc,
+ auxBuffers, 0 /* numSamples */, TRUE /* findCompatible */);
+ }
- if(oldPixelFormat == iPixelFormat) {
- /* We don't have to do anything as the formats are the same :) */
- }
- else if (oldPixelFormat && gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
- {
- res = GL_EXTCALL(wglSetPixelFormatWINE(hdc, iPixelFormat, NULL));
+ /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
+ if (!pixel_format)
+ {
+ ERR("Can't find a suitable pixel format.\n");
+ goto out;
+ }
- if(!res) {
- ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
- return NULL;
- }
- } else if(oldPixelFormat) {
- /* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format.
- * There's a big chance that the old format works although with a performance hit and perhaps rendering errors. */
- ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat);
- } else {
- ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
- return NULL;
- }
- }
+ DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd);
+ if (!context_set_pixel_format(gl_info, hdc, pixel_format))
+ {
+ ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc);
+ goto out;
}
ctx = pwglCreateContext(hdc);
- if (This->numContexts)
+ if (device->numContexts)
{
- if (!pwglShareLists(This->contexts[0]->glCtx, ctx))
+ if (!pwglShareLists(device->contexts[0]->glCtx, ctx))
{
DWORD err = GetLastError();
ERR("wglShareLists(%p, %p) failed, last error %#x.\n",
- This->contexts[0]->glCtx, ctx, err);
+ device->contexts[0]->glCtx, ctx, err);
}
}
if(!ctx) {
ERR("Failed to create a WGL context\n");
- if(create_pbuffer) {
- GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
- GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
- }
goto out;
}
- ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer);
- if(!ret) {
+
+ if (!device_context_add(device, ret))
+ {
ERR("Failed to add the newly created context to the context list\n");
if (!pwglDeleteContext(ctx))
{
DWORD err = GetLastError();
ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, err);
}
- if(create_pbuffer) {
- GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
- GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
- }
goto out;
}
- ret->valid = 1;
- ret->gl_info = &This->adapter->gl_info;
- ret->surface = (IWineD3DSurface *) target;
- ret->current_rt = (IWineD3DSurface *)target;
- ret->render_offscreen = surface_is_offscreen((IWineD3DSurface *) target);
- ret->draw_buffer_dirty = TRUE;
+
+ ret->gl_info = gl_info;
+
+ /* Mark all states dirty to force a proper initialization of the states
+ * on the first use of the context. */
+ for (state = 0; state <= STATE_HIGHEST; ++state)
+ {
+ if (device->StateTable[state].representative)
+ Context_MarkStateDirty(ret, state, device->StateTable);
+ }
+
+ ret->swapchain = swapchain;
+ ret->current_rt = target;
ret->tid = GetCurrentThreadId();
- if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) {
+
+ ret->render_offscreen = surface_is_offscreen(target);
+ ret->draw_buffer_dirty = TRUE;
+ ret->valid = 1;
+
+ ret->glCtx = ctx;
+ ret->win_handle = swapchain->win_handle;
+ ret->hdc = hdc;
+ ret->pixel_format = pixel_format;
+
+ if (device->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *)device))
+ {
/* Create the dirty constants array and initialize them to dirty */
ret->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
- sizeof(*ret->vshader_const_dirty) * This->d3d_vshader_constantF);
+ sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF);
ret->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
- sizeof(*ret->pshader_const_dirty) * This->d3d_pshader_constantF);
+ sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF);
memset(ret->vshader_const_dirty, 1,
- sizeof(*ret->vshader_const_dirty) * This->d3d_vshader_constantF);
+ sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF);
memset(ret->pshader_const_dirty, 1,
- sizeof(*ret->pshader_const_dirty) * This->d3d_pshader_constantF);
+ sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF);
}
+ ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ gl_info->limits.buffers * sizeof(*ret->blit_targets));
+ if (!ret->blit_targets) goto out;
+
ret->free_occlusion_query_size = 4;
ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0,
ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries));
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
- glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);
- checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);");
- glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);
- checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);");
+ glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);
+ checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);");
+ glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
+ checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
if (gl_info->supported[APPLE_CLIENT_STORAGE])
{
LEAVE_GL();
- This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE);
+ device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
+
+ TRACE("Created context %p.\n", ret);
return ret;
out:
- if (ret)
- {
- HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
- HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
- HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty);
- HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty);
- HeapFree(GetProcessHeap(), 0, ret);
- }
+ HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
+ HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
+ HeapFree(GetProcessHeap(), 0, ret->blit_targets);
+ HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty);
+ HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty);
+ HeapFree(GetProcessHeap(), 0, ret);
return NULL;
}
-/*****************************************************************************
- * RemoveContextFromArray
- *
- * Removes a context from the context manager. The opengl context is not
- * destroyed or unset. context is not a valid pointer after that call.
- *
- * Similar to the former call this isn't a performance critical function. A
- * helper function for context_destroy().
- *
- * Params:
- * This: Device to activate the context for
- * context: Context to remove
- *
- *****************************************************************************/
-static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_context *context)
-{
- struct wined3d_context **new_array;
- BOOL found = FALSE;
- UINT i;
-
- TRACE("Removing ctx %p\n", context);
-
- for (i = 0; i < This->numContexts; ++i)
- {
- if (This->contexts[i] == context)
- {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- {
- ERR("Context %p doesn't exist in context array\n", context);
- return;
- }
-
- while (i < This->numContexts - 1)
- {
- This->contexts[i] = This->contexts[i + 1];
- ++i;
- }
-
- --This->numContexts;
- if (!This->numContexts)
- {
- HeapFree(GetProcessHeap(), 0, This->contexts);
- This->contexts = NULL;
- return;
- }
-
- new_array = HeapReAlloc(GetProcessHeap(), 0, This->contexts, This->numContexts * sizeof(*This->contexts));
- if (!new_array)
- {
- ERR("Failed to shrink context array. Oh well.\n");
- return;
- }
-
- This->contexts = new_array;
-}
-
/*****************************************************************************
* context_destroy
*
destroy = FALSE;
}
+ HeapFree(GetProcessHeap(), 0, context->blit_targets);
HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
- RemoveContextFromArray(This, context);
+ device_context_remove(This, context);
if (destroy) HeapFree(GetProcessHeap(), 0, context);
}
int i;
const struct StateEntry *StateTable = This->StateTable;
const struct wined3d_gl_info *gl_info = context->gl_info;
- UINT width = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Width;
- UINT height = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height;
+ UINT width = context->current_rt->currentDesc.Width;
+ UINT height = context->current_rt->currentDesc.Height;
DWORD sampler;
TRACE("Setting up context %p for blitting\n", context);
glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
checkGLcall("glColorMask");
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE), StateTable);
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), StateTable);
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), StateTable);
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), StateTable);
if (gl_info->supported[EXT_SECONDARY_COLOR])
{
glDisable(GL_COLOR_SUM_EXT);
* Returns: The needed context
*
*****************************************************************************/
-static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target)
+static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target)
{
IWineD3DSwapChain *swapchain = NULL;
struct wined3d_context *current_context = context_get_current();
- const struct StateEntry *StateTable = This->StateTable;
DWORD tid = GetCurrentThreadId();
struct wined3d_context *context;
- BOOL old_render_offscreen;
if (current_context && current_context->destroyed) current_context = NULL;
{
if (current_context
&& current_context->current_rt
- && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This)
+ && current_context->swapchain->device == This)
{
target = current_context->current_rt;
}
else
{
IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0];
- if (swapchain->backBuffer) target = swapchain->backBuffer[0];
- else target = swapchain->frontBuffer;
+ if (swapchain->back_buffers) target = swapchain->back_buffers[0];
+ else target = swapchain->front_buffer;
}
}
return current_context;
}
- if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
+ if (target->Flags & SFLAG_SWAPCHAIN)
+ {
TRACE("Rendering onscreen\n");
+ swapchain = (IWineD3DSwapChain *)target->container;
context = findThreadContextForSwapChain(swapchain, tid);
-
- old_render_offscreen = context->render_offscreen;
- context->render_offscreen = surface_is_offscreen(target);
- /* The context != This->activeContext will catch a NOP context change. This can occur
- * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
- * rendering. No context change is needed in that case
- */
-
- if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
- if(This->pbufferContext && tid == This->pbufferContext->tid) {
- This->pbufferContext->tid = 0;
- }
- }
- IWineD3DSwapChain_Release(swapchain);
}
else
{
TRACE("Rendering offscreen\n");
-retry:
- if (wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER)
+ /* Stay with the currently active context. */
+ if (current_context && current_context->swapchain->device == This)
{
- IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *)target;
- if (!This->pbufferContext
- || This->pbufferWidth < targetimpl->currentDesc.Width
- || This->pbufferHeight < targetimpl->currentDesc.Height)
- {
- if (This->pbufferContext) context_destroy(This, This->pbufferContext);
-
- /* The display is irrelevant here, the window is 0. But
- * context_create() needs a valid X connection. Create the context
- * on the same server as the primary swapchain. The primary
- * swapchain is exists at this point. */
- This->pbufferContext = context_create(This, targetimpl,
- ((IWineD3DSwapChainImpl *)This->swapchains[0])->context[0]->win_handle,
- TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms);
- This->pbufferWidth = targetimpl->currentDesc.Width;
- This->pbufferHeight = targetimpl->currentDesc.Height;
- if (This->pbufferContext) context_release(This->pbufferContext);
- }
-
- if (This->pbufferContext)
- {
- if (This->pbufferContext->tid && This->pbufferContext->tid != tid)
- {
- FIXME("The PBuffer context is only supported for one thread for now!\n");
- }
- This->pbufferContext->tid = tid;
- context = This->pbufferContext;
- }
- else
- {
- ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering.\n");
- wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
- goto retry;
- }
+ context = current_context;
}
else
{
- /* Stay with the currently active context. */
- if (current_context
- && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This)
- {
- context = current_context;
- }
- else
- {
- /* This may happen if the app jumps straight into offscreen rendering
- * Start using the context of the primary swapchain. tid == 0 is no problem
- * for findThreadContextForSwapChain.
- *
- * Can also happen on thread switches - in that case findThreadContextForSwapChain
- * is perfect to call. */
- context = findThreadContextForSwapChain(This->swapchains[0], tid);
- }
+ /* This may happen if the app jumps straight into offscreen rendering
+ * Start using the context of the primary swapchain. tid == 0 is no problem
+ * for findThreadContextForSwapChain.
+ *
+ * Can also happen on thread switches - in that case findThreadContextForSwapChain
+ * is perfect to call. */
+ context = findThreadContextForSwapChain(This->swapchains[0], tid);
}
-
- old_render_offscreen = context->render_offscreen;
- context->render_offscreen = TRUE;
}
context_validate(context);
- if (context->render_offscreen != old_render_offscreen)
- {
- Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
- Context_MarkStateDirty(context, STATE_VDECL, StateTable);
- Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
- Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
- Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
- }
-
- /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
- * the alpha blend state changes with different render target formats. */
- if (!context->current_rt)
- {
- Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
- }
- else
- {
- const struct GlPixelFormatDesc *old = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.format_desc;
- const struct GlPixelFormatDesc *new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc;
-
- if (old->format != new->format)
- {
- /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
- if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
- || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
- {
- Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
- }
- }
-
- /* When switching away from an offscreen render target, and we're not
- * using FBOs, we have to read the drawable into the texture. This is
- * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There
- * are some things that need care though. PreLoad needs a GL context,
- * and FindContext is called before the context is activated. It also
- * has to be called with the old rendertarget active, otherwise a
- * wrong drawable is read. */
- if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
- && old_render_offscreen && context->current_rt != target)
- {
- BOOL oldInDraw = This->isInDraw;
-
- /* surface_internal_preload() requires a context to load the
- * texture, so it will call context_acquire(). Set isInDraw to true
- * to signal surface_internal_preload() that it has a context. */
-
- /* FIXME: This is just broken. There's no guarantee whatsoever
- * that the currently active context, if any, is appropriate for
- * reading back the render target. We should probably call
- * context_set_current(context) here and then rely on
- * context_acquire() doing the right thing. */
- This->isInDraw = TRUE;
-
- /* Read the back buffer of the old drawable into the destination texture. */
- if (((IWineD3DSurfaceImpl *)context->current_rt)->texture_name_srgb)
- {
- surface_internal_preload(context->current_rt, SRGB_BOTH);
- }
- else
- {
- surface_internal_preload(context->current_rt, SRGB_RGB);
- }
-
- IWineD3DSurface_ModifyLocation(context->current_rt, SFLAG_INDRAWABLE, FALSE);
-
- This->isInDraw = oldInDraw;
- }
- }
-
- context->draw_buffer_dirty = TRUE;
- context->current_rt = target;
-
return context;
}
static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- IWineD3DSurface *rt = context->current_rt;
+ IWineD3DSurfaceImpl *rt = context->current_rt;
IWineD3DDeviceImpl *device;
- device = ((IWineD3DSurfaceImpl *)rt)->resource.device;
+ device = rt->resource.device;
if (!surface_is_offscreen(rt))
{
ENTER_GL();
{
if (!blit)
{
+ unsigned int i;
+
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ {
+ if (device->render_targets[i])
+ device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
+ else
+ device->draw_buffers[i] = GL_NONE;
+ }
+
if (gl_info->supported[ARB_DRAW_BUFFERS])
{
GL_EXTCALL(glDrawBuffersARB(gl_info->limits.buffers, device->draw_buffers));
context->draw_buffer_dirty = TRUE;
}
+static inline void context_set_render_offscreen(struct wined3d_context *context, const struct StateEntry *StateTable,
+ BOOL offscreen)
+{
+ if (context->render_offscreen == offscreen) return;
+
+ Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
+ Context_MarkStateDirty(context, STATE_VDECL, StateTable);
+ Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
+ Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
+ Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
+ context->render_offscreen = offscreen;
+}
+
+static BOOL match_depth_stencil_format(const struct wined3d_format_desc *existing,
+ const struct wined3d_format_desc *required)
+{
+ short existing_depth, existing_stencil, required_depth, required_stencil;
+
+ if(existing == required) return TRUE;
+ if((existing->Flags & WINED3DFMT_FLAG_FLOAT) != (required->Flags & WINED3DFMT_FLAG_FLOAT)) return FALSE;
+
+ getDepthStencilBits(existing, &existing_depth, &existing_stencil);
+ getDepthStencilBits(required, &required_depth, &required_stencil);
+
+ if(existing_depth < required_depth) return FALSE;
+ /* If stencil bits are used the exact amount is required - otherwise wrapping
+ * won't work correctly */
+ if(required_stencil && required_stencil != existing_stencil) return FALSE;
+ return TRUE;
+}
+/* The caller provides a context */
+static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device,
+ struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil)
+{
+ /* Onscreen surfaces are always in a swapchain */
+ IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)context->current_rt->container;
+
+ if (context->render_offscreen || !depth_stencil) return;
+ if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return;
+
+ /* TODO: If the requested format would satisfy the needs of the existing one(reverse match),
+ * or no onscreen depth buffer was created, the OpenGL drawable could be changed to the new
+ * format. */
+ WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n");
+
+ /* The currently active context is the necessary context to access the swapchain's onscreen buffers */
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)context->current_rt, SFLAG_INTEXTURE, NULL);
+ swapchain->render_to_fbo = TRUE;
+ context_set_render_offscreen(context, device->StateTable, TRUE);
+}
+
+/* Context activation is done by the caller. */
+void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
+{
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_validate_onscreen_formats(device, context, NULL);
+
+ if (context->render_offscreen)
+ {
+ FIXME("Applying blit state for an offscreen target with ORM_FBO. This should be avoided.\n");
+ surface_internal_preload(context->current_rt, SRGB_RGB);
+
+ ENTER_GL();
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, context->current_rt, NULL);
+ LEAVE_GL();
+ }
+ else
+ {
+ ENTER_GL();
+ context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ LEAVE_GL();
+ }
+
+ context->draw_buffer_dirty = TRUE;
+ }
+
+ if (context->draw_buffer_dirty)
+ {
+ context_apply_draw_buffer(context, TRUE);
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ context->draw_buffer_dirty = FALSE;
+ }
+
+ SetupForBlit(device, context);
+}
+
/* Context activation is done by the caller. */
-static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, enum ContextUsage usage)
+void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device,
+ IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil)
{
const struct StateEntry *state_table = device->StateTable;
- unsigned int i;
+ GLenum buffer;
- switch (usage) {
- case CTXUSAGE_CLEAR:
- case CTXUSAGE_DRAWPRIM:
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- ENTER_GL();
- context_apply_fbo_state(context);
- LEAVE_GL();
- }
- if (context->draw_buffer_dirty) {
- context_apply_draw_buffer(context, FALSE);
- context->draw_buffer_dirty = FALSE;
- }
- break;
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_validate_onscreen_formats(device, context, depth_stencil);
- case CTXUSAGE_BLIT:
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- if (context->render_offscreen)
- {
- FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
- surface_internal_preload(context->current_rt, SRGB_RGB);
-
- ENTER_GL();
- context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
- context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt);
- context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
- LEAVE_GL();
- } else {
- ENTER_GL();
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
- LEAVE_GL();
- }
- context->draw_buffer_dirty = TRUE;
- }
- if (context->draw_buffer_dirty) {
- context_apply_draw_buffer(context, TRUE);
- if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
- context->draw_buffer_dirty = FALSE;
- }
- }
- break;
+ ENTER_GL();
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, render_target, depth_stencil);
+ LEAVE_GL();
+ }
- default:
- break;
+ if (!surface_is_offscreen(render_target))
+ buffer = surface_get_gl_buffer(render_target);
+ else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ buffer = GL_COLOR_ATTACHMENT0;
+ else
+ buffer = device->offscreenBuffer;
+
+ ENTER_GL();
+ context_set_draw_buffer(context, buffer);
+ LEAVE_GL();
+
+ if (context->last_was_blit)
+ {
+ device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
}
- switch(usage) {
- case CTXUSAGE_RESOURCELOAD:
- /* This does not require any special states to be set up */
- break;
+ /* Blending and clearing should be orthogonal, but tests on the nvidia
+ * driver show that disabling blending when clearing improves the clearing
+ * performance incredibly. */
+ ENTER_GL();
+ glDisable(GL_BLEND);
+ glEnable(GL_SCISSOR_TEST);
+ checkGLcall("glEnable GL_SCISSOR_TEST");
+ LEAVE_GL();
- case CTXUSAGE_CLEAR:
- if(context->last_was_blit) {
- device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
- }
+ context->last_was_blit = FALSE;
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table);
+ Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table);
+}
- /* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling
- * blending when clearing improves the clearing performance incredibly.
- */
+/* Context activation is done by the caller. */
+void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
+{
+ const struct StateEntry *state_table = device->StateTable;
+ unsigned int i;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_validate_onscreen_formats(device, context, device->depth_stencil);
+
+ if (!context->render_offscreen)
+ {
ENTER_GL();
- glDisable(GL_BLEND);
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL);
LEAVE_GL();
- Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
-
+ }
+ else
+ {
ENTER_GL();
- glEnable(GL_SCISSOR_TEST);
- checkGLcall("glEnable GL_SCISSOR_TEST");
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil);
LEAVE_GL();
- context->last_was_blit = FALSE;
- Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table);
- Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table);
- break;
+ }
+ }
+
+ if (context->draw_buffer_dirty)
+ {
+ context_apply_draw_buffer(context, FALSE);
+ context->draw_buffer_dirty = FALSE;
+ }
+
+ if (context->last_was_blit)
+ {
+ device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
+ }
+
+ IWineD3DDeviceImpl_FindTexUnitMap(device);
+ device_preload_textures(device);
+ if (isStateDirty(context, STATE_VDECL))
+ device_update_stream_info(device, context->gl_info);
+
+ ENTER_GL();
+ for (i = 0; i < context->numDirtyEntries; ++i)
+ {
+ DWORD rep = context->dirtyArray[i];
+ DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
+ BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
+ context->isStateDirty[idx] &= ~(1 << shift);
+ state_table[rep].apply(rep, device->stateBlock, context);
+ }
+ LEAVE_GL();
+ context->numDirtyEntries = 0; /* This makes the whole list clean */
+ context->last_was_blit = FALSE;
+}
+
+static void context_setup_target(IWineD3DDeviceImpl *device,
+ struct wined3d_context *context, IWineD3DSurfaceImpl *target)
+{
+ BOOL old_render_offscreen = context->render_offscreen, render_offscreen;
+ const struct StateEntry *StateTable = device->StateTable;
+
+ if (!target) return;
+ else if (context->current_rt == target) return;
+ render_offscreen = surface_is_offscreen(target);
+
+ context_set_render_offscreen(context, StateTable, render_offscreen);
+
+ /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
+ * the alpha blend state changes with different render target formats. */
+ if (!context->current_rt)
+ {
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
+ }
+ else
+ {
+ const struct wined3d_format_desc *old = context->current_rt->resource.format_desc;
+ const struct wined3d_format_desc *new = target->resource.format_desc;
- case CTXUSAGE_DRAWPRIM:
- /* This needs all dirty states applied */
- if(context->last_was_blit) {
- device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
+ if (old->format != new->format)
+ {
+ /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
+ if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
+ || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+ {
+ Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
}
+ }
- IWineD3DDeviceImpl_FindTexUnitMap(device);
- device_preload_textures(device);
- if (isStateDirty(context, STATE_VDECL))
- device_update_stream_info(device, context->gl_info);
+ /* When switching away from an offscreen render target, and we're not
+ * using FBOs, we have to read the drawable into the texture. This is
+ * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There
+ * are some things that need care though. PreLoad needs a GL context,
+ * and FindContext is called before the context is activated. It also
+ * has to be called with the old rendertarget active, otherwise a
+ * wrong drawable is read. */
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && old_render_offscreen && context->current_rt != target)
+ {
+ BOOL oldInDraw = device->isInDraw;
- ENTER_GL();
- for (i = 0; i < context->numDirtyEntries; ++i)
+ /* surface_internal_preload() requires a context to load the
+ * texture, so it will call context_acquire(). Set isInDraw to true
+ * to signal surface_internal_preload() that it has a context. */
+
+ /* FIXME: This is just broken. There's no guarantee whatsoever
+ * that the currently active context, if any, is appropriate for
+ * reading back the render target. We should probably call
+ * context_set_current(context) here and then rely on
+ * context_acquire() doing the right thing. */
+ device->isInDraw = TRUE;
+
+ /* Read the back buffer of the old drawable into the destination texture. */
+ if (context->current_rt->texture_name_srgb)
{
- DWORD rep = context->dirtyArray[i];
- DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
- BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
- context->isStateDirty[idx] &= ~(1 << shift);
- state_table[rep].apply(rep, device->stateBlock, context);
+ surface_internal_preload(context->current_rt, SRGB_BOTH);
+ }
+ else
+ {
+ surface_internal_preload(context->current_rt, SRGB_RGB);
}
- LEAVE_GL();
- context->numDirtyEntries = 0; /* This makes the whole list clean */
- context->last_was_blit = FALSE;
- break;
- case CTXUSAGE_BLIT:
- SetupForBlit(device, context);
- break;
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)context->current_rt, SFLAG_INDRAWABLE, FALSE);
- default:
- FIXME("Unexpected context usage requested\n");
+ device->isInDraw = oldInDraw;
+ }
}
+
+ context->draw_buffer_dirty = TRUE;
+ context->current_rt = target;
}
/*****************************************************************************
* usage: Prepares the context for blitting, drawing or other actions
*
*****************************************************************************/
-struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurface *target, enum ContextUsage usage)
+struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *target)
{
struct wined3d_context *current_context = context_get_current();
struct wined3d_context *context;
- TRACE("device %p, target %p, usage %#x.\n", device, target, usage);
+ TRACE("device %p, target %p.\n", device, target);
context = FindContext(device, target);
+ context_setup_target(device, context, target);
context_enter(context);
if (!context->valid) return context;
}
}
- context_apply_state(context, device, usage);
-
return context;
}
{
/* Override the IWineD3DResource Preload method. */
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
+ UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count;
IWineD3DDeviceImpl *device = This->resource.device;
struct wined3d_context *context = NULL;
- unsigned int i, j;
BOOL srgb_mode;
BOOL *dirty;
+ UINT i;
switch (srgb)
{
{
/* No danger of recursive calls, context_acquire() sets isInDraw to true
* when loading offscreen render targets into their texture. */
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
}
if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
|| This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
{
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < sub_count; ++i)
{
- for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j)
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+
+ if (palette9_changed(surface))
{
- if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[j][i]))
- {
- TRACE("Reloading surface because the d3d8/9 palette was changed.\n");
- /* TODO: This is not necessarily needed with hw palettized texture support. */
- IWineD3DSurface_LoadLocation(This->surfaces[j][i], SFLAG_INSYSMEM, NULL);
- /* Make sure the texture is reloaded because of the palette change,
- * this kills performance though :( */
- IWineD3DSurface_ModifyLocation(This->surfaces[j][i], SFLAG_INTEXTURE, FALSE);
- }
+ TRACE("Reloading surface %p because the d3d8/9 palette was changed.\n", surface);
+ /* TODO: This is not necessarily needed with hw palettized texture support. */
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL);
+ /* Make sure the texture is reloaded because of the palette change,
+ * this kills performance though :( */
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE);
}
}
}
* since the last load then reload the surfaces. */
if (*dirty)
{
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < sub_count; ++i)
{
- for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j)
- {
- IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
- }
+ IWineD3DSurface_LoadTexture((IWineD3DSurface *)This->baseTexture.sub_resources[i], srgb_mode);
}
}
else
static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This)
{
- unsigned int i, j;
+ UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count;
+ UINT i;
TRACE("(%p) : Cleaning up.\n", This);
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < sub_count; ++i)
{
- for (j = 0; j < 6; ++j)
- {
- IWineD3DSurface *surface = This->surfaces[j][i];
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
- if (surface)
- {
- /* Clean out the texture name we gave to the surface so that the
- * surface doesn't try and release it. */
- surface_set_texture_name(surface, 0, TRUE);
- surface_set_texture_name(surface, 0, FALSE);
- surface_set_texture_target(surface, 0);
- IWineD3DSurface_SetContainer(surface, NULL);
- IWineD3DSurface_Release(surface);
- }
+ if (surface)
+ {
+ /* Clean out the texture name we gave to the surface so that the
+ * surface doesn't try and release it. */
+ surface_set_texture_name(surface, 0, TRUE);
+ surface_set_texture_name(surface, 0, FALSE);
+ surface_set_texture_target(surface, 0);
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL);
+ IWineD3DSurface_Release((IWineD3DSurface *)surface);
}
}
basetexture_cleanup((IWineD3DBaseTexture *)This);
cubetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
}
-static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) {
- unsigned int i, j;
+static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface)
+{
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
- TRACE("(%p)\n", This);
+ UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count;
+ UINT i;
+
+ TRACE("iface %p.\n", iface);
/* Unload all the surfaces and reset the texture name. If UnLoad was called on the
* surface before, this one will be a NOP and vice versa. Unloading an unloaded
- * surface is fine
- */
- for (i = 0; i < This->baseTexture.levels; i++) {
- for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
- IWineD3DSurface_UnLoad(This->surfaces[j][i]);
- surface_set_texture_name(This->surfaces[j][i], 0, TRUE);
- surface_set_texture_name(This->surfaces[j][i], 0, FALSE);
- }
+ * surface is fine. */
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+
+ IWineD3DSurface_UnLoad((IWineD3DSurface *)surface);
+ surface_set_texture_name(surface, 0, TRUE);
+ surface_set_texture_name(surface, 0, FALSE);
}
basetexture_unload((IWineD3DBaseTexture *)iface);
TRACE("(%p) : relay to BaseTexture\n", This);
hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc);
- if (set_gl_texture_desc && SUCCEEDED(hr)) {
- UINT i, j;
- for (i = 0; i < This->baseTexture.levels; ++i) {
- for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) {
- if(This->baseTexture.is_srgb) {
- surface_set_texture_name(This->surfaces[j][i], This->baseTexture.texture_srgb.name, TRUE);
- } else {
- surface_set_texture_name(This->surfaces[j][i], This->baseTexture.texture_rgb.name, FALSE);
- }
- }
+ if (set_gl_texture_desc && SUCCEEDED(hr))
+ {
+ UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count;
+ UINT i;
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+
+ if (This->baseTexture.is_srgb)
+ surface_set_texture_name(surface, This->baseTexture.texture_srgb.name, TRUE);
+ else
+ surface_set_texture_name(surface, This->baseTexture.texture_rgb.name, FALSE);
}
}
/* *******************************************
IWineD3DCubeTexture IWineD3DCubeTexture parts follow
******************************************* */
-static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
- IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
+static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface,
+ UINT level, WINED3DSURFACE_DESC *desc)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *surface;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
- if (Level < This->baseTexture.levels) {
- TRACE("(%p) level (%d)\n", This, Level);
- return IWineD3DSurface_GetDesc(This->surfaces[0][Level], pDesc);
+ if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
- return WINED3DERR_INVALIDCALL;
+
+ return IWineD3DSurface_GetDesc(surface, desc);
}
-static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, IWineD3DSurface** ppCubeMapSurface) {
- IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
- HRESULT hr = WINED3DERR_INVALIDCALL;
+static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface,
+ WINED3DCUBEMAP_FACES face, UINT level, IWineD3DSurface **surface)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *s;
- if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
- *ppCubeMapSurface = This->surfaces[FaceType][Level];
- IWineD3DSurface_AddRef(*ppCubeMapSurface);
+ TRACE("iface %p, face %u, level %u, surface %p.\n",
+ iface, face, level, surface);
- hr = WINED3D_OK;
- }
- if (WINED3D_OK == hr) {
- TRACE("(%p) -> faceType(%d) level(%d) returning surface@%p\n", This, FaceType, Level, This->surfaces[FaceType][Level]);
- } else {
- WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType);
+ if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+ IWineD3DSurface_AddRef(s);
+ *surface = s;
+
+ TRACE("Returning surface %p.\n", *surface);
+
+ return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
- HRESULT hr = WINED3DERR_INVALIDCALL;
- IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
+static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface,
+ WINED3DCUBEMAP_FACES face, UINT level, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *surface;
- if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
- hr = IWineD3DSurface_LockRect(This->surfaces[FaceType][Level], pLockedRect, pRect, Flags);
- }
+ TRACE("iface %p, face %u, level %u, locked_rect %p, rect %s, flags %#x.\n",
+ iface, face, level, locked_rect, wine_dbgstr_rect(rect), flags);
- if (WINED3D_OK == hr) {
- TRACE("(%p) -> faceType(%d) level(%d) returning memory@%p success(%u)\n", This, FaceType, Level, pLockedRect->pBits, hr);
- } else {
- WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType);
+ if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+ return IWineD3DSurface_LockRect(surface, locked_rect, rect, flags);
}
-static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level) {
- HRESULT hr = WINED3DERR_INVALIDCALL;
- IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
+static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface,
+ WINED3DCUBEMAP_FACES face, UINT level)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *surface;
- if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
- hr = IWineD3DSurface_UnlockRect(This->surfaces[FaceType][Level]);
- }
+ TRACE("iface %p, face %u, level %u.\n",
+ iface, face, level);
- if (WINED3D_OK == hr) {
- TRACE("(%p) -> faceType(%d) level(%d) success(%u)\n", This, FaceType, Level, hr);
- } else {
- WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType);
+ if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+
+ return IWineD3DSurface_UnlockRect(surface);
}
-static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) {
- HRESULT hr = WINED3DERR_INVALIDCALL;
- IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
- This->baseTexture.texture_rgb.dirty = TRUE;
- This->baseTexture.texture_srgb.dirty = TRUE;
- TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType);
- if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
- surface_add_dirty_rect(This->surfaces[FaceType][0], pDirtyRect);
- hr = WINED3D_OK;
- } else {
- WARN("(%p) overflow FaceType(%d)\n", This, FaceType);
+static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface,
+ WINED3DCUBEMAP_FACES face, const RECT *dirty_rect)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurfaceImpl *surface;
+
+ TRACE("iface %p, face %u, dirty_rect %s.\n",
+ iface, face, wine_dbgstr_rect(dirty_rect));
+
+ if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, face, 0)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+
+ texture->baseTexture.texture_rgb.dirty = TRUE;
+ texture->baseTexture.texture_srgb.dirty = TRUE;
+ surface_add_dirty_rect(surface, dirty_rect);
+
+ return WINED3D_OK;
}
static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl =
IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info);
UINT pow2_edge_length;
unsigned int i, j;
UINT tmp_w;
texture->lpVtbl = &IWineD3DCubeTexture_Vtbl;
- hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_CUBETEXTURE,
- device, 0, usage, format_desc, pool, parent, parent_ops);
+ hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 6, levels,
+ WINED3DRTYPE_CUBETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize basetexture, returning %#x\n", hr);
/* Generate all the surfaces. */
tmp_w = edge_length;
- for (i = 0; i < texture->baseTexture.levels; ++i)
+ for (i = 0; i < texture->baseTexture.level_count; ++i)
{
/* Create the 6 faces. */
for (j = 0; j < 6; ++j)
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
};
+ UINT idx = j * texture->baseTexture.level_count + i;
+ IWineD3DSurface *surface;
hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_w,
- format, usage, pool, i /* Level */, j, &texture->surfaces[j][i]);
+ format, usage, pool, i /* Level */, j, &surface);
if (FAILED(hr))
{
FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr);
- texture->surfaces[j][i] = NULL;
cubetexture_cleanup(texture);
return hr;
}
- IWineD3DSurface_SetContainer(texture->surfaces[j][i], (IWineD3DBase *)texture);
- TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[j][i]);
- surface_set_texture_target(texture->surfaces[j][i], cube_targets[j]);
+ IWineD3DSurface_SetContainer(surface, (IWineD3DBase *)texture);
+ surface_set_texture_target((IWineD3DSurfaceImpl *)surface, cube_targets[j]);
+ texture->baseTexture.sub_resources[idx] = (IWineD3DResourceImpl *)surface;
+ TRACE("Created surface level %u @ %p.\n", i, surface);
}
tmp_w = max(1, tmp_w >> 1);
}
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION This->adapter->gl_info
/* Define the default light parameters as specified by MSDN */
const WINED3DLIGHT WINED3D_default_light = {
else
{
TRACE("Stream %u isn't UP, %p\n", element->input_slot, This->stateBlock->streamSource[element->input_slot]);
- data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], 0, &buffer_object);
+ data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot],
+ &This->adapter->gl_info, &buffer_object);
/* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets
* (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory
{
WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
buffer_object = 0;
- data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot]);
+ data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot],
+ &This->adapter->gl_info);
if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride)
{
FIXME("System memory vertex data load offset is negative!\n");
}
}
+ This->num_buffer_queries = 0;
if (!This->stateBlock->streamIsUP)
{
WORD map = stream_info->use_map;
{
struct wined3d_stream_info_element *element;
struct wined3d_buffer *buffer;
+ struct wined3d_event_query *query;
if (!(map & 1)) continue;
if (buffer->buffer_object != element->buffer_object)
{
element->buffer_object = 0;
- element->data = buffer_get_sysmem(buffer) + (ptrdiff_t)element->data;
+ element->data = buffer_get_sysmem(buffer, &This->adapter->gl_info) + (ptrdiff_t)element->data;
+ }
+
+ query = ((struct wined3d_buffer *) buffer)->query;
+ if(query)
+ {
+ This->buffer_queries[This->num_buffer_queries++] = query;
}
}
}
static void stream_info_element_from_strided(const struct wined3d_gl_info *gl_info,
const struct WineDirect3DStridedData *strided, struct wined3d_stream_info_element *e)
{
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(strided->format, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(strided->format, gl_info);
e->format_desc = format_desc;
e->stride = strided->dwStride;
e->data = strided->lpData;
}
}
+BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context)
+{
+ struct wined3d_context **new_array;
+
+ TRACE("Adding context %p.\n", context);
+
+ if (!device->contexts) new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
+ else new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, sizeof(*new_array) * (device->numContexts + 1));
+
+ if (!new_array)
+ {
+ ERR("Failed to grow the context array.\n");
+ return FALSE;
+ }
+
+ new_array[device->numContexts++] = context;
+ device->contexts = new_array;
+ return TRUE;
+}
+
+void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context)
+{
+ struct wined3d_context **new_array;
+ BOOL found = FALSE;
+ UINT i;
+
+ TRACE("Removing context %p.\n", context);
+
+ for (i = 0; i < device->numContexts; ++i)
+ {
+ if (device->contexts[i] == context)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ ERR("Context %p doesn't exist in context array.\n", context);
+ return;
+ }
+
+ if (!--device->numContexts)
+ {
+ HeapFree(GetProcessHeap(), 0, device->contexts);
+ device->contexts = NULL;
+ return;
+ }
+
+ memmove(&device->contexts[i], &device->contexts[i + 1], (device->numContexts - i) * sizeof(*device->contexts));
+ new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, device->numContexts * sizeof(*device->contexts));
+ if (!new_array)
+ {
+ ERR("Failed to shrink context array. Oh well.\n");
+ return;
+ }
+
+ device->contexts = new_array;
+}
+
+void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect)
+{
+ IWineD3DStateBlockImpl *stateblock = device->stateBlock;
+ WINED3DVIEWPORT *vp = &stateblock->viewport;
+
+ SetRect(rect, vp->X, vp->Y, vp->X + vp->Width, vp->Y + vp->Height);
+
+ if (stateblock->renderState[WINED3DRS_SCISSORTESTENABLE])
+ {
+ IntersectRect(rect, rect, &stateblock->scissorRect);
+ }
+}
+
+void device_switch_onscreen_ds(IWineD3DDeviceImpl *device,
+ struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil)
+{
+ if (device->onscreen_depth_stencil)
+ {
+ surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_DS_OFFSCREEN);
+ surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_DS_OFFSCREEN,
+ device->onscreen_depth_stencil->ds_current_size.cx,
+ device->onscreen_depth_stencil->ds_current_size.cy);
+ IWineD3DSurface_Release((IWineD3DSurface *)device->onscreen_depth_stencil);
+ }
+ device->onscreen_depth_stencil = depth_stencil;
+ IWineD3DSurface_AddRef((IWineD3DSurface *)device->onscreen_depth_stencil);
+}
+
/**********************************************************
* IUnknown parts follows
**********************************************************/
/* NOTE: You must release the parent if the object was created via a callback
** ***************************/
- if (!list_empty(&This->resources)) {
+ if (!list_empty(&This->resources))
+ {
+ IWineD3DResourceImpl *resource;
FIXME("(%p) Device released with resources still bound, acceptable but unexpected\n", This);
- dumpResources(&This->resources);
+
+ LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
+ {
+ WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
+ FIXME("Leftover resource %p with type %s (%#x).\n",
+ resource, debug_d3dresourcetype(type), type);
+ }
}
if(This->contexts) ERR("Context array not freed!\n");
{
struct wined3d_rendertarget_view *object;
+ TRACE("iface %p, resource %p, parent %p, rendertarget_view %p.\n",
+ iface, resource, parent, rendertarget_view);
+
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
return E_OUTOFMEMORY;
}
- object->vtbl = &wined3d_rendertarget_view_vtbl;
- object->refcount = 1;
- IWineD3DResource_AddRef(resource);
- object->resource = resource;
- object->parent = parent;
+ wined3d_rendertarget_view_init(object, resource, parent);
+ TRACE("Created render target view %p.\n", object);
*rendertarget_view = (IWineD3DRendertargetView *)object;
return WINED3D_OK;
return WINED3D_OK;
}
-static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */
- DWORD fvf, WINED3DVERTEXELEMENT** ppVertexElements) {
+struct wined3d_fvf_convert_state
+{
+ const struct wined3d_gl_info *gl_info;
+ WINED3DVERTEXELEMENT *elements;
+ UINT offset;
+ UINT idx;
+};
+
+static void append_decl_element(struct wined3d_fvf_convert_state *state,
+ WINED3DFORMAT format, WINED3DDECLUSAGE usage, UINT usage_idx)
+{
+ WINED3DVERTEXELEMENT *elements = state->elements;
+ const struct wined3d_format_desc *format_desc;
+ UINT offset = state->offset;
+ UINT idx = state->idx;
+
+ elements[idx].format = format;
+ elements[idx].input_slot = 0;
+ elements[idx].offset = offset;
+ elements[idx].output_slot = 0;
+ elements[idx].method = WINED3DDECLMETHOD_DEFAULT;
+ elements[idx].usage = usage;
+ elements[idx].usage_idx = usage_idx;
+
+ format_desc = getFormatDescEntry(format, state->gl_info);
+ state->offset += format_desc->component_count * format_desc->component_size;
+ ++state->idx;
+}
- unsigned int idx, idx2;
- unsigned int offset;
+static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */
+ DWORD fvf, WINED3DVERTEXELEMENT **ppVertexElements)
+{
+ const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
BOOL has_pos = (fvf & WINED3DFVF_POSITION_MASK) != 0;
BOOL has_blend = (fvf & WINED3DFVF_XYZB5) > WINED3DFVF_XYZRHW;
BOOL has_blend_idx = has_blend &&
DWORD num_textures = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
DWORD texcoords = (fvf & 0xFFFF0000) >> 16;
- WINED3DVERTEXELEMENT *elements = NULL;
-
+ struct wined3d_fvf_convert_state state;
unsigned int size;
+ unsigned int idx;
DWORD num_blends = 1 + (((fvf & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1);
if (has_blend_idx) num_blends--;
size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal +
has_psize + has_diffuse + has_specular + num_textures;
- /* convert the declaration */
- elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WINED3DVERTEXELEMENT));
- if (!elements) return ~0U;
+ state.gl_info = gl_info;
+ state.elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*state.elements));
+ if (!state.elements) return ~0U;
+ state.offset = 0;
+ state.idx = 0;
- idx = 0;
- if (has_pos) {
- if (!has_blend && (fvf & WINED3DFVF_XYZRHW)) {
- elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;
- elements[idx].usage = WINED3DDECLUSAGE_POSITIONT;
- }
- else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) {
- elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;
- elements[idx].usage = WINED3DDECLUSAGE_POSITION;
- }
- else {
- elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;
- elements[idx].usage = WINED3DDECLUSAGE_POSITION;
- }
- elements[idx].usage_idx = 0;
- idx++;
- }
- if (has_blend && (num_blends > 0)) {
- if (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))
- elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
- else {
- switch(num_blends) {
- case 1: elements[idx].format = WINED3DFMT_R32_FLOAT; break;
- case 2: elements[idx].format = WINED3DFMT_R32G32_FLOAT; break;
- case 3: elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; break;
- case 4: elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
+ if (has_pos)
+ {
+ if (!has_blend && (fvf & WINED3DFVF_XYZRHW))
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITIONT, 0);
+ else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW)
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITION, 0);
+ else
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_POSITION, 0);
+ }
+
+ if (has_blend && (num_blends > 0))
+ {
+ if ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))
+ append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
+ else
+ {
+ switch (num_blends)
+ {
+ case 1:
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
+ break;
+ case 2:
+ append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
+ break;
+ case 3:
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
+ break;
+ case 4:
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0);
+ break;
default:
ERR("Unexpected amount of blend values: %u\n", num_blends);
}
}
- elements[idx].usage = WINED3DDECLUSAGE_BLENDWEIGHT;
- elements[idx].usage_idx = 0;
- idx++;
- }
- if (has_blend_idx) {
- if (fvf & WINED3DFVF_LASTBETA_UBYTE4 ||
- (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)))
- elements[idx].format = WINED3DFMT_R8G8B8A8_UINT;
+ }
+
+ if (has_blend_idx)
+ {
+ if ((fvf & WINED3DFVF_LASTBETA_UBYTE4)
+ || ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)))
+ append_decl_element(&state, WINED3DFMT_R8G8B8A8_UINT, WINED3DDECLUSAGE_BLENDINDICES, 0);
else if (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)
- elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
+ append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDINDICES, 0);
else
- elements[idx].format = WINED3DFMT_R32_FLOAT;
- elements[idx].usage = WINED3DDECLUSAGE_BLENDINDICES;
- elements[idx].usage_idx = 0;
- idx++;
- }
- if (has_normal) {
- elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;
- elements[idx].usage = WINED3DDECLUSAGE_NORMAL;
- elements[idx].usage_idx = 0;
- idx++;
- }
- if (has_psize) {
- elements[idx].format = WINED3DFMT_R32_FLOAT;
- elements[idx].usage = WINED3DDECLUSAGE_PSIZE;
- elements[idx].usage_idx = 0;
- idx++;
- }
- if (has_diffuse) {
- elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
- elements[idx].usage = WINED3DDECLUSAGE_COLOR;
- elements[idx].usage_idx = 0;
- idx++;
- }
- if (has_specular) {
- elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM;
- elements[idx].usage = WINED3DDECLUSAGE_COLOR;
- elements[idx].usage_idx = 1;
- idx++;
- }
- for (idx2 = 0; idx2 < num_textures; idx2++) {
- unsigned int numcoords = (texcoords >> (idx2*2)) & 0x03;
- switch (numcoords) {
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDINDICES, 0);
+ }
+
+ if (has_normal) append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_NORMAL, 0);
+ if (has_psize) append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_PSIZE, 0);
+ if (has_diffuse) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 0);
+ if (has_specular) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 1);
+
+ for (idx = 0; idx < num_textures; ++idx)
+ {
+ switch ((texcoords >> (idx * 2)) & 0x03)
+ {
case WINED3DFVF_TEXTUREFORMAT1:
- elements[idx].format = WINED3DFMT_R32_FLOAT;
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
break;
case WINED3DFVF_TEXTUREFORMAT2:
- elements[idx].format = WINED3DFMT_R32G32_FLOAT;
+ append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
break;
case WINED3DFVF_TEXTUREFORMAT3:
- elements[idx].format = WINED3DFMT_R32G32B32_FLOAT;
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
break;
case WINED3DFVF_TEXTUREFORMAT4:
- elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT;
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx);
break;
}
- elements[idx].usage = WINED3DDECLUSAGE_TEXCOORD;
- elements[idx].usage_idx = idx2;
- idx++;
- }
-
- /* Now compute offsets, and initialize the rest of the fields */
- for (idx = 0, offset = 0; idx < size; ++idx)
- {
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(elements[idx].format, &This->adapter->gl_info);
- elements[idx].input_slot = 0;
- elements[idx].method = WINED3DDECLMETHOD_DEFAULT;
- elements[idx].offset = offset;
- offset += format_desc->component_count * format_desc->component_size;
}
- *ppVertexElements = elements;
+ *ppVertexElements = state.elements;
return size;
}
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
IWineD3DPaletteImpl *object;
HRESULT hr;
- TRACE("(%p)->(%x, %p, %p, %p)\n", This, Flags, PalEnt, Palette, Parent);
- /* Create the new object */
- object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DPaletteImpl));
- if(!object) {
- ERR("Out of memory when allocating memory for a IWineD3DPalette implementation\n");
- return E_OUTOFMEMORY;
- }
+ TRACE("iface %p, flags %#x, entries %p, palette %p, parent %p.\n",
+ iface, Flags, PalEnt, Palette, Parent);
- object->lpVtbl = &IWineD3DPalette_Vtbl;
- object->ref = 1;
- object->Flags = Flags;
- object->parent = Parent;
- object->device = This;
- object->palNumEntries = IWineD3DPaletteImpl_Size(Flags);
- object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion));
-
- if(!object->hpal) {
- HeapFree( GetProcessHeap(), 0, object);
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ ERR("Failed to allocate palette memory.\n");
return E_OUTOFMEMORY;
}
- hr = IWineD3DPalette_SetEntries((IWineD3DPalette *) object, 0, 0, IWineD3DPaletteImpl_Size(Flags), PalEnt);
- if(FAILED(hr)) {
- IWineD3DPalette_Release((IWineD3DPalette *) object);
+ hr = wined3d_palette_init(object, This, Flags, PalEnt, Parent);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize palette, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
return hr;
}
- *Palette = (IWineD3DPalette *) object;
+ TRACE("Created palette %p.\n", object);
+ *Palette = (IWineD3DPalette *)object;
return WINED3D_OK;
}
memset(device->dummyTextureName, 0, gl_info->limits.textures * sizeof(*device->dummyTextureName));
}
+static HRESULT WINAPI IWineD3DDeviceImpl_AcquireFocusWindow(IWineD3DDevice *iface, HWND window)
+{
+ IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
+
+ if (!wined3d_register_window(window, device))
+ {
+ ERR("Failed to register window %p.\n", window);
+ return E_FAIL;
+ }
+
+ device->focus_window = window;
+ SetForegroundWindow(window);
+
+ return WINED3D_OK;
+}
+
+static void WINAPI IWineD3DDeviceImpl_ReleaseFocusWindow(IWineD3DDevice *iface)
+{
+ IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
+
+ if (device->focus_window) wined3d_unregister_window(device->focus_window);
+ device->focus_window = NULL;
+}
+
static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
WINED3DPRESENT_PARAMETERS *pPresentationParameters)
{
if(This->d3d_initialized) return WINED3DERR_INVALIDCALL;
if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL;
- if (!pPresentationParameters->Windowed)
- {
- This->focus_window = This->createParms.hFocusWindow;
- if (!This->focus_window) This->focus_window = pPresentationParameters->hDeviceWindow;
- if (!wined3d_register_window(This->focus_window, This))
- {
- ERR("Failed to register window %p.\n", This->focus_window);
- return E_FAIL;
- }
- }
-
TRACE("(%p) : Creating stateblock\n", This);
/* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
hr = IWineD3DDevice_CreateStateBlock(iface,
IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock);
This->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(IWineD3DSurface *) * gl_info->limits.buffers);
+ sizeof(*This->render_targets) * gl_info->limits.buffers);
This->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(GLenum) * gl_info->limits.buffers);
}
}
- if (This->focus_window) SetFocus(This->focus_window);
-
/* Setup the implicit swapchain. This also initializes a context. */
TRACE("Creating implicit swapchain\n");
hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent,
}
This->swapchains[0] = (IWineD3DSwapChain *) swapchain;
- if(swapchain->backBuffer && swapchain->backBuffer[0]) {
- TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
- This->render_targets[0] = swapchain->backBuffer[0];
+ if (swapchain->back_buffers && swapchain->back_buffers[0])
+ {
+ TRACE("Setting rendertarget to %p.\n", swapchain->back_buffers);
+ This->render_targets[0] = swapchain->back_buffers[0];
}
- else {
- TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer);
- This->render_targets[0] = swapchain->frontBuffer;
+ else
+ {
+ TRACE("Setting rendertarget to %p.\n", swapchain->front_buffer);
+ This->render_targets[0] = swapchain->front_buffer;
}
- IWineD3DSurface_AddRef(This->render_targets[0]);
+ IWineD3DSurface_AddRef((IWineD3DSurface *)This->render_targets[0]);
/* Depth Stencil support */
- This->stencilBufferTarget = This->auto_depth_stencil_buffer;
- if (NULL != This->stencilBufferTarget) {
- IWineD3DSurface_AddRef(This->stencilBufferTarget);
- }
+ This->depth_stencil = This->auto_depth_stencil;
+ if (This->depth_stencil)
+ IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil);
hr = This->shader_backend->shader_alloc_private(iface);
if(FAILED(hr)) {
/* Setup all the devices defaults */
IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock);
- context = context_acquire(This, swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, swapchain->front_buffer);
create_dummy_textures(This);
This->offscreenBuffer = GL_COLOR_ATTACHMENT0;
break;
- case ORM_PBUFFER:
- This->offscreenBuffer = GL_BACK;
- break;
-
case ORM_BACKBUFFER:
{
if (context_get_current()->aux_buffers > 0)
if (This->shader_priv) {
This->shader_backend->shader_free_private(iface);
}
- if (This->focus_window) wined3d_unregister_window(This->focus_window);
return hr;
}
/* 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
*/
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, NULL);
gl_info = context->gl_info;
if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
}
}
- /* Delete the pbuffer context if there is any */
- if(This->pbufferContext) context_destroy(This, This->pbufferContext);
-
/* Delete the mouse cursor texture */
if(This->cursorTexture) {
ENTER_GL();
This->shader_backend->shader_free_private(iface);
/* 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->auto_depth_stencil_buffer != This->stencilBufferTarget)
- FIXME("(%p) Something's still holding the stencilBufferTarget\n",This);
+ if (This->onscreen_depth_stencil)
+ {
+ IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil);
+ This->onscreen_depth_stencil = NULL;
}
- This->stencilBufferTarget = NULL;
- TRACE("Releasing the render target at %p\n", This->render_targets[0]);
- if(IWineD3DSurface_Release(This->render_targets[0]) >0){
- /* This check is a bit silly, it should be in swapchain_release FIXME("(%p) Something's still holding the renderTarget\n",This); */
+ TRACE("Releasing the depth stencil buffer at %p\n", This->depth_stencil);
+ if (This->depth_stencil && IWineD3DSurface_Release((IWineD3DSurface *)This->depth_stencil))
+ {
+ if (This->auto_depth_stencil != This->depth_stencil)
+ FIXME("(%p) Something is still holding the depth/stencil buffer.\n",This);
}
+ This->depth_stencil = NULL;
+
+ TRACE("Releasing the render target at %p\n", This->render_targets[0]);
+ IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[0]);
+
TRACE("Setting rendertarget to NULL\n");
This->render_targets[0] = NULL;
- if (This->auto_depth_stencil_buffer) {
- if (IWineD3DSurface_Release(This->auto_depth_stencil_buffer) > 0)
+ if (This->auto_depth_stencil)
+ {
+ if (IWineD3DSurface_Release((IWineD3DSurface *)This->auto_depth_stencil))
{
FIXME("(%p) Something's still holding the auto depth stencil buffer\n", This);
}
- This->auto_depth_stencil_buffer = NULL;
+ This->auto_depth_stencil = NULL;
}
context_release(context);
This->d3d_initialized = FALSE;
- if (This->focus_window) wined3d_unregister_window(This->focus_window);
-
return WINED3D_OK;
}
const WINED3DDISPLAYMODE* pMode) {
DEVMODEW devmode;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info);
LONG ret;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info);
RECT clip_rc;
TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count);
- if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= (signed int) 0)
+ if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= 0)
return WINED3DERR_INVALIDCALL;
memcpy(dstData, &This->stateBlock->vertexShaderConstantI[start * 4], cnt * sizeof(int) * 4);
/* We might access VBOs from this code, so hold the lock */
ENTER_GL();
- if (dest->resource.allocatedMemory == NULL) {
- buffer_get_sysmem(dest);
- }
+ if (!dest->resource.allocatedMemory)
+ buffer_get_sysmem(dest, gl_info);
/* Get a pointer into the destination vbo(create one if none exists) and
* write correct opengl data into it. It's cheap and allows us to run drawStridedFast
FIXME("Clipping is broken and disabled for now\n");
}
} else doClip = FALSE;
- dest_ptr = ((char *) buffer_get_sysmem(dest)) + dwDestIndex * get_flexible_vertex_size(DestFVF);
+ dest_ptr = ((char *)buffer_get_sysmem(dest, gl_info)) + dwDestIndex * get_flexible_vertex_size(DestFVF);
IWineD3DDevice_GetTransform( (IWineD3DDevice *) This,
WINED3DTS_VIEW,
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
struct wined3d_stream_info stream_info;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
BOOL vbo = FALSE, streamWasUP = This->stateBlock->streamIsUP;
HRESULT hr;
}
/* Need any context to write to the vbo. */
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, NULL);
+ gl_info = context->gl_info;
/* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP
* control the streamIsUP flag, thus restore it afterwards.
{
struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
e->buffer_object = 0;
- e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
+ e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, gl_info));
ENTER_GL();
GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object));
vb->buffer_object = 0;
return WINED3DERR_INVALIDCALL;
}
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, NULL);
/* We only have to do this if we need to read the, swapbuffers performs a flush for us */
wglFlush();
/* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever
return WINED3D_OK;
}
+static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const RECT *draw_rect, const RECT *clear_rect)
+{
+ /* partial draw rect */
+ if (draw_rect->left || draw_rect->top
+ || draw_rect->right < target->currentDesc.Width
+ || draw_rect->bottom < target->currentDesc.Height)
+ return FALSE;
+
+ /* partial clear rect */
+ if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0
+ || clear_rect->right < target->currentDesc.Width
+ || clear_rect->bottom < target->currentDesc.Height))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *context,
+ DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect)
+{
+ RECT current_rect, r;
+
+ if (ds->Flags & location)
+ SetRect(¤t_rect, 0, 0,
+ ds->ds_current_size.cx,
+ ds->ds_current_size.cy);
+ else
+ SetRectEmpty(¤t_rect);
+
+ IntersectRect(&r, draw_rect, ¤t_rect);
+ if (EqualRect(&r, draw_rect))
+ {
+ /* current_rect ⊇ draw_rect, modify only. */
+ surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy);
+ return;
+ }
+
+ if (EqualRect(&r, ¤t_rect))
+ {
+ /* draw_rect ⊇ current_rect, test if we're doing a full clear. */
+
+ if (!clear_rect)
+ {
+ /* Full clear, modify only. */
+ surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom);
+ return;
+ }
+
+ IntersectRect(&r, draw_rect, clear_rect);
+ if (EqualRect(&r, draw_rect))
+ {
+ /* clear_rect ⊇ draw_rect, modify only. */
+ surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom);
+ return;
+ }
+ }
+
+ /* Full load. */
+ surface_load_ds_location(ds, context, location);
+ surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy);
+}
+
/* Not called from the VTable (internal subroutine) */
-HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
- CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color,
- float Z, DWORD Stencil) {
+HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
+ const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil)
+{
+ const RECT *clear_rect = (Count > 0 && pRects) ? (const RECT *)pRects : NULL;
+ IWineD3DSurfaceImpl *depth_stencil = This->depth_stencil;
GLbitfield glMask = 0;
unsigned int i;
- WINED3DRECT curRect;
- RECT vp_rect;
- const WINED3DVIEWPORT *vp = &This->stateBlock->viewport;
UINT drawable_width, drawable_height;
- IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
struct wined3d_context *context;
+ RECT draw_rect;
+
+ device_get_draw_rect(This, &draw_rect);
/* 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
* the drawable up to date. We have to check all settings that limit the clear area though. Do not bother
* checking all this if the dest surface is in the drawable anyway.
*/
- if((Flags & WINED3DCLEAR_TARGET) && !(target->Flags & SFLAG_INDRAWABLE)) {
- while(1) {
- if(vp->X != 0 || vp->Y != 0 ||
- vp->Width < target->currentDesc.Width || vp->Height < target->currentDesc.Height) {
- IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
- break;
- }
- if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && (
- This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 ||
- This->stateBlock->scissorRect.right < target->currentDesc.Width ||
- This->stateBlock->scissorRect.bottom < target->currentDesc.Height)) {
- IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
- break;
- }
- if(Count > 0 && pRects && (
- pRects[0].x1 > 0 || pRects[0].y1 > 0 ||
- pRects[0].x2 < target->currentDesc.Width ||
- pRects[0].y2 < target->currentDesc.Height)) {
- IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
- break;
- }
- break;
- }
+ if (Flags & WINED3DCLEAR_TARGET && !(target->Flags & SFLAG_INDRAWABLE))
+ {
+ if (!is_full_clear(target, &draw_rect, clear_rect))
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL);
}
- context = context_acquire(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR);
+ context = context_acquire(This, target);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping clear.\n");
+ return WINED3D_OK;
+ }
+
+ context_apply_clear_state(context, This, target, depth_stencil);
target->get_drawable_size(context, &drawable_width, &drawable_height);
ENTER_GL();
/* Only set the values up once, as they are not changing */
- if (Flags & WINED3DCLEAR_STENCIL) {
+ if (Flags & WINED3DCLEAR_STENCIL)
+ {
+ if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE])
+ {
+ glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE));
+ }
+ glStencilMask(~0U);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK));
glClearStencil(Stencil);
checkGLcall("glClearStencil");
glMask = glMask | GL_STENCIL_BUFFER_BIT;
- glStencilMask(0xFFFFFFFF);
}
- if (Flags & WINED3DCLEAR_ZBUFFER) {
+ if (Flags & WINED3DCLEAR_ZBUFFER)
+ {
DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+
+ if (location == SFLAG_DS_ONSCREEN && depth_stencil != This->onscreen_depth_stencil)
+ device_switch_onscreen_ds(This, context, depth_stencil);
+ prepare_ds_clear(depth_stencil, context, location, &draw_rect, Count, clear_rect);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)depth_stencil, SFLAG_INDRAWABLE, TRUE);
+
glDepthMask(GL_TRUE);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE));
glClearDepth(Z);
checkGLcall("glClearDepth");
glMask = glMask | GL_DEPTH_BUFFER_BIT;
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE));
-
- 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, 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, 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, context, location);
- }
}
- if (Flags & WINED3DCLEAR_TARGET) {
- TRACE("Clearing screen with glClear to color %x\n", Color);
- glClearColor(D3DCOLOR_R(Color),
- D3DCOLOR_G(Color),
- D3DCOLOR_B(Color),
- D3DCOLOR_A(Color));
- checkGLcall("glClearColor");
+ if (Flags & WINED3DCLEAR_TARGET)
+ {
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
- /* Clear ALL colors! */
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3));
+ glClearColor(D3DCOLOR_R(Color), D3DCOLOR_G(Color), D3DCOLOR_B(Color), D3DCOLOR_A(Color));
+ checkGLcall("glClearColor");
glMask = glMask | GL_COLOR_BUFFER_BIT;
}
- vp_rect.left = vp->X;
- vp_rect.top = vp->Y;
- vp_rect.right = vp->X + vp->Width;
- vp_rect.bottom = vp->Y + vp->Height;
- if (!(Count > 0 && pRects)) {
- if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
- IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect);
- }
+ if (!clear_rect)
+ {
if (context->render_offscreen)
{
- glScissor(vp_rect.left, vp_rect.top,
- vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top);
- } else {
- glScissor(vp_rect.left, drawable_height - vp_rect.bottom,
- vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top);
+ glScissor(draw_rect.left, draw_rect.top,
+ draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top);
+ }
+ else
+ {
+ glScissor(draw_rect.left, drawable_height - draw_rect.bottom,
+ draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top);
}
checkGLcall("glScissor");
glClear(glMask);
checkGLcall("glClear");
- } else {
- /* Now process each rect in turn */
- for (i = 0; i < Count; i++) {
+ }
+ else
+ {
+ RECT current_rect;
+
+ /* Now process each rect in turn. */
+ for (i = 0; i < Count; ++i)
+ {
/* Note gl uses lower left, width/height */
- IntersectRect((RECT *)&curRect, &vp_rect, (const RECT *)&pRects[i]);
- if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
- IntersectRect((RECT *) &curRect, (RECT *) &curRect, &This->stateBlock->scissorRect);
- }
- TRACE("(%p) Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d\n", This,
- pRects[i].x1, pRects[i].y1, pRects[i].x2, pRects[i].y2,
- curRect.x1, (target->currentDesc.Height - curRect.y2),
- curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
+ IntersectRect(¤t_rect, &draw_rect, &clear_rect[i]);
+
+ TRACE("clear_rect[%u] %s, current_rect %s.\n", i,
+ wine_dbgstr_rect(&clear_rect[i]),
+ wine_dbgstr_rect(¤t_rect));
/* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently.
* The rectangle is not cleared, no error is returned, but further rectanlges are
- * still cleared if they are valid
- */
- if(curRect.x1 > curRect.x2 || curRect.y1 > curRect.y2) {
- TRACE("Rectangle with negative dimensions, ignoring\n");
+ * still cleared if they are valid. */
+ if (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom)
+ {
+ TRACE("Rectangle with negative dimensions, ignoring.\n");
continue;
}
if (context->render_offscreen)
{
- glScissor(curRect.x1, curRect.y1,
- curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
- } else {
- glScissor(curRect.x1, drawable_height - curRect.y2,
- curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
+ glScissor(current_rect.left, current_rect.top,
+ current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
+ }
+ else
+ {
+ glScissor(current_rect.left, drawable_height - current_rect.bottom,
+ current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
}
checkGLcall("glScissor");
}
}
- /* Restore the old values (why..?) */
- if (Flags & WINED3DCLEAR_STENCIL) {
- glStencilMask(This->stateBlock->renderState[WINED3DRS_STENCILWRITEMASK]);
- }
- if (Flags & WINED3DCLEAR_TARGET) {
- DWORD mask = This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE];
- glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
- mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
- mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
- mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
-
- /* 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((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
- }
- if (Flags & WINED3DCLEAR_ZBUFFER) {
- /* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */
- DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
- surface_modify_ds_location(This->stencilBufferTarget, location);
- }
-
LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN)
+ && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target))
+ wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, CONST WINED3DRECT* pRects,
- DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) {
+static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count,
+ const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)This->render_targets[0];
TRACE("(%p) Count (%d), pRects (%p), Flags (%x), Color (0x%08x), Z (%f), Stencil (%d)\n", This,
Count, pRects, Flags, Color, Z, Stencil);
- if(Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && This->stencilBufferTarget == NULL) {
+ if (Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && !This->depth_stencil)
+ {
WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n");
/* TODO: What about depth stencil buffers without stencil bits? */
return WINED3DERR_INVALIDCALL;
}
- return IWineD3DDeviceImpl_ClearSurface(This, target, Count, pRects, Flags, Color, Z, Stencil);
+ return IWineD3DDeviceImpl_ClearSurface(This, This->render_targets[0], Count, pRects, Flags, Color, Z, Stencil);
}
/*****
return 0.0f;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, IWineD3DSurface *pSourceSurface, CONST RECT* pSourceRect, IWineD3DSurface *pDestinationSurface, CONST POINT* pDestPoint) {
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
- /** TODO: remove casts to IWineD3DSurfaceImpl
- * 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;
- UINT destSize;
- int srcLeft, destLeft, destTop;
- 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 */
- const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc;
- GLenum dummy;
- DWORD sampler;
- int bpp;
- CONVERT_TYPES convert = NO_CONVERSION;
+static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
+ IWineD3DSurface *src_surface, const RECT *src_rect,
+ IWineD3DSurface *dst_surface, const POINT *dst_point)
+{
+ IWineD3DSurfaceImpl *src_impl = (IWineD3DSurfaceImpl *)src_surface;
+ IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)dst_surface;
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ const struct wined3d_format_desc *src_format;
+ const struct wined3d_format_desc *dst_format;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
+ const unsigned char *data;
+ UINT update_w, update_h;
+ CONVERT_TYPES convert;
+ UINT src_w, src_h;
+ UINT dst_x, dst_y;
+ DWORD sampler;
+ struct wined3d_format_desc desc;
- WINED3DSURFACE_DESC winedesc;
-
- TRACE("(%p) : Source (%p) Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
-
- IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
- 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;
+ TRACE("iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n",
+ iface, src_surface, wine_dbgstr_rect(src_rect),
+ dst_surface, wine_dbgstr_point(dst_point));
- 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);
+ if (src_impl->resource.pool != WINED3DPOOL_SYSTEMMEM || dst_impl->resource.pool != WINED3DPOOL_DEFAULT)
+ {
+ WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n",
+ src_surface, dst_surface);
return WINED3DERR_INVALIDCALL;
}
- /* This call loads the opengl surface directly, instead of copying the surface to the
- * destination's sysmem copy. If surface conversion is needed, use BltFast instead to
- * copy in sysmem and use regular surface loading.
- */
- 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,
- pDestPoint ? pDestPoint->y : 0,
- pSourceSurface, pSourceRect, 0);
+ src_format = src_impl->resource.format_desc;
+ dst_format = dst_impl->resource.format_desc;
+
+ if (src_format->format != dst_format->format)
+ {
+ WARN("Source and destination surfaces should have the same format.\n");
+ return WINED3DERR_INVALIDCALL;
}
- if (destFormat == WINED3DFMT_UNKNOWN) {
- TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", This);
- IWineD3DSurface_SetFormat(pDestinationSurface, srcFormat);
+ dst_x = dst_point ? dst_point->x : 0;
+ dst_y = dst_point ? dst_point->y : 0;
- /* Get the update surface description */
- IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
- }
+ /* This call loads the OpenGL surface directly, instead of copying the
+ * surface to the destination's sysmem copy. If surface conversion is
+ * needed, use BltFast instead to copy in sysmem and use regular surface
+ * loading. */
+ d3dfmt_get_conv(dst_impl, FALSE, TRUE, &desc, &convert);
+ if (convert != NO_CONVERSION || desc.convert)
+ return IWineD3DSurface_BltFast(dst_surface, dst_x, dst_y, src_surface, src_rect, 0);
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, NULL);
+ gl_info = context->gl_info;
ENTER_GL();
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
LEAVE_GL();
/* Make sure the surface is loaded and up to date */
- surface_internal_preload(pDestinationSurface, SRGB_RGB);
- IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
+ surface_internal_preload(dst_impl, SRGB_RGB);
+ IWineD3DSurface_BindTexture(dst_surface, FALSE);
- src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc;
- dst_format_desc = dst_impl->resource.format_desc;
+ src_w = src_impl->currentDesc.Width;
+ src_h = src_impl->currentDesc.Height;
+ update_w = src_rect ? src_rect->right - src_rect->left : src_w;
+ update_h = src_rect ? src_rect->bottom - src_rect->top : src_h;
- /* this needs to be done in lines if the sourceRect != the sourceWidth */
- srcWidth = pSourceRect ? pSourceRect->right - pSourceRect->left : srcSurfaceWidth;
- srcHeight = pSourceRect ? pSourceRect->bottom - pSourceRect->top : srcSurfaceHeight;
- srcLeft = pSourceRect ? pSourceRect->left : 0;
- destLeft = pDestPoint ? pDestPoint->x : 0;
- destTop = pDestPoint ? pDestPoint->y : 0;
-
-
- /* This function doesn't support compressed textures
- the pitch is just bytesPerPixel * width */
- if(srcWidth != srcSurfaceWidth || srcLeft ){
- rowoffset = srcSurfaceWidth * src_format_desc->byte_count;
- offset += srcLeft * src_format_desc->byte_count;
- /* TODO: do we ever get 3bpp?, would a shift and an add be quicker than a mul (well maybe a cycle or two) */
- }
- /* TODO DXT formats */
-
- if(pSourceRect != NULL && pSourceRect->top != 0){
- 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, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
- dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset);
-
- /* Sanity check */
- if (IWineD3DSurface_GetData(pSourceSurface) == NULL) {
-
- /* need to lock the surface to get the data */
- FIXME("Surfaces has no allocated memory, but should be an in memory only surface\n");
- }
+ data = IWineD3DSurface_GetData(src_surface);
+ if (!data) ERR("Source surface has no allocated memory, but should be a sysmem surface.\n");
ENTER_GL();
- /* TODO: Cube and volume support */
- if(rowoffset != 0){
- /* not a whole row so we have to do it a line at a time */
- int j;
-
- /* hopefully using pointer addition will be quicker than using a point + j * rowoffset */
- const unsigned char* data =((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
+ if (dst_format->Flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ UINT row_length = (update_w / src_format->block_width) * src_format->block_byte_count;
+ UINT row_count = update_h / src_format->block_height;
+ UINT src_pitch = IWineD3DSurface_GetPitch(src_surface);
- for (j = destTop; j < (srcHeight + destTop); ++j)
+ if (src_rect)
{
- glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j,
- srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data);
- data += rowoffset;
+ data += (src_rect->top / src_format->block_height) * src_pitch;
+ data += (src_rect->left / src_format->block_width) * src_format->block_byte_count;
}
- } else { /* Full width, so just write out the whole texture */
- const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
+ TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
+ "format %#x, image_size %#x, data %p.\n", dst_impl->texture_target, dst_impl->texture_level,
+ dst_x, dst_y, update_w, update_h, dst_format->glFormat, row_count * row_length, data);
- if (dst_format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+ if (row_length == src_pitch)
{
- 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");
- }
- if (destFormat != srcFormat)
- {
- FIXME("Updating mixed format compressed textures is not supported.\n");
- }
- else
+ GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
+ dst_x, dst_y, update_w, update_h, dst_format->glInternal, row_count * row_length, data));
+ }
+ else
+ {
+ UINT row, y;
+
+ /* glCompressedTexSubImage2DARB() ignores pixel store state, so we
+ * can't use the unpack row length like below. */
+ for (row = 0, y = dst_y; row < row_count; ++row)
{
- GL_EXTCALL(glCompressedTexImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
- dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data));
+ GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
+ dst_x, y, update_w, src_format->block_height, dst_format->glInternal, row_length, data));
+ y += src_format->block_height;
+ data += src_pitch;
}
}
- else
+ checkGLcall("glCompressedTexSubImage2DARB");
+ }
+ else
+ {
+ if (src_rect)
{
- glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop,
- srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data);
+ data += src_rect->top * src_w * src_format->byte_count;
+ data += src_rect->left * src_format->byte_count;
}
- }
- checkGLcall("glTexSubImage2D");
+
+ TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, data %p.\n",
+ dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y,
+ update_w, update_h, dst_format->glFormat, dst_format->glType, data);
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, src_w);
+ glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y,
+ update_w, update_h, dst_format->glFormat, dst_format->glType, data);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ checkGLcall("glTexSubImage2D");
+ }
LEAVE_GL();
context_release(context);
- IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE);
+ IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INTEXTURE, TRUE);
sampler = This->rev_tex_unit_map[0];
if (sampler != WINED3D_UNMAPPED_STAGE)
{
return WINED3DERR_INVALIDCALL;
}
-static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
- HRESULT hr;
- IWineD3DSwapChain *swapchain;
-
- hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
- if (SUCCEEDED(hr)) {
- IWineD3DSwapChain_Release((IUnknown *)swapchain);
- return swapchain;
- }
-
- return NULL;
-}
-
-static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
+static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface,
const WINED3DRECT *rect, const float color[4])
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
struct wined3d_context *context;
- if (rect) IWineD3DSurface_LoadLocation(surface, SFLAG_INDRAWABLE, NULL);
- IWineD3DSurface_ModifyLocation(surface, SFLAG_INDRAWABLE, TRUE);
+ if (rect) IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INDRAWABLE, NULL);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INDRAWABLE, TRUE);
- if (!surface_is_offscreen(surface))
- {
- TRACE("Surface %p is onscreen\n", surface);
-
- context = context_acquire(This, surface, CTXUSAGE_RESOURCELOAD);
- ENTER_GL();
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
- context_set_draw_buffer(context, surface_get_gl_buffer(surface));
- }
- else
- {
- TRACE("Surface %p is offscreen\n", surface);
+ context = context_acquire(This, surface);
+ context_apply_clear_state(context, This, surface, NULL);
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
- ENTER_GL();
- context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
- context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, surface);
- context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
- }
+ ENTER_GL();
- if (rect) {
- glEnable(GL_SCISSOR_TEST);
- if(surface_is_offscreen(surface)) {
+ if (rect)
+ {
+ if (surface_is_offscreen(surface))
glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1);
- } else {
- glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2,
+ else
+ glScissor(rect->x1, surface->currentDesc.Height - rect->y2,
rect->x2 - rect->x1, rect->y2 - rect->y1);
- }
checkGLcall("glScissor");
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SCISSORRECT);
- } else {
+ }
+ else
+ {
glDisable(GL_SCISSOR_TEST);
}
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
-
- glDisable(GL_BLEND);
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE));
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3));
glClearColor(color[0], color[1], color[2], color[3]);
glClear(GL_COLOR_BUFFER_BIT);
LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
}
-static inline DWORD argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) {
- unsigned int r, g, b, a;
- DWORD ret;
-
- if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
- || destfmt == WINED3DFMT_B8G8R8X8_UNORM
- || destfmt == WINED3DFMT_B8G8R8_UNORM)
- return color;
-
- TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
-
- a = (color & 0xff000000) >> 24;
- r = (color & 0x00ff0000) >> 16;
- g = (color & 0x0000ff00) >> 8;
- b = (color & 0x000000ff) >> 0;
-
- switch(destfmt)
- {
- case WINED3DFMT_B5G6R5_UNORM:
- if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
- r = (r * 32) / 256;
- g = (g * 64) / 256;
- b = (b * 32) / 256;
- ret = r << 11;
- ret |= g << 5;
- ret |= b;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- case WINED3DFMT_B5G5R5X1_UNORM:
- case WINED3DFMT_B5G5R5A1_UNORM:
- a = (a * 2) / 256;
- r = (r * 32) / 256;
- g = (g * 32) / 256;
- b = (b * 32) / 256;
- ret = a << 15;
- ret |= r << 10;
- ret |= g << 5;
- ret |= b << 0;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- case WINED3DFMT_A8_UNORM:
- TRACE("Returning %08x\n", a);
- return a;
-
- case WINED3DFMT_B4G4R4X4_UNORM:
- case WINED3DFMT_B4G4R4A4_UNORM:
- a = (a * 16) / 256;
- r = (r * 16) / 256;
- g = (g * 16) / 256;
- b = (b * 16) / 256;
- ret = a << 12;
- ret |= r << 8;
- ret |= g << 4;
- ret |= b << 0;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- case WINED3DFMT_B2G3R3_UNORM:
- r = (r * 8) / 256;
- g = (g * 8) / 256;
- b = (b * 4) / 256;
- ret = r << 5;
- ret |= g << 2;
- ret |= b << 0;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- case WINED3DFMT_R8G8B8X8_UNORM:
- case WINED3DFMT_R8G8B8A8_UNORM:
- ret = a << 24;
- ret |= b << 16;
- ret |= g << 8;
- ret |= r << 0;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- case WINED3DFMT_B10G10R10A2_UNORM:
- a = (a * 4) / 256;
- r = (r * 1024) / 256;
- g = (g * 1024) / 256;
- b = (b * 1024) / 256;
- ret = a << 30;
- ret |= r << 20;
- ret |= g << 10;
- ret |= b << 0;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- case WINED3DFMT_R10G10B10A2_UNORM:
- a = (a * 4) / 256;
- r = (r * 1024) / 256;
- g = (g * 1024) / 256;
- b = (b * 1024) / 256;
- ret = a << 30;
- ret |= b << 20;
- ret |= g << 10;
- ret |= r << 0;
- TRACE("Returning %08x\n", ret);
- return ret;
-
- default:
- FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
- return 0;
- }
-}
-
static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface,
IWineD3DSurface *pSurface, const WINED3DRECT *pRect, WINED3DCOLOR color)
{
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
const float c[4] = {D3DCOLOR_R(color), D3DCOLOR_G(color), D3DCOLOR_B(color), D3DCOLOR_A(color)};
- color_fill_fbo(iface, pSurface, pRect, c);
+ color_fill_fbo(iface, surface, pRect, c);
return WINED3D_OK;
} else {
/* Just forward this to the DirectDraw blitting engine */
memset(&BltFx, 0, sizeof(BltFx));
BltFx.dwSize = sizeof(BltFx);
- BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format);
+ BltFx.u5.dwFillColor = color_convert_argb_to_fmt(color, surface->resource.format_desc->format);
return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL,
WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
}
IWineD3DRendertargetView *rendertarget_view, const float color[4])
{
IWineD3DResource *resource;
- IWineD3DSurface *surface;
+ IWineD3DSurfaceImpl *surface;
HRESULT hr;
hr = IWineD3DRendertargetView_GetResource(rendertarget_view, &resource);
return;
}
- surface = (IWineD3DSurface *)resource;
+ surface = (IWineD3DSurfaceImpl *)resource;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
/* 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_POINT);
+ BltFx.u5.dwFillColor = color_convert_argb_to_fmt(c, surface->resource.format_desc->format);
+ hr = IWineD3DSurface_Blt((IWineD3DSurface *)surface, NULL, NULL, NULL,
+ WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
if (FAILED(hr))
{
ERR("Blt failed, hr %#x\n", hr);
return WINED3DERR_INVALIDCALL;
}
- *ppRenderTarget = This->render_targets[RenderTargetIndex];
+ *ppRenderTarget = (IWineD3DSurface *)This->render_targets[RenderTargetIndex];
TRACE("(%p) : RenderTarget %d Index returning %p\n", This, RenderTargetIndex, *ppRenderTarget);
/* Note inc ref on returned surface */
if(*ppRenderTarget != NULL)
}
static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *iface,
- IWineD3DSurface *Front, IWineD3DSurface *Back)
+ IWineD3DSurface *front, IWineD3DSurface *back)
{
- IWineD3DSurfaceImpl *FrontImpl = (IWineD3DSurfaceImpl *) Front;
- IWineD3DSurfaceImpl *BackImpl = (IWineD3DSurfaceImpl *) Back;
- IWineD3DSwapChainImpl *Swapchain;
+ IWineD3DSurfaceImpl *front_impl = (IWineD3DSurfaceImpl *)front;
+ IWineD3DSurfaceImpl *back_impl = (IWineD3DSurfaceImpl *)back;
+ IWineD3DSwapChainImpl *swapchain;
HRESULT hr;
- TRACE("iface %p, front %p, back %p.\n", iface, Front, Back);
+ TRACE("iface %p, front %p, back %p.\n", iface, front, back);
- hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &Swapchain);
- if(hr != WINED3D_OK) {
- ERR("Can't get the swapchain\n");
+ if (FAILED(hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **)&swapchain)))
+ {
+ ERR("Failed to get the swapchain, hr %#x.\n", hr);
return hr;
}
- /* Make sure to release the swapchain */
- IWineD3DSwapChain_Release((IWineD3DSwapChain *) Swapchain);
-
- if(FrontImpl && !(FrontImpl->resource.usage & WINED3DUSAGE_RENDERTARGET) ) {
- ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n");
- return WINED3DERR_INVALIDCALL;
- }
- else if(BackImpl && !(BackImpl->resource.usage & WINED3DUSAGE_RENDERTARGET)) {
- ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n");
+ if (front_impl && !(front_impl->resource.usage & WINED3DUSAGE_RENDERTARGET))
+ {
+ ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n");
+ IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
return WINED3DERR_INVALIDCALL;
}
- if(Swapchain->frontBuffer != Front) {
- TRACE("Changing the front buffer from %p to %p\n", Swapchain->frontBuffer, Front);
-
- if(Swapchain->frontBuffer)
+ if (back_impl)
+ {
+ if (!(back_impl->resource.usage & WINED3DUSAGE_RENDERTARGET))
{
- IWineD3DSurface_SetContainer(Swapchain->frontBuffer, NULL);
- ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN;
+ ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n");
+ IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+ return WINED3DERR_INVALIDCALL;
}
- Swapchain->frontBuffer = Front;
- if(Swapchain->frontBuffer) {
- IWineD3DSurface_SetContainer(Swapchain->frontBuffer, (IWineD3DBase *) Swapchain);
- ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
+ if (!swapchain->back_buffers)
+ {
+ swapchain->back_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*swapchain->back_buffers));
+ if (!swapchain->back_buffers)
+ {
+ ERR("Failed to allocate back buffer array memory.\n");
+ IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+ return E_OUTOFMEMORY;
+ }
}
}
- if(Back && !Swapchain->backBuffer) {
- /* We need memory for the back buffer array - only one back buffer this way */
- Swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *));
- if(!Swapchain->backBuffer) {
- ERR("Out of memory\n");
- return E_OUTOFMEMORY;
+ if (swapchain->front_buffer != front_impl)
+ {
+ TRACE("Changing the front buffer from %p to %p.\n", swapchain->front_buffer, front_impl);
+
+ if (swapchain->front_buffer)
+ {
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, NULL);
+ swapchain->front_buffer->Flags &= ~SFLAG_SWAPCHAIN;
}
- }
+ swapchain->front_buffer = front_impl;
- if(Swapchain->backBuffer[0] != Back) {
- TRACE("Changing the back buffer from %p to %p\n", Swapchain->backBuffer, Back);
+ if (front)
+ {
+ IWineD3DSurface_SetContainer(front, (IWineD3DBase *)swapchain);
+ front_impl->Flags |= SFLAG_SWAPCHAIN;
+ }
+ }
- /* 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");
+ if (swapchain->back_buffers[0] != back_impl)
+ {
+ TRACE("Changing the back buffer from %p to %p.\n", swapchain->back_buffers[0], back_impl);
- ENTER_GL();
- if(!Swapchain->backBuffer[0]) {
- /* GL was told to draw to the front buffer at creation,
- * undo that
- */
- glDrawBuffer(GL_BACK);
- checkGLcall("glDrawBuffer(GL_BACK)");
- /* Set the backbuffer count to 1 because other code uses it to fing the back buffers */
- Swapchain->presentParms.BackBufferCount = 1;
- } else if (!Back) {
- /* That makes problems - disable for now */
- /* glDrawBuffer(GL_FRONT); */
- checkGLcall("glDrawBuffer(GL_FRONT)");
- /* We have lost our back buffer, set this to 0 to avoid confusing other code */
- Swapchain->presentParms.BackBufferCount = 0;
+ if (swapchain->back_buffers[0])
+ {
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[0], NULL);
+ swapchain->back_buffers[0]->Flags &= ~SFLAG_SWAPCHAIN;
}
- LEAVE_GL();
+ swapchain->back_buffers[0] = back_impl;
- if(Swapchain->backBuffer[0])
+ if (back)
{
- IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], NULL);
- ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN;
+ swapchain->presentParms.BackBufferWidth = back_impl->currentDesc.Width;
+ swapchain->presentParms.BackBufferHeight = back_impl->currentDesc.Height;
+ swapchain->presentParms.BackBufferFormat = back_impl->resource.format_desc->format;
+ swapchain->presentParms.BackBufferCount = 1;
+
+ IWineD3DSurface_SetContainer(back, (IWineD3DBase *)swapchain);
+ back_impl->Flags |= SFLAG_SWAPCHAIN;
}
- Swapchain->backBuffer[0] = Back;
-
- if(Swapchain->backBuffer[0]) {
- IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain);
- ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags |= SFLAG_SWAPCHAIN;
- Swapchain->presentParms.BackBufferWidth = BackImpl->currentDesc.Width;
- Swapchain->presentParms.BackBufferHeight = BackImpl->currentDesc.Height;
- Swapchain->presentParms.BackBufferFormat = BackImpl->resource.format_desc->format;
- } else {
- HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer);
- Swapchain->backBuffer = NULL;
+ else
+ {
+ swapchain->presentParms.BackBufferCount = 0;
+ HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+ swapchain->back_buffers = NULL;
}
-
}
+ IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice* iface, IWineD3DSurface **ppZStencilSurface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- *ppZStencilSurface = This->stencilBufferTarget;
+ *ppZStencilSurface = (IWineD3DSurface *)This->depth_stencil;
TRACE("(%p) : zStencilSurface returning %p\n", This, *ppZStencilSurface);
if(*ppZStencilSurface != NULL) {
}
}
-void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
- IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip)
+void stretch_rect_fbo(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect_in,
+ IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter)
{
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
- IWineD3DSwapChain *src_swapchain, *dst_swapchain;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
GLenum gl_filter;
- POINT offset = {0, 0};
+ RECT src_rect, dst_rect;
- TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n",
- This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter, flip);
- TRACE("src_rect [%u, %u]->[%u, %u]\n", src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2);
- TRACE("dst_rect [%u, %u]->[%u, %u]\n", dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2);
+ TRACE("device %p, src_surface %p, src_rect_in %s, dst_surface %p, dst_rect_in %s, filter %s (0x%08x).\n",
+ device, src_surface, wine_dbgstr_rect(src_rect_in), dst_surface,
+ wine_dbgstr_rect(dst_rect_in), debug_d3dtexturefiltertype(filter), filter);
+
+ src_rect = *src_rect_in;
+ dst_rect = *dst_rect_in;
switch (filter) {
case WINED3DTEXF_LINEAR:
/* Make sure the drawables are up-to-date. Note that loading the
* destination surface isn't strictly required if we overwrite the
* entire surface. */
- IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
- IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)src_surface, SFLAG_INDRAWABLE, NULL);
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, NULL);
- /* Attach src surface to src fbo */
- src_swapchain = get_swapchain(src_surface);
- dst_swapchain = get_swapchain(dst_surface);
+ if (!surface_is_offscreen(src_surface)) context = context_acquire(device, src_surface);
+ else if (!surface_is_offscreen(dst_surface)) context = context_acquire(device, dst_surface);
+ else context = context_acquire(device, NULL);
- if (src_swapchain) context = context_acquire(This, src_surface, CTXUSAGE_RESOURCELOAD);
- else if (dst_swapchain) context = context_acquire(This, dst_surface, CTXUSAGE_RESOURCELOAD);
- else context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping blit.\n");
+ return;
+ }
gl_info = context->gl_info;
TRACE("Source surface %p is onscreen\n", src_surface);
- if(buffer == GL_FRONT) {
- RECT windowsize;
- UINT h;
- ClientToScreen(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &offset);
- GetClientRect(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &windowsize);
- h = windowsize.bottom - windowsize.top;
- src_rect->x1 -= offset.x; src_rect->x2 -=offset.x;
- src_rect->y1 = offset.y + h - src_rect->y1;
- src_rect->y2 = offset.y + h - src_rect->y2;
- } else {
- src_rect->y1 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y1;
- src_rect->y2 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y2;
- }
+ if (buffer == GL_FRONT)
+ surface_translate_frontbuffer_coords(src_surface, context->win_handle, &src_rect);
+
+ src_rect.top = src_surface->currentDesc.Height - src_rect.top;
+ src_rect.bottom = src_surface->currentDesc.Height - src_rect.bottom;
ENTER_GL();
context_bind_fbo(context, GL_READ_FRAMEBUFFER, NULL);
} else {
TRACE("Source surface %p is offscreen\n", src_surface);
ENTER_GL();
- context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo);
- context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, src_surface);
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL);
glReadBuffer(GL_COLOR_ATTACHMENT0);
checkGLcall("glReadBuffer()");
- context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE);
}
LEAVE_GL();
TRACE("Destination surface %p is onscreen\n", dst_surface);
- if(buffer == GL_FRONT) {
- RECT windowsize;
- UINT h;
- ClientToScreen(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &offset);
- GetClientRect(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &windowsize);
- h = windowsize.bottom - windowsize.top;
- dst_rect->x1 -= offset.x; dst_rect->x2 -=offset.x;
- dst_rect->y1 = offset.y + h - dst_rect->y1;
- dst_rect->y2 = offset.y + h - dst_rect->y2;
- } else {
- /* Screen coords = window coords, surface height = window height */
- dst_rect->y1 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y1;
- dst_rect->y2 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y2;
- }
+ if (buffer == GL_FRONT)
+ surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect);
+
+ dst_rect.top = dst_surface->currentDesc.Height - dst_rect.top;
+ dst_rect.bottom = dst_surface->currentDesc.Height - dst_rect.bottom;
ENTER_GL();
context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL);
TRACE("Destination surface %p is offscreen\n", dst_surface);
ENTER_GL();
- context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, &context->dst_fbo);
- context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, dst_surface);
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL);
context_set_draw_buffer(context, GL_COLOR_ATTACHMENT0);
- context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE);
}
glDisable(GL_SCISSOR_TEST);
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
+ IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
- if (flip) {
- gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
- dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter);
- checkGLcall("glBlitFramebuffer()");
- } else {
- gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
- dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter);
- checkGLcall("glBlitFramebuffer()");
- }
+ gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
+ dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter);
+ checkGLcall("glBlitFramebuffer()");
LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
- IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE);
}
static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget,
}
/* If we are trying to set what we already have, don't bother */
- if (pRenderTarget == This->render_targets[RenderTargetIndex]) {
+ if (pRenderTarget == (IWineD3DSurface *)This->render_targets[RenderTargetIndex])
+ {
TRACE("Trying to do a NOP SetRenderTarget operation\n");
return WINED3D_OK;
}
- if(pRenderTarget) IWineD3DSurface_AddRef(pRenderTarget);
- if(This->render_targets[RenderTargetIndex]) IWineD3DSurface_Release(This->render_targets[RenderTargetIndex]);
- This->render_targets[RenderTargetIndex] = pRenderTarget;
+ if (pRenderTarget)
+ IWineD3DSurface_AddRef(pRenderTarget);
+ if (This->render_targets[RenderTargetIndex])
+ IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[RenderTargetIndex]);
+ This->render_targets[RenderTargetIndex] = (IWineD3DSurfaceImpl *)pRenderTarget;
/* Render target 0 is special */
if(RenderTargetIndex == 0 && set_viewport) {
* Tests show that stateblock recording is ignored, the change goes
* directly into the primary stateblock.
*/
- This->stateBlock->viewport.Height = ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height;
- This->stateBlock->viewport.Width = ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Width;
+ This->stateBlock->viewport.Height = This->render_targets[0]->currentDesc.Height;
+ This->stateBlock->viewport.Width = This->render_targets[0]->currentDesc.Width;
This->stateBlock->viewport.X = 0;
This->stateBlock->viewport.Y = 0;
This->stateBlock->viewport.MaxZ = 1.0f;
static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *iface, IWineD3DSurface *pNewZStencil) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- HRESULT hr = WINED3D_OK;
- IWineD3DSurface *tmp;
+ IWineD3DSurfaceImpl *tmp;
- TRACE("(%p) Swapping z-buffer. Old = %p, new = %p\n",This, This->stencilBufferTarget, pNewZStencil);
+ TRACE("device %p, depth_stencil %p, old depth_stencil %p.\n", This, pNewZStencil, This->depth_stencil);
- if (pNewZStencil == This->stencilBufferTarget) {
- TRACE("Trying to do a NOP SetRenderTarget operation\n");
- } else {
- /** OpenGL doesn't support 'sharing' of the stencilBuffer so we may incur an extra memory overhead
- * depending on the renter target implementation being used.
- * A shared context implementation will share all buffers between all rendertargets (including swapchains),
- * implementations that use separate pbuffers for different swapchains or rendertargets will have to duplicate the
- * stencil buffer and incur an extra memory overhead
- ******************************************************/
-
- if (This->stencilBufferTarget) {
- if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
- || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) {
- surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED);
- } else {
- struct wined3d_context *context = context_acquire(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);
- context_release(context);
+ if (This->depth_stencil == (IWineD3DSurfaceImpl *)pNewZStencil)
+ {
+ TRACE("Trying to do a NOP SetRenderTarget operation.\n");
+ return WINED3D_OK;
+ }
+
+ if (This->depth_stencil)
+ {
+ if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
+ || This->depth_stencil->Flags & SFLAG_DISCARD)
+ {
+ surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED,
+ This->depth_stencil->currentDesc.Width,
+ This->depth_stencil->currentDesc.Height);
+ if (This->depth_stencil == This->onscreen_depth_stencil)
+ {
+ IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil);
+ This->onscreen_depth_stencil = NULL;
}
}
+ }
- tmp = This->stencilBufferTarget;
- This->stencilBufferTarget = pNewZStencil;
- /* should we be calling the parent or the wined3d surface? */
- if (NULL != This->stencilBufferTarget) IWineD3DSurface_AddRef(This->stencilBufferTarget);
- if (NULL != tmp) IWineD3DSurface_Release(tmp);
- hr = WINED3D_OK;
+ tmp = This->depth_stencil;
+ This->depth_stencil = (IWineD3DSurfaceImpl *)pNewZStencil;
+ if (This->depth_stencil) IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil);
+ if (tmp) IWineD3DSurface_Release((IWineD3DSurface *)tmp);
- if((!tmp && pNewZStencil) || (!pNewZStencil && tmp)) {
- /* Swapping NULL / non NULL depth stencil affects the depth and tests */
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE));
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE));
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK));
- }
+ if ((!tmp && pNewZStencil) || (!pNewZStencil && tmp))
+ {
+ /* Swapping NULL / non NULL depth stencil affects the depth and tests */
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK));
}
- return hr;
+ return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* iface, UINT XHotSpot,
TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot);
/* some basic validation checks */
- if(This->cursorTexture) {
- struct wined3d_context *context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ if (This->cursorTexture)
+ {
+ struct wined3d_context *context = context_acquire(This, NULL);
ENTER_GL();
glDeleteTextures(1, &This->cursorTexture);
LEAVE_GL();
if (SUCCEEDED(IWineD3DSurface_LockRect(pCursorBitmap, &rect, NULL, WINED3DLOCK_READONLY)))
{
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
- const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
struct wined3d_context *context;
char *mem, *bits = rect.pBits;
- GLint intfmt = glDesc->glInternal;
- GLint format = glDesc->glFormat;
- GLint type = glDesc->glType;
+ GLint intfmt = format_desc->glInternal;
+ GLint format = format_desc->glFormat;
+ GLint type = format_desc->glType;
INT height = This->cursorHeight;
INT width = This->cursorWidth;
- INT bpp = glDesc->byte_count;
+ INT bpp = format_desc->byte_count;
DWORD sampler;
INT i;
memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp);
IWineD3DSurface_UnlockRect(pCursorBitmap);
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, NULL);
ENTER_GL();
while (surface->pow2Width < pPresentationParameters->BackBufferWidth) surface->pow2Width <<= 1;
while (surface->pow2Height < pPresentationParameters->BackBufferHeight) surface->pow2Height <<= 1;
}
- surface->glRect.left = 0;
- surface->glRect.top = 0;
- surface->glRect.right = surface->pow2Width;
- surface->glRect.bottom = surface->pow2Height;
if (surface->texture_name)
{
- struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ struct wined3d_context *context = context_acquire(device, NULL);
ENTER_GL();
glDeleteTextures(1, &surface->texture_name);
LEAVE_GL();
/* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered
* to a FBO */
- if(!surface_init_sysmem((IWineD3DSurface *) surface))
+ if (!surface_init_sysmem(surface))
{
return E_OUTOFMEMORY;
}
return FALSE;
}
-void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
+static void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
- IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
IWineD3DBaseShaderImpl *shader;
- context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This, NULL);
gl_info = context->gl_info;
IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
swapchain->num_contexts = 0;
}
-HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
+static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
- IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
struct wined3d_context *context;
HRESULT hr;
IWineD3DSurfaceImpl *target;
return E_OUTOFMEMORY;
}
- target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer);
- context = context_create(This, target, swapchain->win_handle, FALSE, &swapchain->presentParms);
- if (!context)
+ target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer;
+ if (!(context = context_create(swapchain, target, swapchain->ds_format)))
{
WARN("Failed to create context.\n");
HeapFree(GetProcessHeap(), 0, swapchain->context);
return WINED3D_OK;
err:
- context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
+ context_acquire(This, NULL);
destroy_dummy_textures(This, context->gl_info);
context_release(context);
context_destroy(This, context);
pPresentationParameters->hDeviceWindow != swapchain->presentParms.hDeviceWindow) {
ERR("Cannot change the device window yet\n");
}
- if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) {
+ if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil)
+ {
HRESULT hrc;
TRACE("Creating the depth stencil buffer\n");
pPresentationParameters->MultiSampleType,
pPresentationParameters->MultiSampleQuality,
FALSE,
- &This->auto_depth_stencil_buffer);
+ (IWineD3DSurface **)&This->auto_depth_stencil);
if (FAILED(hrc)) {
ERR("Failed to create the depth stencil buffer\n");
}
}
+ if (This->onscreen_depth_stencil)
+ {
+ IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil);
+ This->onscreen_depth_stencil = NULL;
+ }
+
/* Reset the depth stencil */
if (pPresentationParameters->EnableAutoDepthStencil)
- IWineD3DDevice_SetDepthStencilSurface(iface, This->auto_depth_stencil_buffer);
+ IWineD3DDevice_SetDepthStencilSurface(iface, (IWineD3DSurface *)This->auto_depth_stencil);
else
IWineD3DDevice_SetDepthStencilSurface(iface, NULL);
IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock);
IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
- delete_opengl_contexts(iface, (IWineD3DSwapChain *) swapchain);
+ delete_opengl_contexts(iface, swapchain);
if(pPresentationParameters->Windowed) {
mode.Width = swapchain->orig_width;
swapchain->presentParms.BackBufferWidth = pPresentationParameters->BackBufferWidth;
swapchain->presentParms.BackBufferHeight = pPresentationParameters->BackBufferHeight;
- hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters);
+ hr = updateSurfaceDesc(swapchain->front_buffer, pPresentationParameters);
if(FAILED(hr))
{
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
return hr;
}
- for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
- hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters);
+ for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
+ {
+ hr = updateSurfaceDesc(swapchain->back_buffers[i], pPresentationParameters);
if(FAILED(hr))
{
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
return hr;
}
}
- if(This->auto_depth_stencil_buffer) {
- hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters);
+ if (This->auto_depth_stencil)
+ {
+ hr = updateSurfaceDesc(This->auto_depth_stencil, pPresentationParameters);
if(FAILED(hr))
{
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
}
}
- if((pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) ||
- (swapchain->presentParms.Windowed && !pPresentationParameters->Windowed) ||
- DisplayModeChanged) {
-
+ if (!pPresentationParameters->Windowed != !swapchain->presentParms.Windowed
+ || DisplayModeChanged)
+ {
IWineD3DDevice_SetDisplayMode(iface, 0, &mode);
- if(swapchain->win_handle && !pPresentationParameters->Windowed) {
+ if (!pPresentationParameters->Windowed)
+ {
if(swapchain->presentParms.Windowed) {
/* switch from windowed to fs */
swapchain_setup_fullscreen_window(swapchain, pPresentationParameters->BackBufferWidth,
pPresentationParameters->BackBufferHeight);
} else {
/* Fullscreen -> fullscreen mode change */
- MoveWindow(swapchain->win_handle, 0, 0,
+ MoveWindow(swapchain->device_window, 0, 0,
pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight,
TRUE);
}
- } else if(swapchain->win_handle && !swapchain->presentParms.Windowed) {
+ }
+ else if (!swapchain->presentParms.Windowed)
+ {
/* Fullscreen -> windowed switch */
swapchain_restore_fullscreen_window(swapchain);
}
}
}
- hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *) swapchain);
+ hr = create_primary_opengl_context(iface, swapchain);
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
/* All done. There is no need to reload resources or shaders, this will happen automatically on the
{
for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i)
{
- if (This->render_targets[i] == (IWineD3DSurface *)resource) {
+ if (This->render_targets[i] == (IWineD3DSurfaceImpl *)resource)
This->render_targets[i] = NULL;
- }
- }
- if (This->stencilBufferTarget == (IWineD3DSurface *)resource) {
- This->stencilBufferTarget = NULL;
}
+ if (This->depth_stencil == (IWineD3DSurfaceImpl *)resource)
+ This->depth_stencil = NULL;
}
break;
return WINED3D_OK;
}
+static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC(IWineD3DDevice *iface, HDC dc, IWineD3DSurface **surface)
+{
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+ IWineD3DResourceImpl *resource;
+
+ LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
+ {
+ WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
+ if (type == WINED3DRTYPE_SURFACE)
+ {
+ if (((IWineD3DSurfaceImpl *)resource)->hDC == dc)
+ {
+ TRACE("Found surface %p for dc %p.\n", resource, dc);
+ *surface = (IWineD3DSurface *)resource;
+ return WINED3D_OK;
+ }
+ }
+ }
+
+ return WINED3DERR_INVALIDCALL;
+}
+
/**********************************************************
* IWineD3DDevice VTbl follows
**********************************************************/
IWineD3DDeviceImpl_UpdateSurface,
IWineD3DDeviceImpl_GetFrontBufferData,
/*** object tracking ***/
- IWineD3DDeviceImpl_EnumResources
+ IWineD3DDeviceImpl_EnumResources,
+ IWineD3DDeviceImpl_GetSurfaceFromDC,
+ IWineD3DDeviceImpl_AcquireFocusWindow,
+ IWineD3DDeviceImpl_ReleaseFocusWindow,
};
HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
select_shader_mode(&adapter->gl_info, &device->ps_selected_mode, &device->vs_selected_mode);
device->shader_backend = adapter->shader_backend;
- memset(&shader_caps, 0, sizeof(shader_caps));
- device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
- device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
- device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
- device->vs_clipping = shader_caps.VSClipping;
-
- memset(&ffp_caps, 0, sizeof(ffp_caps));
+ if (device->shader_backend)
+ {
+ device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
+ device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
+ device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
+ device->vs_clipping = shader_caps.VSClipping;
+ }
fragment_pipeline = adapter->fragment_pipe;
device->frag_pipe = fragment_pipeline;
- fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
- device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
-
- hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info,
- ffp_vertexstate_template, fragment_pipeline, misc_state_template);
- if (FAILED(hr))
+ if (fragment_pipeline)
{
- ERR("Failed to compile state table, hr %#x.\n", hr);
- IWineD3D_Release(device->wined3d);
- return hr;
- }
+ fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
+ device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
+ hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info,
+ ffp_vertexstate_template, fragment_pipeline, misc_state_template);
+ if (FAILED(hr))
+ {
+ ERR("Failed to compile state table, hr %#x.\n", hr);
+ IWineD3D_Release(device->wined3d);
+ return hr;
+ }
+ }
device->blitter = adapter->blitter;
return WINED3D_OK;
}
}
-void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height)
-{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.device;
- /* The drawable size of a pbuffer render target is the current pbuffer size. */
- *width = device->pbufferWidth;
- *height = device->pbufferHeight;
-}
-
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;
+ *width = context->current_rt->pow2Width;
+ *height = context->current_rt->pow2Height;
}
void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height)
{
- IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface;
+ IWineD3DSwapChainImpl *swapchain = context->swapchain;
/* 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 = surface->currentDesc.Width;
- *height = surface->currentDesc.Height;
+ * the active context belongs to. */
+ *width = swapchain->presentParms.BackBufferWidth;
+ *height = swapchain->presentParms.BackBufferHeight;
}
LRESULT device_process_message(IWineD3DDeviceImpl *device, HWND window,
*/
#include "config.h"
+#include <stdio.h>
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
-#define GLINFO_LOCATION (*gl_info)
#define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
-#define MAKEDWORD_VERSION(maj, min) ((maj & 0xffff) << 16) | (min & 0xffff)
/* The d3d device ID */
static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
{"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
{"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 },
{"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100, 0 },
+ {"GL_ARB_shadow", ARB_SHADOW, 0 },
{"GL_ARB_sync", ARB_SYNC, 0 },
{"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 },
{"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 },
{"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 },
{"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 },
{"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 },
+ {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2, 0 },
{"GL_EXT_fog_coord", EXT_FOG_COORD, 0 },
{"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 },
{"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 },
}
/* Adjust the amount of used texture memory */
-long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram)
+unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *device, unsigned int glram)
{
- struct wined3d_adapter *adapter = D3DDevice->adapter;
+ struct wined3d_adapter *adapter = device->adapter;
adapter->UsedTextureRam += glram;
- TRACE("Adjusted gl ram by %ld to %d\n", glram, adapter->UsedTextureRam);
+ TRACE("Adjusted gl ram by %d to %d\n", glram, adapter->UsedTextureRam);
return adapter->UsedTextureRam;
}
checkGLcall("Loading the PBO test texture");
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ LEAVE_GL();
+
wglFinish(); /* just to be sure */
memset(check, 0, sizeof(check));
+ ENTER_GL();
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
checkGLcall("Reading back the PBO test texture");
static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
{
- return (gl_vendor == GL_VENDOR_ATI);
+ return gl_vendor == GL_VENDOR_FGLRX;
}
return ret;
}
+/* Context activation is done by the caller. */
+static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ char data[4 * 4 * 4];
+ GLuint tex, fbo;
+ GLenum status;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
+
+ memset(data, 0xcc, sizeof(data));
+
+ ENTER_GL();
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ checkGLcall("glTexImage2D");
+
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ checkGLcall("glFramebufferTexture2D");
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
+ checkGLcall("glCheckFramebufferStatus");
+
+ memset(data, 0x11, sizeof(data));
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ checkGLcall("glTexSubImage2D");
+
+ glClearColor(0.996, 0.729, 0.745, 0.792);
+ glClear(GL_COLOR_BUFFER_BIT);
+ checkGLcall("glClear");
+
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ checkGLcall("glGetTexImage");
+
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ checkGLcall("glBindTexture");
+
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ glDeleteTextures(1, &tex);
+ checkGLcall("glDeleteTextures");
+
+ LEAVE_GL();
+
+ return *(DWORD *)data == 0x11111111;
+}
+
static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
{
TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants);
gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
}
+static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
+}
+
struct driver_quirk
{
BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
quirk_disable_nvvp_clip,
"Apple NV_vertex_program clip bug quirk"
},
+ {
+ match_fbo_tex_update,
+ quirk_fbo_tex_update,
+ "FBO rebind for attachment updates"
+ },
};
/* Certain applications (Steam) complain if we report an outdated driver version. In general,
{HW_VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 14, 10, 6764 },
{HW_VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 14, 10, 6764 },
{HW_VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 14, 10, 6764 },
- {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2300, "ATI Mobility Radeon HD 2300", 14, 10, 6764 },
+ {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2350, "ATI Mobility Radeon HD 2350", 14, 10, 6764 },
{HW_VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 14, 10, 6764 },
{HW_VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 14, 10, 6764 },
{HW_VENDOR_ATI, CARD_ATI_RADEON_HD4350, "ATI Radeon HD 4350", 14, 10, 6764 },
return GL_VENDOR_NVIDIA;
if (strstr(gl_vendor_string, "ATI"))
- return GL_VENDOR_ATI;
+ return GL_VENDOR_FGLRX;
if (strstr(gl_vendor_string, "Intel(R)")
- || strstr(gl_renderer, "Intel(R)")
+ /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
+ || strstr(gl_renderer, "Intel")
|| strstr(gl_vendor_string, "Intel Inc."))
return GL_VENDOR_INTEL;
|| strstr(gl_renderer, "Gallium"))
return GL_VENDOR_MESA;
- FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_WINE.\n", debugstr_a(gl_vendor_string));
+ FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
+ debugstr_a(gl_vendor_string));
- return GL_VENDOR_WINE;
+ return GL_VENDOR_UNKNOWN;
}
static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
return HW_VENDOR_ATI;
if (strstr(gl_vendor_string, "Intel(R)")
- || strstr(gl_renderer, "Intel(R)")
+ /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
+ || strstr(gl_renderer, "Intel")
|| strstr(gl_vendor_string, "Intel Inc."))
return HW_VENDOR_INTEL;
if (strstr(gl_vendor_string, "Mesa")
|| strstr(gl_vendor_string, "Tungsten Graphics, Inc")
|| strstr(gl_vendor_string, "VMware, Inc."))
- return HW_VENDOR_WINE;
+ return HW_VENDOR_SOFTWARE;
FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
-enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
- unsigned int *vidmem )
+static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer, unsigned int *vidmem)
{
- /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
- * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
- */
- if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
+ if (WINE_D3D10_CAPABLE(gl_info))
{
/* Geforce 200 - highend */
if (strstr(gl_renderer, "GTX 280")
return CARD_NVIDIA_GEFORCE_8300GS;
}
+ /* Geforce8-compatible fall back if the GPU is not in the list yet */
+ *vidmem = 128;
+ return CARD_NVIDIA_GEFORCE_8300GS;
+ }
+
+ /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
+ * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
+ */
+ if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
+ {
/* Geforce7 - highend */
if (strstr(gl_renderer, "7800")
|| strstr(gl_renderer, "7900")
}
-enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
- unsigned int *vidmem )
+static enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer, unsigned int *vidmem)
{
/* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
*
* Beware: renderer string do not match exact card model,
* eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
- if (WINE_D3D9_CAPABLE(gl_info))
+ if (WINE_D3D10_CAPABLE(gl_info))
{
/* Radeon EG CYPRESS XT / PRO HD5800 - highend */
if (strstr(gl_renderer, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */
return CARD_ATI_RADEON_HD2600;
}
- /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
- if (strstr(gl_renderer, "HD 2300")
+ /* Radeon R6xx HD2350/HD2400/HD3400 - lowend
+ * Note HD2300=DX9, HD2350=DX10 */
+ if (strstr(gl_renderer, "HD 2350")
|| strstr(gl_renderer, "HD 2400")
|| strstr(gl_renderer, "HD 3470")
|| strstr(gl_renderer, "HD 3450")
|| strstr(gl_renderer, "HD 3430")
|| strstr(gl_renderer, "HD 3400"))
{
- *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
- return CARD_ATI_RADEON_HD2300;
+ *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
+ return CARD_ATI_RADEON_HD2350;
}
/* Radeon R6xx/R7xx integrated */
return CARD_ATI_RADEON_HD3200;
}
+ /* Default for when no GPU has been found */
+ *vidmem = 128; /* 128MB */
+ return CARD_ATI_RADEON_HD3200;
+ }
+
+ if (WINE_D3D8_CAPABLE(gl_info))
+ {
/* Radeon R5xx */
if (strstr(gl_renderer, "X1600")
|| strstr(gl_renderer, "X1650")
return CARD_ATI_RADEON_X1600;
}
- /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
+ /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
+ * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
if (strstr(gl_renderer, "X700")
|| strstr(gl_renderer, "X800")
|| strstr(gl_renderer, "X850")
|| strstr(gl_renderer, "X1300")
|| strstr(gl_renderer, "X1400")
|| strstr(gl_renderer, "X1450")
- || strstr(gl_renderer, "X1550"))
+ || strstr(gl_renderer, "X1550")
+ || strstr(gl_renderer, "X2300")
+ || strstr(gl_renderer, "X2500")
+ || strstr(gl_renderer, "HD 2300")
+ )
{
*vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
return CARD_ATI_RADEON_X700;
}
-enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
- unsigned int *vidmem )
+static enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer, unsigned int *vidmem)
{
if (strstr(gl_renderer, "X3100"))
{
}
-enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
- unsigned int *vidmem )
+static enum wined3d_pci_device select_card_ati_mesa(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer, unsigned int *vidmem)
{
/* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
*
return CARD_ATI_RADEON_HD2600;
}
- /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
+ /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */
if (strstr(gl_renderer, "RV610")
|| strstr(gl_renderer, "RV620"))
{
- *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
- return CARD_ATI_RADEON_HD2300;
+ *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
+ return CARD_ATI_RADEON_HD2350;
}
/* Radeon R6xx/R7xx integrated */
if (strstr(gl_renderer, "(RV610")
|| strstr(gl_renderer, "(RV620"))
{
- *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
- return CARD_ATI_RADEON_HD2300;
+ *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
+ return CARD_ATI_RADEON_HD2350;
}
/* Radeon R6xx/R7xx integrated */
}
-enum wined3d_pci_device (select_card_nvidia_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
- unsigned int *vidmem )
+static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer, unsigned int *vidmem)
{
FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n");
if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
return CARD_NVIDIA_RIVA_128;
}
-enum wined3d_pci_device (select_card_intel_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
- unsigned int *vidmem )
+static enum wined3d_pci_device select_card_intel_mesa(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer, unsigned int *vidmem)
{
FIXME_(d3d_caps)("Card selection not handled for Mesa Intel driver\n");
return CARD_INTEL_I915G;
{GL_VENDOR_APPLE, HW_VENDOR_NVIDIA, "Apple OSX NVidia binary driver", select_card_nvidia_binary},
{GL_VENDOR_APPLE, HW_VENDOR_ATI, "Apple OSX AMD/ATI binary driver", select_card_ati_binary},
{GL_VENDOR_APPLE, HW_VENDOR_INTEL, "Apple OSX Intel binary driver", select_card_intel_binary},
- {GL_VENDOR_ATI, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary},
+ {GL_VENDOR_FGLRX, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary},
{GL_VENDOR_MESA, HW_VENDOR_ATI, "Mesa AMD/ATI driver", select_card_ati_mesa},
{GL_VENDOR_MESA, HW_VENDOR_NVIDIA, "Mesa Nouveau driver", select_card_nvidia_mesa},
- {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa}
+ {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa},
+ {GL_VENDOR_INTEL, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa}
};
* with Default values
*/
memset(gl_info->supported, 0, sizeof(gl_info->supported));
+ gl_info->limits.blends = 1;
gl_info->limits.buffers = 1;
gl_info->limits.textures = 1;
gl_info->limits.fragment_samplers = 1;
if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
{
const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
+ unsigned int major, minor;
+
TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str));
+
+ /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
+ sscanf(str, "%u.%u", &major, &minor);
+ gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
}
if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
{
ThisExtn[len] = '\0';
TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
- if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
- gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
- TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
- }
if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
/* TODO: Store modes per adapter and read it from the adapter structure */
if (Adapter == 0) { /* Display */
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
UINT format_bits = format_desc->byte_count * CHAR_BIT;
unsigned int i = 0;
unsigned int j = 0;
/* TODO: Store modes per adapter and read it from the adapter structure */
if (Adapter == 0)
{
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info);
UINT format_bits = format_desc->byte_count * CHAR_BIT;
DEVMODEW DevModeW;
int ModeIdx = 0;
}
static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
- const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
+ const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
{
short redSize, greenSize, blueSize, alphaSize, colorBits;
if(!cfg)
return FALSE;
+ /* Float formats need FBOs. If FBOs are used this function isn't called */
+ if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
+
if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
{
return FALSE;
return TRUE;
- } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
- if (format_desc->format == WINED3DFMT_R16_FLOAT)
- return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if (format_desc->format == WINED3DFMT_R16G16_FLOAT)
- return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if (format_desc->format == WINED3DFMT_R16G16B16A16_FLOAT)
- return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
- if (format_desc->format == WINED3DFMT_R32_FLOAT)
- return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if (format_desc->format == WINED3DFMT_R32G32_FLOAT)
- return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if (format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT)
- return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
- } else {
- /* Probably a color index mode */
- return FALSE;
}
+ /* Probably a RGBA_float or color index mode */
return FALSE;
}
static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
- const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
+ const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc)
{
short depthSize, stencilSize;
BOOL lockable = FALSE;
return FALSE;
}
+ /* Float formats need FBOs. If FBOs are used this function isn't called */
+ if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
+
if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT))
lockable = TRUE;
int nCfgs;
const WineD3D_PixelFormat *cfgs;
const struct wined3d_adapter *adapter;
- const struct GlPixelFormatDesc *rt_format_desc;
- const struct GlPixelFormatDesc *ds_format_desc;
+ const struct wined3d_format_desc *rt_format_desc;
+ const struct wined3d_format_desc *ds_format_desc;
int it;
WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
adapter = &This->adapters[Adapter];
rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info);
ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info);
- cfgs = adapter->cfgs;
- nCfgs = adapter->nCfgs;
- for (it = 0; it < nCfgs; ++it) {
- if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
- {
- if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ if ((rt_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET) &&
+ (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) {
+ TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
+ return WINED3D_OK;
+ }
+ }
+ else
+ {
+ cfgs = adapter->cfgs;
+ nCfgs = adapter->nCfgs;
+ for (it = 0; it < nCfgs; ++it) {
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
{
- TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
- return WINED3D_OK;
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
+ {
+ TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
+ return WINED3D_OK;
+ }
}
}
}
WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
{
IWineD3DImpl *This = (IWineD3DImpl *)iface;
- const struct GlPixelFormatDesc *glDesc;
+ const struct wined3d_format_desc *glDesc;
const struct wined3d_adapter *adapter;
TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
/* Check if we support bumpmapping for a format */
-static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter,
- WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
{
- switch(format_desc->format)
- {
- case WINED3DFMT_R8G8_SNORM:
- case WINED3DFMT_R16G16_SNORM:
- case WINED3DFMT_R5G5_SNORM_L6_UNORM:
- case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
- case WINED3DFMT_R8G8B8A8_SNORM:
- /* Ask the fixed function pipeline implementation if it can deal
- * with the conversion. If we've got a GL extension giving native
- * support this will be an identity conversion. */
- if (adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup))
- {
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
- }
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
-
- default:
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
- }
+ /* Ask the fixed function pipeline implementation if it can deal
+ * with the conversion. If we've got a GL extension giving native
+ * support this will be an identity conversion. */
+ return (format_desc->Flags & WINED3DFMT_FLAG_BUMPMAP)
+ && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup);
}
/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter,
- const struct GlPixelFormatDesc *display_format_desc, const struct GlPixelFormatDesc *ds_format_desc)
+ const struct wined3d_format_desc *display_format_desc, const struct wined3d_format_desc *ds_format_desc)
{
int it=0;
/* Only allow depth/stencil formats */
if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE;
- /* Walk through all WGL pixel formats to find a match */
- for (it = 0; it < adapter->nCfgs; ++it)
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
- WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
- if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
+ /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
+ if (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
+ }
+ else
+ {
+ /* Walk through all WGL pixel formats to find a match */
+ for (it = 0; it < adapter->nCfgs; ++it)
{
- if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
+ WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
{
- return TRUE;
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
+ {
+ return TRUE;
+ }
}
}
}
return FALSE;
}
-static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
{
/* The flags entry of a format contains the filtering capability */
if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
/* Check the render target capabilities of a format */
static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter,
- const struct GlPixelFormatDesc *adapter_format_desc, const struct GlPixelFormatDesc *check_format_desc)
+ const struct wined3d_format_desc *adapter_format_desc, const struct wined3d_format_desc *check_format_desc)
{
/* Filter out non-RT formats */
if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
-
if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
WineD3D_PixelFormat *cfgs = adapter->cfgs;
int it;
return TRUE;
}
}
- } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
- /* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */
- WineD3D_PixelFormat *cfgs = adapter->cfgs;
- int it;
-
- /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */
- for (it = 0; it < adapter->nCfgs; ++it)
- {
- if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
- &cfgs[it], check_format_desc))
- {
- TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
- cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
- return TRUE;
- }
- }
- } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){
+ }
+ else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
/* For now return TRUE for FBOs until we have some proper checks.
* Note that this function will only be called when the format is around for texturing. */
return TRUE;
return FALSE;
}
-static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
{
- const struct wined3d_gl_info *gl_info = &adapter->gl_info;
-
- /* Check for supported sRGB formats (Texture loading and framebuffer) */
- if (!gl_info->supported[EXT_TEXTURE_SRGB])
- {
- TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
- return FALSE;
- }
-
- switch (format_desc->format)
- {
- case WINED3DFMT_B8G8R8A8_UNORM:
- case WINED3DFMT_B8G8R8X8_UNORM:
- case WINED3DFMT_B4G4R4A4_UNORM:
- case WINED3DFMT_L8_UNORM:
- case WINED3DFMT_L8A8_UNORM:
- case WINED3DFMT_DXT1:
- case WINED3DFMT_DXT2:
- case WINED3DFMT_DXT3:
- case WINED3DFMT_DXT4:
- case WINED3DFMT_DXT5:
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
-
- default:
- TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format));
- return FALSE;
- }
- return FALSE;
+ return adapter->gl_info.supported[EXT_TEXTURE_SRGB]
+ && (format_desc->Flags & WINED3DFMT_FLAG_SRGB_READ);
}
-static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter,
- WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
{
/* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
* doing the color fixup in shaders.
* Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
- if ((format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) || (format_desc->format == WINED3DFMT_B8G8R8A8_UNORM))
+ if (format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
{
int vs_selected_mode;
int ps_selected_mode;
/* Check if a format support blending in combination with pixel shaders */
static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter,
- const struct GlPixelFormatDesc *format_desc)
+ const struct wined3d_format_desc *format_desc)
{
/* The flags entry of a format contains the post pixel shader blending capability */
if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
return FALSE;
}
-static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
{
/* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
* but we have to report mipmapping so we cannot reject this flag. Tests show that
}
/* Check if a texture format is supported on the given adapter */
-static BOOL CheckTextureCapability(struct wined3d_adapter *adapter,
- WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc)
{
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
return FALSE;
/*****
- * supported: Palettized
+ * Not supported: Palettized
+ * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7.
+ * Since it is not widely available, don't offer it. Further no Windows driver offers
+ * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
*/
case WINED3DFMT_P8_UINT:
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
- /* No Windows driver offers WINED3DFMT_P8_UINT_A8_UNORM, so don't offer it either */
case WINED3DFMT_P8_UINT_A8_UNORM:
return FALSE;
return FALSE;
}
-static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *adapter_format_desc,
- WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *check_format_desc, WINED3DSURFTYPE SurfaceType)
+static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter,
+ const struct wined3d_format_desc *adapter_format_desc,
+ const struct wined3d_format_desc *check_format_desc,
+ WINED3DSURFTYPE SurfaceType)
{
if(SurfaceType == SURFACE_GDI) {
switch(check_format_desc->format)
}
/* All format that are supported for textures are supported for surfaces as well */
- if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE;
+ if (CheckTextureCapability(adapter, check_format_desc)) return TRUE;
/* All depth stencil formats are supported on surfaces */
if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
/* If opengl can't process the format natively, the blitter may be able to convert it */
- if (adapter->blitter->color_fixup_supported(check_format_desc->color_fixup))
+ if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT,
+ NULL, WINED3DPOOL_DEFAULT, 0, check_format_desc,
+ NULL, WINED3DPOOL_DEFAULT, 0, adapter_format_desc))
{
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
return FALSE;
}
-static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc)
+static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter,
+ const struct wined3d_format_desc *format_desc)
{
- const struct wined3d_gl_info *gl_info = &adapter->gl_info;
-
- if (!gl_info->limits.vertex_samplers)
- {
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
- }
-
- switch (format_desc->format)
- {
- case WINED3DFMT_R32G32B32A32_FLOAT:
- if (!gl_info->supported[ARB_TEXTURE_FLOAT])
- {
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
- }
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
-
- default:
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
- }
- return FALSE;
+ return adapter->gl_info.limits.vertex_samplers
+ && (format_desc->Flags & WINED3DFMT_FLAG_VTF);
}
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
IWineD3DImpl *This = (IWineD3DImpl *)iface;
struct wined3d_adapter *adapter = &This->adapters[Adapter];
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
- const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
+ const struct wined3d_format_desc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
DWORD UsageCaps = 0;
TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
return WINED3DERR_INVALIDCALL;
}
- if(RType == WINED3DRTYPE_CUBETEXTURE) {
+ switch (RType)
+ {
+ case WINED3DRTYPE_CUBETEXTURE:
+ /* Cubetexture allows:
+ * - WINED3DUSAGE_AUTOGENMIPMAP
+ * - WINED3DUSAGE_DEPTHSTENCIL
+ * - WINED3DUSAGE_DYNAMIC
+ * - WINED3DUSAGE_NONSECURE (d3d9ex)
+ * - WINED3DUSAGE_RENDERTARGET
+ * - WINED3DUSAGE_SOFTWAREPROCESSING
+ * - WINED3DUSAGE_QUERY_WRAPANDMIP
+ */
+ if (SurfaceType != SURFACE_OPENGL)
+ {
+ TRACE_(d3d_caps)("[FAILED]\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- if(SurfaceType != SURFACE_OPENGL) {
- TRACE("[FAILED]\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- /* Cubetexture allows:
- * - D3DUSAGE_AUTOGENMIPMAP
- * - D3DUSAGE_DEPTHSTENCIL
- * - D3DUSAGE_DYNAMIC
- * - D3DUSAGE_NONSECURE (d3d9ex)
- * - D3DUSAGE_RENDERTARGET
- * - D3DUSAGE_SOFTWAREPROCESSING
- * - D3DUSAGE_QUERY_WRAPANDMIP
- */
- if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
- {
- /* Check if the texture format is around */
- if (CheckTextureCapability(adapter, DeviceType, format_desc))
+ if (!CheckTextureCapability(adapter, format_desc))
{
- if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
- /* Check for automatic mipmap generation support */
- if (gl_info->supported[SGIS_GENERATE_MIPMAP])
- {
- UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
- } else {
- /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
- TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
- }
- }
+ TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- /* Always report dynamic locking */
- if(Usage & WINED3DUSAGE_DYNAMIC)
- UsageCaps |= WINED3DUSAGE_DYNAMIC;
+ if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ {
+ if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
+ /* When autogenmipmap isn't around continue and return
+ * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
+ TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
+ else
+ UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
+ }
- if(Usage & WINED3DUSAGE_RENDERTARGET) {
- if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_RENDERTARGET;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ /* Always report dynamic locking. */
+ if (Usage & WINED3DUSAGE_DYNAMIC)
+ UsageCaps |= WINED3DUSAGE_DYNAMIC;
+
+ if (Usage & WINED3DUSAGE_RENDERTARGET)
+ {
+ if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_RENDERTARGET;
+ }
- /* Always report software processing */
- if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
- UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
+ /* Always report software processing. */
+ if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+ UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
- /* Check QUERY_FILTER support */
- if(Usage & WINED3DUSAGE_QUERY_FILTER) {
- if (CheckFilterCapability(adapter, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (Usage & WINED3DUSAGE_QUERY_FILTER)
+ {
+ if (!CheckFilterCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
+ }
- /* Check QUERY_POSTPIXELSHADER_BLENDING support */
- if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
+ {
+ if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
+ }
- /* Check QUERY_SRGBREAD support */
- if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
- if (CheckSrgbReadCapability(adapter, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
+ {
+ if (!CheckSrgbReadCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
+ }
- /* Check QUERY_SRGBWRITE support */
- if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
- if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
+ {
+ if (!CheckSrgbWriteCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
+ }
- /* Check QUERY_VERTEXTEXTURE support */
- if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
- if (CheckVertexTextureCapability(adapter, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
+ {
+ if (!CheckVertexTextureCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
+ }
- /* Check QUERY_WRAPANDMIP support */
- if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
- if (CheckWrapAndMipCapability(adapter, format_desc))
- {
- UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
- } else {
- TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
+ {
+ if (!CheckWrapAndMipCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
+ return WINED3DERR_NOTAVAILABLE;
}
- } else {
- TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
+ UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
+ }
+ break;
+
+ case WINED3DRTYPE_SURFACE:
+ /* Surface allows:
+ * - WINED3DUSAGE_DEPTHSTENCIL
+ * - WINED3DUSAGE_NONSECURE (d3d9ex)
+ * - WINED3DUSAGE_RENDERTARGET
+ */
+ if (!CheckSurfaceCapability(adapter, adapter_format_desc, format_desc, SurfaceType))
+ {
+ TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
return WINED3DERR_NOTAVAILABLE;
}
- } else {
- TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- } else if(RType == WINED3DRTYPE_SURFACE) {
- /* Surface allows:
- * - D3DUSAGE_DEPTHSTENCIL
- * - D3DUSAGE_NONSECURE (d3d9ex)
- * - D3DUSAGE_RENDERTARGET
- */
- if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType))
- {
- if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
- if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
+ if (Usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
{
- UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
- } else {
TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
}
- if(Usage & WINED3DUSAGE_RENDERTARGET) {
- if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
+ if (Usage & WINED3DUSAGE_RENDERTARGET)
+ {
+ if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
{
- UsageCaps |= WINED3DUSAGE_RENDERTARGET;
- } else {
TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_RENDERTARGET;
}
- /* Check QUERY_POSTPIXELSHADER_BLENDING support */
- if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
+ {
+ if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
}
- } else {
- TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ break;
- } else if(RType == WINED3DRTYPE_TEXTURE) {
- /* Texture allows:
- * - D3DUSAGE_AUTOGENMIPMAP
- * - D3DUSAGE_DEPTHSTENCIL
- * - D3DUSAGE_DMAP
- * - D3DUSAGE_DYNAMIC
- * - D3DUSAGE_NONSECURE (d3d9ex)
- * - D3DUSAGE_RENDERTARGET
- * - D3DUSAGE_SOFTWAREPROCESSING
- * - D3DUSAGE_TEXTAPI (d3d9ex)
- * - D3DUSAGE_QUERY_WRAPANDMIP
- */
+ case WINED3DRTYPE_TEXTURE:
+ /* Texture allows:
+ * - WINED3DUSAGE_AUTOGENMIPMAP
+ * - WINED3DUSAGE_DEPTHSTENCIL
+ * - WINED3DUSAGE_DMAP
+ * - WINED3DUSAGE_DYNAMIC
+ * - WINED3DUSAGE_NONSECURE (d3d9ex)
+ * - WINED3DUSAGE_RENDERTARGET
+ * - WINED3DUSAGE_SOFTWAREPROCESSING
+ * - WINED3DUSAGE_TEXTAPI (d3d9ex)
+ * - WINED3DUSAGE_QUERY_WRAPANDMIP
+ */
+ if (SurfaceType != SURFACE_OPENGL)
+ {
+ TRACE_(d3d_caps)("[FAILED]\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- if(SurfaceType != SURFACE_OPENGL) {
- TRACE("[FAILED]\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ if (!CheckTextureCapability(adapter, format_desc))
+ {
+ TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- /* Check if the texture format is around */
- if (CheckTextureCapability(adapter, DeviceType, format_desc))
- {
- if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
- /* Check for automatic mipmap generation support */
- if (gl_info->supported[SGIS_GENERATE_MIPMAP])
- {
- UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
- } else {
- /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */
+ if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ {
+ if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
+ /* When autogenmipmap isn't around continue and return
+ * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
- }
+ else
+ UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
}
- /* Always report dynamic locking */
- if(Usage & WINED3DUSAGE_DYNAMIC)
+ /* Always report dynamic locking. */
+ if (Usage & WINED3DUSAGE_DYNAMIC)
UsageCaps |= WINED3DUSAGE_DYNAMIC;
- if(Usage & WINED3DUSAGE_RENDERTARGET) {
- if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
+ if (Usage & WINED3DUSAGE_RENDERTARGET)
+ {
+ if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
{
- UsageCaps |= WINED3DUSAGE_RENDERTARGET;
- } else {
TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ UsageCaps |= WINED3DUSAGE_RENDERTARGET;
}
- /* Always report software processing */
- if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+ /* Always report software processing. */
+ if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
- /* Check QUERY_FILTER support */
- if(Usage & WINED3DUSAGE_QUERY_FILTER) {
- if (CheckFilterCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_FILTER)
+ {
+ if (!CheckFilterCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
}
- /* Check QUERY_LEGACYBUMPMAP support */
- if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
- if (CheckBumpMapCapability(adapter, DeviceType, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
+ {
+ if (!CheckBumpMapCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
- } else {
TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
}
- /* Check QUERY_POSTPIXELSHADER_BLENDING support */
- if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
+ {
+ if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
}
- /* Check QUERY_SRGBREAD support */
- if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
- if (CheckSrgbReadCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
+ {
+ if (!CheckSrgbReadCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
}
- /* Check QUERY_SRGBWRITE support */
- if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
- if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
+ {
+ if (!CheckSrgbWriteCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
}
- /* Check QUERY_VERTEXTEXTURE support */
- if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
- if (CheckVertexTextureCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
+ {
+ if (!CheckVertexTextureCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
}
- /* Check QUERY_WRAPANDMIP support */
- if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
- if (CheckWrapAndMipCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
+ {
+ if (!CheckWrapAndMipCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
- } else {
TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
}
- if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
- if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
+ if (Usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
{
- UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
- } else {
TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ if ((format_desc->Flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW])
+ {
+ TRACE_(d3d_caps)("[FAILED] - No shadow sampler support.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
}
- } else {
- TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
- /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
- * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
- *
- * Volumetexture allows:
- * - D3DUSAGE_DYNAMIC
- * - D3DUSAGE_NONSECURE (d3d9ex)
- * - D3DUSAGE_SOFTWAREPROCESSING
- * - D3DUSAGE_QUERY_WRAPANDMIP
- */
+ break;
- if(SurfaceType != SURFACE_OPENGL) {
- TRACE("[FAILED]\n");
- return WINED3DERR_NOTAVAILABLE;
- }
+ case WINED3DRTYPE_VOLUMETEXTURE:
+ case WINED3DRTYPE_VOLUME:
+ /* Volume is to VolumeTexture what Surface is to Texture, but its
+ * usage caps are not documented. Most driver seem to offer
+ * (nearly) the same on Volume and VolumeTexture, so do that too.
+ *
+ * Volumetexture allows:
+ * - D3DUSAGE_DYNAMIC
+ * - D3DUSAGE_NONSECURE (d3d9ex)
+ * - D3DUSAGE_SOFTWAREPROCESSING
+ * - D3DUSAGE_QUERY_WRAPANDMIP
+ */
+ if (SurfaceType != SURFACE_OPENGL)
+ {
+ TRACE_(d3d_caps)("[FAILED]\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
- /* Check volume texture and volume usage caps */
- if (gl_info->supported[EXT_TEXTURE3D])
- {
- if (!CheckTextureCapability(adapter, DeviceType, format_desc))
+ if (!gl_info->supported[EXT_TEXTURE3D])
+ {
+ TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if (!CheckTextureCapability(adapter, format_desc))
{
TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
return WINED3DERR_NOTAVAILABLE;
}
- /* Always report dynamic locking */
- if(Usage & WINED3DUSAGE_DYNAMIC)
+ /* Filter formats that need conversion; For one part, this
+ * conversion is unimplemented, and volume textures are huge, so
+ * it would be a big performance hit. Unless we hit an application
+ * needing one of those formats, don't advertize them to avoid
+ * leading applications into temptation. The windows drivers don't
+ * support most of those formats on volumes anyway, except for
+ * WINED3DFMT_R32_FLOAT. */
+ switch (CheckFormat)
+ {
+ case WINED3DFMT_P8_UINT:
+ case WINED3DFMT_L4A4_UNORM:
+ case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R16_FLOAT:
+ case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
+ case WINED3DFMT_R5G5_SNORM_L6_UNORM:
+ case WINED3DFMT_R16G16_UNORM:
+ TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
+ return WINED3DERR_NOTAVAILABLE;
+
+ case WINED3DFMT_R8G8B8A8_SNORM:
+ case WINED3DFMT_R16G16_SNORM:
+ if (!gl_info->supported[NV_TEXTURE_SHADER])
+ {
+ TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ break;
+
+ case WINED3DFMT_R8G8_SNORM:
+ if (!gl_info->supported[NV_TEXTURE_SHADER])
+ {
+ TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ break;
+
+ case WINED3DFMT_DXT1:
+ case WINED3DFMT_DXT2:
+ case WINED3DFMT_DXT3:
+ case WINED3DFMT_DXT4:
+ case WINED3DFMT_DXT5:
+ /* The GL_EXT_texture_compression_s3tc spec requires that
+ * loading an s3tc compressed texture results in an error.
+ * While the D3D refrast does support s3tc volumes, at
+ * least the nvidia windows driver does not, so we're free
+ * not to support this format. */
+ TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
+ return WINED3DERR_NOTAVAILABLE;
+
+ default:
+ /* Do nothing, continue with checking the format below */
+ break;
+ }
+
+ /* Always report dynamic locking. */
+ if (Usage & WINED3DUSAGE_DYNAMIC)
UsageCaps |= WINED3DUSAGE_DYNAMIC;
- /* Always report software processing */
- if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+ /* Always report software processing. */
+ if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
- /* Check QUERY_FILTER support */
- if(Usage & WINED3DUSAGE_QUERY_FILTER) {
- if (CheckFilterCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_FILTER)
+ {
+ if (!CheckFilterCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
}
- /* Check QUERY_POSTPIXELSHADER_BLENDING support */
- if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
+ {
+ if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
}
- /* Check QUERY_SRGBREAD support */
- if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
- if (CheckSrgbReadCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_SRGBREAD)
+ {
+ if (!CheckSrgbReadCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
}
- /* Check QUERY_SRGBWRITE support */
- if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
- if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE)
+ {
+ if (!CheckSrgbWriteCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
}
- /* Check QUERY_VERTEXTEXTURE support */
- if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
- if (CheckVertexTextureCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
+ {
+ if (!CheckVertexTextureCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
- } else {
TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
return WINED3DERR_NOTAVAILABLE;
}
+ UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
}
- /* Check QUERY_WRAPANDMIP support */
- if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
- if (CheckWrapAndMipCapability(adapter, format_desc))
+ if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
+ {
+ if (!CheckWrapAndMipCapability(adapter, format_desc))
{
- UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
- } else {
TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
return WINED3DERR_NOTAVAILABLE;
}
- }
- } else {
- TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
- return WINED3DERR_NOTAVAILABLE;
- }
-
- /* Filter formats that need conversion; For one part, this conversion is unimplemented,
- * and volume textures are huge, so it would be a big performance hit. Unless we hit an
- * app needing one of those formats, don't advertize them to avoid leading apps into
- * temptation. The windows drivers don't support most of those formats on volumes anyway,
- * except of R32F.
- */
- switch(CheckFormat) {
- case WINED3DFMT_P8_UINT:
- case WINED3DFMT_L4A4_UNORM:
- case WINED3DFMT_R32_FLOAT:
- case WINED3DFMT_R16_FLOAT:
- case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
- case WINED3DFMT_R5G5_SNORM_L6_UNORM:
- case WINED3DFMT_R16G16_UNORM:
- TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
- return WINED3DERR_NOTAVAILABLE;
-
- case WINED3DFMT_R8G8B8A8_SNORM:
- case WINED3DFMT_R16G16_SNORM:
- if (!gl_info->supported[NV_TEXTURE_SHADER])
- {
- TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
- return WINED3DERR_NOTAVAILABLE;
+ UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
}
break;
- case WINED3DFMT_R8G8_SNORM:
- if (!gl_info->supported[NV_TEXTURE_SHADER])
- {
- TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
- return WINED3DERR_NOTAVAILABLE;
- }
- break;
-
- case WINED3DFMT_DXT1:
- case WINED3DFMT_DXT2:
- case WINED3DFMT_DXT3:
- case WINED3DFMT_DXT4:
- case WINED3DFMT_DXT5:
- /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
- * compressed texture results in an error. While the D3D refrast does
- * support s3tc volumes, at least the nvidia windows driver does not, so
- * we're free not to support this format.
- */
- TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
- return WINED3DERR_NOTAVAILABLE;
-
- default:
- /* Do nothing, continue with checking the format below */
- break;
- }
- } else if(RType == WINED3DRTYPE_BUFFER){
- /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
- TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
- return WINED3DERR_NOTAVAILABLE;
+ default:
+ FIXME_(d3d_caps)("Unhandled resource type %s.\n", debug_d3dresourcetype(RType));
+ return WINED3DERR_NOTAVAILABLE;
}
- /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
- * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
- * usage flags match. */
- if(UsageCaps == Usage) {
+ /* When the UsageCaps exactly matches Usage return WINED3D_OK except for
+ * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then
+ * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */
+ if (UsageCaps == Usage)
return WINED3D_OK;
- } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){
+ if (UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP))
return WINED3DOK_NOAUTOGEN;
- } else {
- TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested for CheckFormat=%s and RType=%d but only %#08x is available\n", Usage, debug_d3dformat(CheckFormat), RType, UsageCaps);
- return WINED3DERR_NOTAVAILABLE;
- }
+
+ TRACE_(d3d_caps)("[FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available\n",
+ Usage, debug_d3dformat(CheckFormat), debug_d3dresourcetype(RType), UsageCaps);
+
+ return WINED3DERR_NOTAVAILABLE;
}
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx,
WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
/* TODO:
WINED3DPMISCCAPS_NULLREFERENCE
- WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
WINED3DPMISCCAPS_FOGANDSPECULARALPHA
WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
+ if (gl_info->supported[EXT_DRAW_BUFFERS2])
+ pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER |
WINED3DPRASTERCAPS_PAT |
WINED3DPTFILTERCAPS_MAGFLINEAR;
pCaps->VertexTextureFilterCaps = 0;
- memset(&shader_caps, 0, sizeof(shader_caps));
adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
-
- memset(&fragment_caps, 0, sizeof(fragment_caps));
adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
/* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
- pCaps->VS20Caps = shader_caps.VS20Caps;
- pCaps->MaxVShaderInstructionsExecuted = shader_caps.MaxVShaderInstructionsExecuted;
- pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;
- pCaps->PS20Caps = shader_caps.PS20Caps;
- pCaps->MaxPShaderInstructionsExecuted = shader_caps.MaxPShaderInstructionsExecuted;
- pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots;
-
/* The following caps are shader specific, but they are things we cannot detect, or which
* are the same among all shader models. So to avoid code duplication set the shader version
* specific, but otherwise constant caps here
}
}
-BOOL InitAdapters(IWineD3DImpl *This)
+static BOOL InitAdapters(IWineD3DImpl *This)
{
static HMODULE mod_gl;
BOOL ret;
cfgs->doubleBuffer = values[9];
cfgs->auxBuffers = values[10];
- cfgs->pbufferDrawable = FALSE;
- /* Check for pbuffer support when it is around as
- * wglGetPixelFormatAttribiv fails for unknown attributes. */
- if (gl_info->supported[WGL_ARB_PBUFFER])
- {
- int attrib = WGL_DRAW_TO_PBUFFER_ARB;
- int value;
- if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
- cfgs->pbufferDrawable = value;
- }
-
cfgs->numSamples = 0;
/* Check multisample support */
if (gl_info->supported[ARB_MULTISAMPLE])
}
}
- TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, samples=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable, cfgs->pbufferDrawable);
+ TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
+ "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
+ cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
+ cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
+ cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable);
cfgs++;
}
}
cfgs->colorSize = ppfd.cColorBits;
cfgs->depthSize = ppfd.cDepthBits;
cfgs->stencilSize = ppfd.cStencilBits;
- cfgs->pbufferDrawable = 0;
cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
cfgs->auxBuffers = ppfd.cAuxBuffers;
cfgs->numSamples = 0;
- TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
+ TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
+ "depth=%d, stencil=%d, windowDrawable=%d\n",
+ cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
+ cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
+ cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable);
cfgs++;
adapter->nCfgs++;
}
* IWineD3D VTbl follows
**********************************************************/
-const IWineD3DVtbl IWineD3D_Vtbl =
+static const struct IWineD3DVtbl IWineD3D_Vtbl =
{
/* IUnknown */
IWineD3DImpl_QueryInterface,
{
wined3d_null_wined3d_object_destroyed,
};
+
+HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent)
+{
+ wined3d->lpVtbl = &IWineD3D_Vtbl;
+ wined3d->dxVersion = version;
+ wined3d->ref = 1;
+ wined3d->parent = parent;
+
+ if (!InitAdapters(wined3d))
+ {
+ WARN("Failed to initialize adapters.\n");
+ if (version > 7)
+ {
+ MESSAGE("Direct3D%u is not available without OpenGL.\n", version);
+ return E_FAIL;
+ }
+ }
+
+ return WINED3D_OK;
+}
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
-#define GLINFO_LOCATION This->adapter->gl_info
#include <stdio.h>
#include <math.h>
UINT vx_index;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const UINT *streamOffset = This->stateBlock->streamOffset;
- long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
+ LONG SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
BOOL pixelShader = use_ps(This->stateBlock);
BOOL specular_fog = FALSE;
const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
TRACE("Using slow vertex array code\n");
/* Variable Initialization */
- if (idxSize != 0) {
- /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer.
- * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing
- * idxData will be != NULL
- */
- if(idxData == NULL) {
- idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData);
- }
+ if (idxSize)
+ {
+ /* Immediate mode drawing can't make use of indices in a vbo - get the
+ * data from the index buffer. If the index buffer has no vbo (not
+ * supported or other reason), or with user pointer drawing idxData
+ * will be non-NULL. */
+ if (!idxData)
+ idxData = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->pIndexData, gl_info);
if (idxSize == 2) pIdxBufS = idxData;
else pIdxBufL = idxData;
}
/* Start drawing in GL */
- VTRACE(("glBegin(%x)\n", glPrimType));
glBegin(glPrimType);
if (si->use_map & (1 << WINED3D_FFP_POSITION))
if (idxData != NULL) {
/* Indexed so work out the number of strides to skip */
- if (idxSize == 2) {
- VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ if (idxSize == 2)
SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
- } else {
- VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ else
SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
- }
}
tmp_tex_mask = tex_mask;
GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT startIdx)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
- long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
+ const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+ LONG SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
const WORD *pIdxBufS = NULL;
const DWORD *pIdxBufL = NULL;
UINT vx_index;
IWineD3DStateBlockImpl *stateblock = This->stateBlock;
const BYTE *ptr;
- if (idxSize != 0) {
- /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer.
- * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing
- * idxData will be != NULL
- */
- if(idxData == NULL) {
- idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData);
- }
+ if (idxSize)
+ {
+ /* Immediate mode drawing can't make use of indices in a vbo - get the
+ * data from the index buffer. If the index buffer has no vbo (not
+ * supported or other reason), or with user pointer drawing idxData
+ * will be non-NULL. */
+ if (!idxData)
+ idxData = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->pIndexData, gl_info);
if (idxSize == 2) pIdxBufS = idxData;
else pIdxBufL = idxData;
}
/* Start drawing in GL */
- VTRACE(("glBegin(%x)\n", glPrimitiveType));
glBegin(glPrimitiveType);
for (vx_index = 0; vx_index < numberOfVertices; ++vx_index) {
if (idxData != NULL) {
/* Indexed so work out the number of strides to skip */
- if (idxSize == 2) {
- VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ if (idxSize == 2)
SkipnStrides = pIdxBufS[startIdx + vx_index] + stateblock->loadBaseVertexIndex;
- } else {
- VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ else
SkipnStrides = pIdxBufL[startIdx + vx_index] + stateblock->loadBaseVertexIndex;
- }
}
for (i = MAX_ATTRIBS - 1; i >= 0; i--)
{
struct wined3d_buffer *vb =
(struct wined3d_buffer *)stateblock->streamSource[si->elements[instancedData[j]].stream_idx];
- ptr += (long) buffer_get_sysmem(vb);
+ ptr += (ULONG_PTR)buffer_get_sysmem(vb, &This->adapter->gl_info);
}
send_attribute(This, si->elements[instancedData[j]].format_desc->format, instancedData[j], ptr);
}
}
-static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_info *s)
+static inline void remove_vbos(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info,
+ struct wined3d_stream_info *s)
{
unsigned int i;
{
struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
e->buffer_object = 0;
- e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
+ e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, gl_info));
}
}
}
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IWineD3DSurfaceImpl *target;
struct wined3d_context *context;
unsigned int i;
/* Invalidate the back buffer memory so LockRect will read it the next time */
for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i)
{
- target = (IWineD3DSurfaceImpl *)This->render_targets[i];
+ IWineD3DSurface *target = (IWineD3DSurface *)This->render_targets[i];
if (target)
{
- IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL);
- IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
+ IWineD3DSurface_LoadLocation(target, SFLAG_INDRAWABLE, NULL);
+ IWineD3DSurface_ModifyLocation(target, SFLAG_INDRAWABLE, TRUE);
}
}
}
/* Signals other modules that a drawing is in progress and the stateblock finalized */
This->isInDraw = TRUE;
- context = context_acquire(This, This->render_targets[0], CTXUSAGE_DRAWPRIM);
+ context = context_acquire(This, This->render_targets[0]);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping draw.\n");
+ return;
+ }
+
+ context_apply_draw_state(context, This);
- if (This->stencilBufferTarget) {
+ if (This->depth_stencil)
+ {
/* Note that this depends on the context_acquire() call above to set
* This->render_offscreen properly. We don't currently take the
* Z-compare function into account, but we could skip loading the
DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]
|| This->stateBlock->renderState[WINED3DRS_ZENABLE])
- surface_load_ds_location(This->stencilBufferTarget, context, location);
- if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE])
- surface_modify_ds_location(This->stencilBufferTarget, location);
+ {
+ RECT current_rect, draw_rect, r;
+
+ if (location == SFLAG_DS_ONSCREEN && This->depth_stencil != This->onscreen_depth_stencil)
+ device_switch_onscreen_ds(This, context, This->depth_stencil);
+
+ if (This->depth_stencil->Flags & location)
+ SetRect(¤t_rect, 0, 0,
+ This->depth_stencil->ds_current_size.cx,
+ This->depth_stencil->ds_current_size.cy);
+ else
+ SetRectEmpty(¤t_rect);
+
+ device_get_draw_rect(This, &draw_rect);
+
+ IntersectRect(&r, &draw_rect, ¤t_rect);
+ if (!EqualRect(&r, &draw_rect))
+ surface_load_ds_location(This->depth_stencil, context, location);
+
+ if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE])
+ {
+ surface_modify_ds_location(This->depth_stencil, location,
+ This->depth_stencil->ds_current_size.cx,
+ This->depth_stencil->ds_current_size.cy);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->depth_stencil, SFLAG_INDRAWABLE, TRUE);
+ }
+ }
}
/* Ok, we will be updating the screen from here onwards so grab the lock */
if(emulation) {
stream_info = &stridedlcl;
memcpy(&stridedlcl, &This->strided_streams, sizeof(stridedlcl));
- remove_vbos(This, &stridedlcl);
+ remove_vbos(This, context->gl_info, &stridedlcl);
}
}
/* Finished updating the screen, restore lock */
LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ for(i = 0; i < This->num_buffer_queries; i++)
+ {
+ wined3d_event_query_issue(This->buffer_queries[i], This);
+ }
+
+ if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
/* Diagnostics */
#ifdef SHOW_FRAME_MAKEUP
{
- static long int primCounter = 0;
+ static LONG primCounter = 0;
/* NOTE: set primCounter to the value reported by drawprim
before you want to to write frame makeup to /tmp */
if (primCounter >= 0) {
WINED3DLOCKED_RECT r;
char buffer[80];
IWineD3DSurface_LockRect(This->render_targets[0], &r, NULL, WINED3DLOCK_READONLY);
- sprintf(buffer, "/tmp/backbuffer_%ld.tga", primCounter);
+ sprintf(buffer, "/tmp/backbuffer_%d.tga", primCounter);
TRACE("Saving screenshot %s\n", buffer);
IWineD3DSurface_SaveSnapshot(This->render_targets[0], buffer);
IWineD3DSurface_UnlockRect(This->render_targets[0]);
int textureNo;
for (textureNo = 0; textureNo < MAX_COMBINED_SAMPLERS; ++textureNo) {
if (This->stateBlock->textures[textureNo] != NULL) {
- sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo);
+ sprintf(buffer, "/tmp/texture_%p_%d_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo);
TRACE("Saving texture %s\n", buffer);
if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) {
IWineD3DTexture_GetSurfaceLevel(This->stateBlock->textures[textureNo], 0, &pSur);
}
#endif
}
- TRACE("drawprim #%ld\n", primCounter);
+ TRACE("drawprim #%d\n", primCounter);
++primCounter;
}
#endif
/* Simply activate the context for blitting. This disables all the things we don't want and
* takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the
* patch (as opposed to normal draws) will most likely need different changes anyway. */
- context = context_acquire(This, NULL, CTXUSAGE_BLIT);
+ context = context_acquire(This, NULL);
+ context_apply_blit_state(context, This);
/* First, locate the position data. This is provided in a vertex buffer in the stateblock.
* Beware of vbos
{
struct wined3d_buffer *vb;
vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
- e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
+ e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, context->gl_info));
}
vtxStride = e->stride;
data = e->data +
WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION (*gl_info)
-
#define WINED3D_GLSL_SAMPLE_PROJECTED 0x1
#define WINED3D_GLSL_SAMPLE_RECT 0x2
#define WINED3D_GLSL_SAMPLE_LOD 0x4
struct constant_heap vconst_heap;
struct constant_heap pconst_heap;
unsigned char *stack;
- GLhandleARB depth_blt_program[tex_type_count];
+ GLhandleARB depth_blt_program_full[tex_type_count];
+ GLhandleARB depth_blt_program_masked[tex_type_count];
UINT next_constant_version;
};
/* GL locking is done by the caller. */
static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program)
{
- GLint i, object_count, source_size;
+ GLint i, object_count, source_size = -1;
GLhandleARB *objects;
char *source = NULL;
GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp));
- if (!source || source_size < tmp)
+ if (source_size < tmp)
{
HeapFree(GetProcessHeap(), 0, source);
static void shader_glsl_load_constants(const struct wined3d_context *context,
char usePixelShader, char useVertexShader)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
+ IWineD3DDeviceImpl *device = context->swapchain->device;
IWineD3DStateBlockImpl* stateBlock = device->stateBlock;
struct shader_glsl_priv *priv = device->shader_priv;
correction_params[1] = 1.0f;
} else {
/* position is window relative, not viewport relative */
- correction_params[0] = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height;
+ correction_params[0] = context->current_rt->currentDesc.Height;
correction_params[1] = -1.0f;
}
GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
*/
FIXME("Cannot find a free uniform for vpos correction params\n");
shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n",
- context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height,
+ context->render_offscreen ? 0.0f : device->render_targets[0]->currentDesc.Height,
context->render_offscreen ? 1.0f : -1.0f);
}
shader_addline(buffer, "vec4 vpos;\n");
switch (reg_maps->sampler_type[i])
{
case WINED3DSTT_1D:
- shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i);
+ if (pshader && ps_args->shadow & (1 << i))
+ shader_addline(buffer, "uniform sampler1DShadow %csampler%u;\n", prefix, i);
+ else
+ shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i);
break;
case WINED3DSTT_2D:
- if(device->stateBlock->textures[i] &&
- IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) == GL_TEXTURE_RECTANGLE_ARB) {
- shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i);
- } else {
- shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
+ if (pshader && ps_args->shadow & (1 << i))
+ {
+ if (device->stateBlock->textures[i]
+ && IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i])
+ == GL_TEXTURE_RECTANGLE_ARB)
+ shader_addline(buffer, "uniform sampler2DRectShadow %csampler%u;\n", prefix, i);
+ else
+ shader_addline(buffer, "uniform sampler2DShadow %csampler%u;\n", prefix, i);
+ }
+ else
+ {
+ if (device->stateBlock->textures[i]
+ && IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i])
+ == GL_TEXTURE_RECTANGLE_ARB)
+ shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i);
+ else
+ shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
}
break;
case WINED3DSTT_CUBE:
+ if (pshader && ps_args->shadow & (1 << i)) FIXME("Unsupported Cube shadow sampler.\n");
shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i);
break;
case WINED3DSTT_VOLUME:
+ if (pshader && ps_args->shadow & (1 << i)) FIXME("Unsupported 3D shadow sampler.\n");
shader_addline(buffer, "uniform sampler3D %csampler%u;\n", prefix, i);
break;
default:
}
}
-static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_info,
- DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function)
+static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx,
+ DWORD sampler_idx, DWORD flags, glsl_sample_function_t *sample_function)
{
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ctx->reg_maps->sampler_type[sampler_idx];
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ BOOL shadow = shader_is_pshader_version(ctx->reg_maps->shader_version.type)
+ && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx));
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
/* Note that there's no such thing as a projected cube texture. */
switch(sampler_type) {
case WINED3DSTT_1D:
- if(lod) {
- sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
- }
- else if (grad)
+ if (shadow)
{
- if (gl_info->supported[EXT_GPU_SHADER4])
- sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad";
- else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
- sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
- else
+ if (lod)
{
- FIXME("Unsupported 1D grad function.\n");
- sample_function->name = "unsupported1DGrad";
+ sample_function->name = projected ? "shadow1DProjLod" : "shadow1DLod";
}
- }
- else
- {
- sample_function->name = projected ? "texture1DProj" : "texture1D";
- }
- sample_function->coord_mask = WINED3DSP_WRITEMASK_0;
- break;
- case WINED3DSTT_2D:
- if(texrect) {
- if(lod) {
- sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
- }
- else if (grad)
+ else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
- sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad";
+ sample_function->name = projected ? "shadow1DProjGrad" : "shadow1DGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
- sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB";
+ sample_function->name = projected ? "shadow1DProjGradARB" : "shadow1DGradARB";
else
{
- FIXME("Unsupported RECT grad function.\n");
- sample_function->name = "unsupported2DRectGrad";
+ FIXME("Unsupported 1D shadow grad function.\n");
+ sample_function->name = "unsupported1DGrad";
}
}
else
{
- sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
+ sample_function->name = projected ? "shadow1DProj" : "shadow1D";
}
- } else {
- if(lod) {
- sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1;
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
}
- else if (grad)
+ else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
- sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad";
+ sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
- sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
+ sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
else
{
- FIXME("Unsupported 2D grad function.\n");
- sample_function->name = "unsupported2DGrad";
+ FIXME("Unsupported 1D grad function.\n");
+ sample_function->name = "unsupported1DGrad";
}
}
else
{
- sample_function->name = projected ? "texture2DProj" : "texture2D";
+ sample_function->name = projected ? "texture1DProj" : "texture1D";
}
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0;
}
- sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1;
break;
- case WINED3DSTT_CUBE:
- if(lod) {
- sample_function->name = "textureCubeLod";
- }
- else if (grad)
+
+ case WINED3DSTT_2D:
+ if (shadow)
{
- if (gl_info->supported[EXT_GPU_SHADER4])
- sample_function->name = "textureCubeGrad";
- else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
- sample_function->name = "textureCubeGradARB";
+ if (texrect)
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "shadow2DRectProjLod" : "shadow2DRectLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "shadow2DRectProjGrad" : "shadow2DRectGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB";
+ else
+ {
+ FIXME("Unsupported RECT shadow grad function.\n");
+ sample_function->name = "unsupported2DRectGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "shadow2DRectProj" : "shadow2DRect";
+ }
+ }
else
{
- FIXME("Unsupported Cube grad function.\n");
- sample_function->name = "unsupportedCubeGrad";
+ if (lod)
+ {
+ sample_function->name = projected ? "shadow2DProjLod" : "shadow2DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "shadow2DProjGrad" : "shadow2DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "shadow2DProjGradARB" : "shadow2DGradARB";
+ else
+ {
+ FIXME("Unsupported 2D shadow grad function.\n");
+ sample_function->name = "unsupported2DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "shadow2DProj" : "shadow2D";
+ }
}
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
}
else
{
- sample_function->name = "textureCube";
+ if (texrect)
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB";
+ else
+ {
+ FIXME("Unsupported RECT grad function.\n");
+ sample_function->name = "unsupported2DRectGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
+ }
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
+ else
+ {
+ FIXME("Unsupported 2D grad function.\n");
+ sample_function->name = "unsupported2DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture2DProj" : "texture2D";
+ }
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1;
}
- sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
break;
- case WINED3DSTT_VOLUME:
- if(lod) {
- sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
+
+ case WINED3DSTT_CUBE:
+ if (shadow)
+ {
+ FIXME("Unsupported Cube shadow function.\n ");
+ sample_function->name = "unsupportedCubeShadow";
+ sample_function->coord_mask = 0;
}
- else if (grad)
+ else
{
- if (gl_info->supported[EXT_GPU_SHADER4])
- sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
- else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
- sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
+ if (lod)
+ {
+ sample_function->name = "textureCubeLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = "textureCubeGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = "textureCubeGradARB";
+ else
+ {
+ FIXME("Unsupported Cube grad function.\n");
+ sample_function->name = "unsupportedCubeGrad";
+ }
+ }
else
{
- FIXME("Unsupported 3D grad function.\n");
- sample_function->name = "unsupported3DGrad";
+ sample_function->name = "textureCube";
}
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ }
+ break;
+
+ case WINED3DSTT_VOLUME:
+ if (shadow)
+ {
+ FIXME("Unsupported 3D shadow function.\n ");
+ sample_function->name = "unsupported3DShadow";
+ sample_function->coord_mask = 0;
}
else
{
- sample_function->name = projected ? "texture3DProj" : "texture3D";
+ if (lod)
+ {
+ sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
+ else
+ {
+ FIXME("Unsupported 3D grad function.\n");
+ sample_function->name = "unsupported3DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture3DProj" : "texture3D";
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
}
- sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
break;
+
default:
sample_function->name = "";
sample_function->coord_mask = 0;
{
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
glsl_src_param_t src_param;
+ unsigned int mask_size;
DWORD write_mask;
char dst_mask[6];
write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
shader_addline(buffer, "tmp0.x = length(%s);\n", src_param.param_str);
shader_glsl_append_dst(buffer, ins);
- shader_addline(buffer, "tmp0.x == 0.0 ? (%s * FLT_MAX) : (%s / tmp0.x));",
- src_param.param_str, src_param.param_str);
+ if (mask_size > 1)
+ {
+ shader_addline(buffer, "tmp0.x == 0.0 ? vec%u(0.0) : (%s / tmp0.x));\n",
+ mask_size, src_param.param_str);
+ }
+ else
+ {
+ shader_addline(buffer, "tmp0.x == 0.0 ? 0.0 : (%s / tmp0.x));\n",
+ src_param.param_str);
+ }
}
/** Process the WINED3DSIO_EXPP instruction in GLSL:
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
ins->ctx->reg_maps->shader_version.minor);
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
DWORD sample_flags = 0;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
DWORD sampler_idx;
DWORD mask = 0, swizzle;
* 2.0+: Use provided sampler source. */
if (shader_version < WINED3D_SHADER_VERSION(2,0)) sampler_idx = ins->dst[0].reg.idx;
else sampler_idx = ins->src[1].reg.idx;
- sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
if (shader_version < WINED3D_SHADER_VERSION(1,4))
{
DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
/* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
if (flags & WINED3DTTFF_PROJECTED && sampler_type != WINED3DSTT_CUBE) {
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
- shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
mask |= sample_function.coord_mask;
if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, dx_param, dy_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
- DWORD sampler_type;
DWORD sampler_idx;
DWORD swizzle = ins->src[1].swizzle;
}
sampler_idx = ins->src[1].reg.idx;
- sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
if(deviceImpl->stateBlock->textures[sampler_idx] &&
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
- shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, lod_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
- DWORD sampler_type;
DWORD sampler_idx;
DWORD swizzle = ins->src[1].swizzle;
sampler_idx = ins->src[1].reg.idx;
- sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
if(deviceImpl->stateBlock->textures[sampler_idx] &&
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
- shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
* then perform a 1D texture lookup from stage dstregnum, place into dst. */
static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
glsl_sample_function_t sample_function;
DWORD sampler_idx = ins->dst[0].reg.idx;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
UINT mask_size;
shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
*
* It is a dependent read - not valid with conditional NP2 textures
*/
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask);
switch(mask_size)
static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD reg = ins->dst[0].reg.idx;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
/* Dependent read, not valid with conditional NP2 */
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
DWORD reg = ins->dst[0].reg.idx;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
- WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg];
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
glsl_sample_function_t sample_function;
shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str);
/* Dependent read, not valid with conditional NP2 */
- shader_glsl_get_sample_function(gl_info, stype, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
/* Sample the texture */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
glsl_src_param_t src0_param;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n");
/* Dependent read, not valid with conditional NP2 */
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
DWORD sampler_idx;
DWORD mask;
DWORD flags;
sampler_idx = ins->dst[0].reg.idx;
flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
- sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
/* Dependent read, not valid with conditional NP2 */
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
mask = sample_function.coord_mask;
shader_glsl_write_mask_to_str(mask, coord_mask);
* Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD sampler_idx = ins->dst[0].reg.idx;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s.wx", src0_param.reg_name);
}
* Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD sampler_idx = ins->dst[0].reg.idx;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s.yz", src0_param.reg_name);
}
* Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
{
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD sampler_idx = ins->dst[0].reg.idx;
- WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
/* Dependent read, not valid with conditional NP2 */
- shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
}
/* GL locking is done by the caller */
-static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type)
+static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked)
{
GLhandleARB program_id;
GLhandleARB vshader_id, pshader_id;
+ const char *blt_pshader;
+
static const char *blt_vshader[] =
{
"#version 120\n"
"}\n"
};
- static const char *blt_pshaders[tex_type_count] =
+ static const char *blt_pshaders_full[tex_type_count] =
{
/* tex_1d */
NULL,
"}\n",
};
- if (!blt_pshaders[tex_type])
+ static const char *blt_pshaders_masked[tex_type_count] =
+ {
+ /* tex_1d */
+ NULL,
+ /* tex_2d */
+ "#version 120\n"
+ "uniform sampler2D sampler;\n"
+ "uniform vec4 mask;\n"
+ "void main(void)\n"
+ "{\n"
+ " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n"
+ " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n"
+ "}\n",
+ /* tex_3d */
+ NULL,
+ /* tex_cube */
+ "#version 120\n"
+ "uniform samplerCube sampler;\n"
+ "uniform vec4 mask;\n"
+ "void main(void)\n"
+ "{\n"
+ " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n"
+ " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n"
+ "}\n",
+ /* tex_rect */
+ "#version 120\n"
+ "#extension GL_ARB_texture_rectangle : enable\n"
+ "uniform sampler2DRect sampler;\n"
+ "uniform vec4 mask;\n"
+ "void main(void)\n"
+ "{\n"
+ " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n"
+ " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n"
+ "}\n",
+ };
+
+ blt_pshader = masked ? blt_pshaders_masked[tex_type] : blt_pshaders_full[tex_type];
+ if (!blt_pshader)
{
FIXME("tex_type %#x not supported\n", tex_type);
tex_type = tex_2d;
GL_EXTCALL(glCompileShaderARB(vshader_id));
pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
- GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshaders[tex_type], NULL));
+ GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshader, NULL));
GL_EXTCALL(glCompileShaderARB(pshader_id));
program_id = GL_EXTCALL(glCreateProgramObjectARB());
/* GL locking is done by the caller */
static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
+ IWineD3DDeviceImpl *device = context->swapchain->device;
struct shader_glsl_priv *priv = device->shader_priv;
GLhandleARB program_id = 0;
GLenum old_vertex_color_clamp, current_vertex_color_clamp;
}
/* GL locking is done by the caller */
-static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
+static void shader_glsl_select_depth_blt(IWineD3DDevice *iface,
+ enum tex_types tex_type, const SIZE *ds_mask_size)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+ BOOL masked = ds_mask_size->cx && ds_mask_size->cy;
struct shader_glsl_priv *priv = This->shader_priv;
- GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
+ GLhandleARB *blt_program;
+ GLint loc;
- if (!*blt_program) {
- GLint loc;
- *blt_program = create_glsl_blt_shader(gl_info, tex_type);
+ blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type];
+ if (!*blt_program)
+ {
+ *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked);
loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler"));
GL_EXTCALL(glUseProgramObjectARB(*blt_program));
GL_EXTCALL(glUniform1iARB(loc, 0));
- } else {
+ }
+ else
+ {
GL_EXTCALL(glUseProgramObjectARB(*blt_program));
}
+
+ if (masked)
+ {
+ loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask"));
+ GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy));
+ }
}
/* GL locking is done by the caller */
return;
}
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
gl_info = context->gl_info;
if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
return;
}
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
gl_info = context->gl_info;
if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
ENTER_GL();
for (i = 0; i < tex_type_count; ++i)
{
- if (priv->depth_blt_program[i])
+ if (priv->depth_blt_program_full[i])
+ {
+ GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i]));
+ }
+ if (priv->depth_blt_program_masked[i])
{
- GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i]));
+ GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i]));
}
}
LEAVE_GL();
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION stateblock->device->adapter->gl_info
-
/* GL locking for state handlers is done by the caller. */
static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
GLenum target = GL_COMBINER0_NV + stage;
GLenum output;
- IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* For GLINFO_LOCATION */
TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
DWORD mapped_stage = stateblock->device->texUnitMap[stage + 1];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
float mat[2][2];
/* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to
* map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix
* for stage + 1. Keep the nvrc tex unit mapping in mind too
*/
- if (mapped_stage < context->gl_info->limits.textures)
+ if (mapped_stage < gl_info->limits.textures)
{
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage))");
static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
{
+ pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
+
+ /* The caps below can be supported but aren't handled yet in utils.c
+ * 'd3dta_to_combiner_input', disable them until support is fixed */
+#if 0
+ if (gl_info->supported[NV_REGISTER_COMBINERS2])
+ pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT;
+#endif
+
pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_ADDSIGNED |
WINED3DTEXOPCAPS_ADDSIGNED2X |
pCaps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners);
pCaps->MaxSimultaneousTextures = gl_info->limits.textures;
-
- pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
-
- /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
-#if 0
- if (gl_info->supported[NV_REGISTER_COMBINERS2])
- pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT;
-#endif
}
static HRESULT nvrc_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
static const struct StateEntryTemplate nvrc_fragmentstate_template[] = {
{ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), nvrc_texfactor }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), nvts_texdim }, NV_TEXTURE_SHADER2 },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), nvts_texdim }, NV_TEXTURE_SHADER2 },
}
/* Not called from the vtable */
-DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) {
+static DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags)
+{
switch (dwFlags & SIZE_BITS) {
case WINEDDPCAPS_1BIT: return 2;
case WINEDDPCAPS_2BIT: return 4;
return WINED3D_OK;
}
-const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl =
+static const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl =
{
/*** IUnknown ***/
IWineD3DPaletteImpl_QueryInterface,
IWineD3DPaletteImpl_GetCaps,
IWineD3DPaletteImpl_SetEntries
};
+
+HRESULT wined3d_palette_init(IWineD3DPaletteImpl *palette, IWineD3DDeviceImpl *device,
+ DWORD flags, const PALETTEENTRY *entries, IUnknown *parent)
+{
+ HRESULT hr;
+
+ palette->lpVtbl = &IWineD3DPalette_Vtbl;
+ palette->ref = 1;
+ palette->parent = parent;
+ palette->device = device;
+ palette->Flags = flags;
+
+ palette->palNumEntries = IWineD3DPaletteImpl_Size(flags);
+ palette->hpal = CreatePalette((const LOGPALETTE *)&palette->palVersion);
+ if (!palette->hpal)
+ {
+ WARN("Failed to create palette.\n");
+ return E_FAIL;
+ }
+
+ hr = IWineD3DPalette_SetEntries((IWineD3DPalette *)palette, 0, 0, IWineD3DPaletteImpl_Size(flags), entries);
+ if (FAILED(hr))
+ {
+ WARN("Failed to set palette entries, hr %#x.\n", hr);
+ DeleteObject(palette->hpal);
+ return hr;
+ }
+
+ return WINED3D_OK;
+}
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION (*gl_info)
-static HRESULT wined3d_event_query_init(const struct wined3d_gl_info *gl_info, struct wined3d_event_query **query)
+BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info)
{
- struct wined3d_event_query *ret;
- *query = NULL;
- if (!gl_info->supported[ARB_SYNC] && !gl_info->supported[NV_FENCE]
- && !gl_info->supported[APPLE_FENCE]) return E_NOTIMPL;
-
- ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
- if (!ret)
- {
- ERR("Failed to allocate a wined3d event query structure.\n");
- return E_OUTOFMEMORY;
- }
- ret->context = NULL;
- *query = ret;
- return WINED3D_OK;
+ return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE];
}
-static void wined3d_event_query_destroy(struct wined3d_event_query *query)
+void wined3d_event_query_destroy(struct wined3d_event_query *query)
{
if (query->context) context_free_event_query(query);
HeapFree(GetProcessHeap(), 0, query);
}
-static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
{
struct wined3d_context *context;
const struct wined3d_gl_info *gl_info;
return WINED3D_EVENT_QUERY_WRONG_THREAD;
}
- context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, query->context->current_rt);
gl_info = context->gl_info;
ENTER_GL();
return ret;
}
-static void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+{
+ struct wined3d_context *context;
+ const struct wined3d_gl_info *gl_info;
+ enum wined3d_event_query_result ret;
+
+ TRACE("(%p)\n", query);
+
+ if (!query->context)
+ {
+ TRACE("Query not started\n");
+ return WINED3D_EVENT_QUERY_NOT_STARTED;
+ }
+ gl_info = query->context->gl_info;
+
+ if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC])
+ {
+ /* A glFinish does not reliably wait for draws in other contexts. The caller has
+ * to find its own way to cope with the thread switch
+ */
+ WARN("Event query finished from wrong thread\n");
+ return WINED3D_EVENT_QUERY_WRONG_THREAD;
+ }
+
+ context = context_acquire(device, query->context->current_rt);
+
+ ENTER_GL();
+ if (gl_info->supported[ARB_SYNC])
+ {
+ GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, ~(GLuint64)0));
+ checkGLcall("glClientWaitSync");
+
+ switch (gl_ret)
+ {
+ case GL_ALREADY_SIGNALED:
+ case GL_CONDITION_SATISFIED:
+ ret = WINED3D_EVENT_QUERY_OK;
+ break;
+
+ /* We don't expect a timeout for a ~584 year wait */
+ default:
+ ERR("glClientWaitSync returned %#x.\n", gl_ret);
+ ret = WINED3D_EVENT_QUERY_ERROR;
+ }
+ }
+ else if (context->gl_info->supported[APPLE_FENCE])
+ {
+ GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
+ checkGLcall("glFinishFenceAPPLE");
+ ret = WINED3D_EVENT_QUERY_OK;
+ }
+ else if (context->gl_info->supported[NV_FENCE])
+ {
+ GL_EXTCALL(glFinishFenceNV(query->object.id));
+ checkGLcall("glFinishFenceNV");
+ ret = WINED3D_EVENT_QUERY_OK;
+ }
+ else
+ {
+ ERR("Event query created without GL support\n");
+ ret = WINED3D_EVENT_QUERY_ERROR;
+ }
+ LEAVE_GL();
+
+ context_release(context);
+ return ret;
+}
+
+void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
{
context_free_event_query(query);
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
context_alloc_event_query(context, query);
}
else
{
- context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, query->context->current_rt);
}
}
else
{
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
context_alloc_event_query(context, query);
}
return S_OK;
}
- context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This->device, query->context->current_rt);
ENTER_GL();
FIXME("Wrong thread, can't restart query.\n");
context_free_occlusion_query(query);
- context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This->device, NULL);
context_alloc_occlusion_query(context, query);
}
else
{
- context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This->device, query->context->current_rt);
ENTER_GL();
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
else
{
if (query->context) context_free_occlusion_query(query);
- context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This->device, NULL);
context_alloc_occlusion_query(context, query);
}
}
else
{
- context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This->device, query->context->current_rt);
ENTER_GL();
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
WINED3DQUERYTYPE type, IUnknown *parent)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- HRESULT hr;
switch (type)
{
case WINED3DQUERYTYPE_EVENT:
TRACE("Event query.\n");
- query->lpVtbl = &IWineD3DEventQuery_Vtbl;
- hr = wined3d_event_query_init(gl_info, (struct wined3d_event_query **) &query->extendedData);
- if (hr == E_NOTIMPL)
+ if (!wined3d_event_query_supported(gl_info))
{
/* Half-Life 2 needs this query. It does not render the main
* menu correctly otherwise. Pretend to support it, faking
* lowering performance. */
FIXME("Event query: Unimplemented, but pretending to be supported.\n");
}
- else if(FAILED(hr))
+ query->lpVtbl = &IWineD3DEventQuery_Vtbl;
+ query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query));
+ if (!query->extendedData)
{
- return hr;
+ ERR("Failed to allocate event query memory.\n");
+ return E_OUTOFMEMORY;
}
break;
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type,
- IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
+ IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format_desc *format_desc,
WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
struct IWineD3DResourceClass *resource = &((IWineD3DResourceImpl *)iface)->resource;
*pParent = This->resource.parent;
return WINED3D_OK;
}
-
-void dumpResources(struct list *list) {
- IWineD3DResourceImpl *resource;
-
- 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)));
- }
-}
else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1;
else if (ins.handler_idx == WINED3DSIH_IFC) reg_maps->usesifc = 1;
else if (ins.handler_idx == WINED3DSIH_CALL) reg_maps->usescall = 1;
+ else if (ins.handler_idx == WINED3DSIH_RCP) reg_maps->usesrcp = 1;
limit = ins.src_count + (ins.predicate ? 1 : 0);
for (i = 0; i < limit; ++i)
if (ins.dst_count) fe->shader_read_dst_param(fe_data, &ptr, &dst_param, &dst_rel_addr);
/* Predication token */
- if (ins.predicate) ins.predicate = *ptr++;
+ if (ins.predicate)
+ {
+ FIXME("Predicates not implemented.\n");
+ ins.predicate = *ptr++;
+ }
/* Other source tokens */
for (i = 0; i < ins.src_count; ++i)
static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {}
static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {}
-static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
+static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) {}
static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
{
/* Set the shader caps to 0 for the none shader backend */
caps->VertexShaderVersion = 0;
+ caps->MaxVertexShaderConst = 0;
caps->PixelShaderVersion = 0;
caps->PixelShader1xMaxValue = 0.0f;
+ caps->MaxPixelShaderConst = 0;
+ caps->VSClipping = FALSE;
}
static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
}
args->color_fixup[i] = texture->resource.format_desc->color_fixup;
+ if (texture->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW)
+ args->shadow |= 1 << i;
+
/* Flag samplers that need NP2 texcoord fixup. */
if (!texture->baseTexture.pow2Matrix_identity)
{
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
-#define GLINFO_LOCATION (*context->gl_info)
-
/* GL locking for state handlers is done by the caller. */
static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
-static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- /* Used for states which are not mapped to a gl state as-is, but used somehow different,
- * e.g as a parameter for drawing, or which are unimplemented in windows d3d
- */
- if(STATE_IS_RENDER(state)) {
- WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0);
- TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]);
- } else {
- /* Shouldn't have an unknown type here */
- FIXME("%d no direct mapping to gl of state with unknown type\n", state);
- }
+ ERR("Undefined state.\n");
}
-static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_nop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- ERR("Undefined state.\n");
+ TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state));
}
static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
/* No z test without depth stencil buffers */
- if (!stateblock->device->stencilBufferTarget)
+ if (!stateblock->device->depth_stencil)
{
TRACE("No Z buffer - disabling depth test\n");
glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0];
+ IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
int srcBlend = GL_ZERO;
int dstBlend = GL_ZERO;
/* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state,
so it may need updating */
if (stateblock->renderState[WINED3DRS_COLORKEYENABLE])
- {
- const struct StateEntry *StateTable = stateblock->device->StateTable;
- StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
- }
+ stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
}
static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
- IWineD3DSurfaceImpl *surf;
-
- surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
+ IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
{
}
if (enable_ckey || context->last_was_ckey)
- {
- const struct StateEntry *StateTable = stateblock->device->StateTable;
- StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
- }
+ stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
context->last_was_ckey = enable_ckey;
if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
int blendEquation = GL_FUNC_ADD;
int blendEquationAlpha = GL_FUNC_ADD;
/* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
if (stateblock->renderState[WINED3DRS_BLENDOPALPHA]
- && !context->gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
+ && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
{
WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
return;
static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int i;
/* Note the texture color applies to all textures whereas
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
/* And now the default texture color as well */
- for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
+ for (i = 0; i < gl_info->limits.texture_stages; ++i)
{
/* Note the WINED3DRS value applies to all textures, but GL has one
* per texture, so apply it now ready to be used!
static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
GL_EXTCALL(glActiveStencilFaceEXT(face));
GLint stencilPass_ccw = GL_KEEP;
/* No stencil test without a stencil buffer. */
- if (!stateblock->device->stencilBufferTarget)
+ if (!stateblock->device->depth_stencil)
{
glDisable(GL_STENCIL_TEST);
checkGLcall("glDisable GL_STENCIL_TEST");
static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0;
+ DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0;
+ DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0;
glStencilMask(mask);
checkGLcall("glStencilMask");
static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- union {
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union
+ {
DWORD d;
float f;
} min, max;
static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- union {
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union
+ {
DWORD d;
float f;
} min, max;
static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
+ DWORD mask0 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
+ DWORD mask1 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE1];
+ DWORD mask2 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE2];
+ DWORD mask3 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE3];
TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
- Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
- Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
- Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
- Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
- glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
- Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
- Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
- Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
+ mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
+ mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
+ mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
+ mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
+ glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
+ mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
+ mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
+ mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
checkGLcall("glColorMask(...)");
- /* depends on WINED3DRS_COLORWRITEENABLE. */
- if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
- stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
- stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
- ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
- stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
- stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
- stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
+ if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
+ || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
+ {
+ FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
+ mask0, mask1, mask2, mask3);
+ FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
}
}
+static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
+{
+ GL_EXTCALL(glColorMaskIndexedEXT(index,
+ mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
+ mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
+ mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
+ mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
+}
+
+static void state_colorwrite0(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+ set_color_mask(context->gl_info, 0, stateblock->renderState[WINED3DRS_COLORWRITEENABLE]);
+}
+
+static void state_colorwrite1(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+ set_color_mask(context->gl_info, 1, stateblock->renderState[WINED3DRS_COLORWRITEENABLE1]);
+}
+
+static void state_colorwrite2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+ set_color_mask(context->gl_info, 2, stateblock->renderState[WINED3DRS_COLORWRITEENABLE2]);
+}
+
+static void state_colorwrite3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+ set_color_mask(context->gl_info, 3, stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
+}
+
static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
}
}
+static void state_zvisible(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+ if (stateblock->renderState[WINED3DRS_ZVISIBLE])
+ FIXME("WINED3DRS_ZVISIBLE not implemented.\n");
+}
+
static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
}
}
-static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
- if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
- FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
- }
-}
-
static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
- IWineD3DSurfaceImpl *surf;
-
- surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
+ IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
{
{
DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
DWORD mapped_stage = stateblock->device->texUnitMap[texUnit];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
BOOL generated;
int coordIdx;
}
if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
- if (mapped_stage >= context->gl_info->limits.textures) return;
+ if (mapped_stage >= gl_info->limits.textures) return;
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
checkGLcall("glActiveTextureARB");
}
}
-static void unloadTexCoords(const struct wined3d_context *context)
+static void unloadTexCoords(const struct wined3d_gl_info *gl_info)
{
unsigned int texture_idx;
- for (texture_idx = 0; texture_idx < context->gl_info->limits.texture_stages; ++texture_idx)
+ for (texture_idx = 0; texture_idx < gl_info->limits.texture_stages; ++texture_idx)
{
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
-static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
+static void loadTexCoords(const struct wined3d_gl_info *gl_info, IWineD3DStateBlockImpl *stateblock,
const struct wined3d_stream_info *si, GLuint *curVBO)
{
- const struct wined3d_gl_info *gl_info = context->gl_info;
const UINT *offset = stateblock->streamOffset;
unsigned int mapped_stage = 0;
unsigned int textureNo = 0;
*/
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
- unloadTexCoords(context);
- loadTexCoords(context, stateblock, &stateblock->device->strided_streams, &curVBO);
+ unloadTexCoords(gl_info);
+ loadTexCoords(gl_info, stateblock, &stateblock->device->strided_streams, &curVBO);
}
}
* while it was enabled, so re-apply them. */
for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
{
- if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
- device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply
- (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
- }
+ if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)))
+ stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
}
context->last_was_pshader = FALSE;
}
static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- static BOOL once = FALSE;
+ WINED3DVERTEXBLENDFLAGS f = stateblock->renderState[WINED3DRS_VERTEXBLEND];
+ static unsigned int once;
- switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
- case WINED3DVBF_1WEIGHTS:
- case WINED3DVBF_2WEIGHTS:
- case WINED3DVBF_3WEIGHTS:
- if(!once) {
- once = TRUE;
- /* TODO: Implement vertex blending in drawStridedSlow */
- FIXME("Vertex blending enabled, but not supported by hardware\n");
- }
- break;
+ if (f == WINED3DVBF_DISABLE) return;
- case WINED3DVBF_TWEENING:
- WARN("Tweening not supported yet\n");
- }
+ if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
+ else WARN("Vertex blend flags %#x not supported.\n", f);
}
static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ static unsigned int once;
switch(val) {
case WINED3DVBF_1WEIGHTS:
if (!stateblock->device->vertexBlendUsed)
{
unsigned int i;
- for (i = 1; i < context->gl_info->limits.blends; ++i)
+ for (i = 1; i < gl_info->limits.blends; ++i)
{
if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i))))
{
}
break;
+ case WINED3DVBF_TWEENING:
+ case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
+ if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
+ else WARN("Vertex blend flags %#x not supported.\n", val);
+ /* Fall through. */
case WINED3DVBF_DISABLE:
- case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */
glDisable(GL_VERTEX_BLEND_ARB);
checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
break;
-
- case WINED3DVBF_TWEENING:
- /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have
- * vertex weights in the vertices?
- * For now we don't report that as supported, so a warn should suffice
- */
- WARN("Tweening not supported yet\n");
- break;
}
}
/* This should match any arrays loaded in loadVertexData.
* TODO: Only load / unload arrays if we have to.
*/
-static inline void unloadVertexData(const struct wined3d_context *context)
+static inline void unloadVertexData(const struct wined3d_gl_info *gl_info)
{
- const struct wined3d_gl_info *gl_info = context->gl_info;
-
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
{
glDisableClientState(GL_WEIGHT_ARRAY_ARB);
}
- unloadTexCoords(context);
+ unloadTexCoords(gl_info);
}
-static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i)
+static inline void unload_numbered_array(struct wined3d_context *context, int i)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
GL_EXTCALL(glDisableVertexAttribArrayARB(i));
checkGLcall("glDisableVertexAttribArrayARB(reg)");
/* This should match any arrays loaded in loadNumberedArrays
* TODO: Only load / unload arrays if we have to.
*/
-static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static inline void unloadNumberedArrays(struct wined3d_context *context)
{
/* disable any attribs (this is the same for both GLSL and ARB modes) */
GLint maxAttribs = 16;
if (glGetError() != GL_NO_ERROR)
maxAttribs = 16;
for (i = 0; i < maxAttribs; ++i) {
- unload_numbered_array(stateblock, context, i);
+ unload_numbered_array(context, i);
}
}
for (i = 0; i < MAX_ATTRIBS; i++) {
if (!(stream_info->use_map & (1 << i)))
{
- if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
+ if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
continue;
}
/* Do not load instance data. It will be specified using glTexCoord by drawprim */
if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA)
{
- if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
+ if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
stateblock->device->instancedDraw = TRUE;
continue;
}
if (stream_info->elements[i].buffer_object)
{
vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
- ptr += (long) buffer_get_sysmem(vb);
+ ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info);
}
- if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
+ if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
switch (stream_info->elements[i].format_desc->format)
{
GL_EXTCALL(glVertexBlendARB(e->format_desc->component_count + 1));
- VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
- WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) ,
- sd->u.s.blendWeights.dwStride,
- sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
-
if (curVBO != e->buffer_object)
{
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
curVBO = e->buffer_object;
}
- GL_EXTCALL(glWeightPointerARB)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
- e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
+ e->format_desc->gl_vtx_format,
+ e->format_desc->gl_vtx_type,
+ e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ GL_EXTCALL(glWeightPointerARB(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
checkGLcall("glWeightPointerARB");
/* Vertex Pointers -----------------------------------------*/
if (si->use_map & (1 << WINED3D_FFP_POSITION))
{
- VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data));
-
e = &si->elements[WINED3D_FFP_POSITION];
if (curVBO != e->buffer_object)
{
*/
if (!e->buffer_object)
{
+ TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
glVertexPointer(3 /* min(e->format_desc->gl_vtx_format, 3) */, e->format_desc->gl_vtx_type, e->stride,
e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
- } else {
+ }
+ else
+ {
+ TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
+ e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
glVertexPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
}
/* Normals -------------------------------------------------*/
if (si->use_map & (1 << WINED3D_FFP_NORMAL))
{
- VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data));
-
e = &si->elements[WINED3D_FFP_NORMAL];
if (curVBO != e->buffer_object)
{
checkGLcall("glBindBufferARB");
curVBO = e->buffer_object;
}
+
+ TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
glNormalPointer(e->format_desc->gl_vtx_type, e->stride,
e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
checkGLcall("glNormalPointer(...)");
if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
{
- VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
-
e = &si->elements[WINED3D_FFP_DIFFUSE];
if (curVBO != e->buffer_object)
{
curVBO = e->buffer_object;
}
+ TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
+ e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
glColorPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
{
TRACE("setting specular colour\n");
- VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
e = &si->elements[WINED3D_FFP_SPECULAR];
if (gl_info->supported[EXT_SECONDARY_COLOR])
* vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
* 4 component secondary colors use it
*/
- GL_EXTCALL(glSecondaryColorPointerEXT)(format, type,
- e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
}
else
switch(type)
{
case GL_UNSIGNED_BYTE:
- GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE,
- e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
break;
default:
FIXME("Add 4 component specular color pointers for type %x\n", type);
/* Make sure that the right color component is dropped */
- GL_EXTCALL(glSecondaryColorPointerEXT)(3, type,
- e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+ GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
+ e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
}
}
glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
- } else {
-
- /* Missing specular color is not critical, no warnings */
- VTRACE(("Specular colour is not supported in this GL implementation\n"));
+ }
+ else
+ {
+ WARN("Specular colour is not supported in this GL implementation.\n");
}
}
else
{
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
- } else {
-
- /* Missing specular color is not critical, no warnings */
- VTRACE(("Specular colour is not supported in this GL implementation\n"));
+ }
+ else
+ {
+ WARN("Specular colour is not supported in this GL implementation.\n");
}
}
/* Texture coords -------------------------------------------*/
- loadTexCoords(context, stateblock, si, &curVBO);
+ loadTexCoords(gl_info, stateblock, si, &curVBO);
}
static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
if (context->numberedArraysLoaded && !load_numbered)
{
- unloadNumberedArrays(stateblock, context);
+ unloadNumberedArrays(context);
context->numberedArraysLoaded = FALSE;
context->numbered_array_mask = 0;
}
else if (context->namedArraysLoaded)
{
- unloadVertexData(context);
+ unloadVertexData(context->gl_info);
context->namedArraysLoaded = FALSE;
}
context->last_was_vshader = useVertexShaderFunction;
- if(updateFog) {
- device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
- }
+ if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
+
if(!useVertexShaderFunction) {
int i;
for(i = 0; i < MAX_TEXTURES; i++) {
static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0];
+ IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
UINT width, height;
WINED3DVIEWPORT vp = stateblock->viewport;
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
}
+ if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
+ shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
}
static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0];
+ IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
RECT *pRect = &stateblock->scissorRect;
UINT height;
UINT width;
static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
} else {
}
const struct StateEntryTemplate misc_state_template[] = {
- { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
- { STATE_STREAMSRC, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
{ STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
{ STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
* vshader loadings are untied from each other
*/
{ STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
- { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
+ { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
{ STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
+ { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
{ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
{ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
{ STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
{ STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
/* Samplers */
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
const struct StateEntryTemplate ffp_vertexstate_template[] = {
{ STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
- { STATE_VSHADER, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
- { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
+ { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
/* Clip planes */
{ STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
/* Transform states follow */
{ STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
{ STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
- { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
{ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
{ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
/* Fog */
{ STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE },
{ STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
{ STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
{ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
{ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
{ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
- { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
- { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
+ { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
+ { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
+
/* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
* so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
* otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
{ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
- { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_BORDERCOLOR), { STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
{0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
};
-#undef GLINFO_LOCATION
/* Context activation is done by the caller. */
static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
{
+ pCaps->PrimitiveMiscCaps = 0;
pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_ADDSIGNED |
WINED3DTEXOPCAPS_ADDSIGNED2X |
state_table[i].representative = 0;
state_table[i].apply = state_undefined;
}
+
+ start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends));
+ last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255));
+ for (i = start; i <= last; ++i)
+ {
+ state_table[i].representative = 0;
+ state_table[i].apply = state_undefined;
+ }
}
static void validate_state_table(struct StateEntry *state_table)
{
- unsigned int i;
+ static const struct
+ {
+ DWORD first;
+ DWORD last;
+ }
+ rs_holes[] =
+ {
+ { 1, 1},
+ { 3, 3},
+ { 17, 18},
+ { 21, 21},
+ { 42, 45},
+ { 61, 127},
+ {149, 150},
+ {169, 169},
+ {177, 177},
+ {196, 197},
+ { 0, 0},
+ };
+ static const DWORD simple_states[] =
+ {
+ STATE_MATERIAL,
+ STATE_VDECL,
+ STATE_STREAMSRC,
+ STATE_INDEXBUFFER,
+ STATE_VERTEXSHADERCONSTANT,
+ STATE_PIXELSHADERCONSTANT,
+ STATE_VSHADER,
+ STATE_PIXELSHADER,
+ STATE_VIEWPORT,
+ STATE_SCISSORRECT,
+ STATE_FRONTFACE,
+ };
+ unsigned int i, current;
+
+ for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
+ {
+ if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
+ {
+ if (!state_table[i].representative)
+ ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
+ }
+ else if (state_table[i].representative)
+ ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
+
+ if (i == STATE_RENDER(rs_holes[current].last)) ++current;
+ }
+
+ for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
+ {
+ if (!state_table[simple_states[i]].representative)
+ ERR("State %s (%#x) should have a representative.\n",
+ debug_d3dstate(simple_states[i]), simple_states[i]);
+ }
for (i = 0; i < STATE_HIGHEST + 1; ++i)
{
DWORD rep = state_table[i].representative;
- if (rep && !state_table[rep].representative)
+ if (rep)
{
- ERR("State %s (%#x) has invalid representative %s (%#x).\n",
- debug_d3dstate(i), i, debug_d3dstate(rep), rep);
- state_table[i].representative = 0;
+ if (state_table[rep].representative != rep)
+ {
+ ERR("State %s (%#x) has invalid representative %s (%#x).\n",
+ debug_d3dstate(i), i, debug_d3dstate(rep), rep);
+ state_table[i].representative = 0;
+ }
+
+ if (rep != i)
+ {
+ if (state_table[i].apply)
+ ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
+ }
+ else if (!state_table[i].apply)
+ {
+ ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
+ }
}
}
}
* applying later lines, but do not record anything in the state
* table
*/
- if(!cur[i].content.apply) continue;
+ if (!cur[i].content.representative) continue;
handlers = num_handlers(multistate_funcs[cur[i].state]);
multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
{
TRACE("Updating scissor rect.\n");
- targetStateBlock->scissorRect = This->scissorRect;
+ This->scissorRect = targetStateBlock->scissorRect;
}
map = This->changed.streamSource;
return WINED3D_OK;
}
-static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl *This)
+static void apply_lights(IWineD3DDevice *device, const IWineD3DStateBlockImpl *This)
{
UINT i;
for(i = 0; i < LIGHTMAP_SIZE; i++) {
{
const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry);
- IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms);
- IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1);
+ IWineD3DDevice_SetLight(device, light->OriginalIndex, &light->OriginalParms);
+ IWineD3DDevice_SetLightEnable(device, light->OriginalIndex, light->glIndex != -1);
}
}
}
static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface)
{
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
- IWineD3DDevice *pDevice = (IWineD3DDevice *)This->device;
+ IWineD3DDevice *device = (IWineD3DDevice *)This->device;
unsigned int i;
DWORD map;
- TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
+ TRACE("(%p) : Applying state block %p ------------------v\n", This, device);
TRACE("Blocktype: %d\n", This->blockType);
- if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
+ if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(device, This->vertexShader);
/* Vertex Shader Constants */
for (i = 0; i < This->num_contained_vs_consts_f; ++i)
{
- IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i],
+ IWineD3DDevice_SetVertexShaderConstantF(device, This->contained_vs_consts_f[i],
This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1);
}
for (i = 0; i < This->num_contained_vs_consts_i; ++i)
{
- IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i],
+ IWineD3DDevice_SetVertexShaderConstantI(device, This->contained_vs_consts_i[i],
This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1);
}
for (i = 0; i < This->num_contained_vs_consts_b; ++i)
{
- IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i],
+ IWineD3DDevice_SetVertexShaderConstantB(device, This->contained_vs_consts_b[i],
This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1);
}
- apply_lights(pDevice, This);
+ apply_lights(device, This);
- if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
+ if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(device, This->pixelShader);
/* Pixel Shader Constants */
for (i = 0; i < This->num_contained_ps_consts_f; ++i)
{
- IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i],
+ IWineD3DDevice_SetPixelShaderConstantF(device, This->contained_ps_consts_f[i],
This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1);
}
for (i = 0; i < This->num_contained_ps_consts_i; ++i)
{
- IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i],
+ IWineD3DDevice_SetPixelShaderConstantI(device, This->contained_ps_consts_i[i],
This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1);
}
for (i = 0; i < This->num_contained_ps_consts_b; ++i)
{
- IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i],
+ IWineD3DDevice_SetPixelShaderConstantB(device, This->contained_ps_consts_b[i],
This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1);
}
/* Render */
for (i = 0; i < This->num_contained_render_states; ++i)
{
- IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i],
+ IWineD3DDevice_SetRenderState(device, This->contained_render_states[i],
This->renderState[This->contained_render_states[i]]);
}
DWORD stage = This->contained_tss_states[i].stage;
DWORD state = This->contained_tss_states[i].state;
- IWineD3DDevice_SetTextureStageState(pDevice, stage, state, This->textureState[stage][state]);
+ IWineD3DDevice_SetTextureStageState(device, stage, state, This->textureState[stage][state]);
}
/* Sampler states */
DWORD value = This->samplerState[stage][state];
if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS;
- IWineD3DDevice_SetSamplerState(pDevice, stage, state, value);
+ IWineD3DDevice_SetSamplerState(device, stage, state, value);
}
for (i = 0; i < This->num_contained_transform_states; ++i)
{
- IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i],
+ IWineD3DDevice_SetTransform(device, This->contained_transform_states[i],
&This->transforms[This->contained_transform_states[i]]);
}
if (This->changed.indices)
{
- IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt);
- IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
+ IWineD3DDevice_SetIndexBuffer(device, This->pIndexData, This->IndexFmt);
+ IWineD3DDevice_SetBaseVertexIndex(device, This->baseVertexIndex);
}
if (This->changed.vertexDecl && This->vertexDecl)
{
- IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
+ IWineD3DDevice_SetVertexDeclaration(device, This->vertexDecl);
}
if (This->changed.material)
{
- IWineD3DDevice_SetMaterial(pDevice, &This->material);
+ IWineD3DDevice_SetMaterial(device, &This->material);
}
if (This->changed.viewport)
{
- IWineD3DDevice_SetViewport(pDevice, &This->viewport);
+ IWineD3DDevice_SetViewport(device, &This->viewport);
}
if (This->changed.scissorRect)
{
- IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);
+ IWineD3DDevice_SetScissorRect(device, &This->scissorRect);
}
map = This->changed.streamSource;
for (i = 0; map; map >>= 1, ++i)
{
- if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
+ if (map & 1) IWineD3DDevice_SetStreamSource(device, i, This->streamSource[i], 0, This->streamStride[i]);
}
map = This->changed.streamFreq;
for (i = 0; map; map >>= 1, ++i)
{
- if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
+ if (map & 1) IWineD3DDevice_SetStreamSourceFreq(device, i, This->streamFreq[i] | This->streamFlags[i]);
}
map = This->changed.textures;
if (!(map & 1)) continue;
stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS;
- IWineD3DDevice_SetTexture(pDevice, stage, This->textures[i]);
+ IWineD3DDevice_SetTexture(device, stage, This->textures[i]);
}
map = This->changed.clipplane;
clip[1] = This->clipplane[i][1];
clip[2] = This->clipplane[i][2];
clip[3] = This->clipplane[i][3];
- IWineD3DDevice_SetClipPlane(pDevice, i, clip);
+ IWineD3DDevice_SetClipPlane(device, i, clip);
}
This->device->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1;
break;
}
}
- TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);
+ TRACE("(%p) : Applied state block %p ------------------^\n", This, device);
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
IWineD3DDevice *device = (IWineD3DDevice *)This->device;
- IWineD3DDeviceImpl *ThisDevice = (IWineD3DDeviceImpl *)device;
- const struct wined3d_gl_info *gl_info = &ThisDevice->adapter->gl_info;
+ IWineD3DDeviceImpl *device_impl = (IWineD3DDeviceImpl *)device;
+ const struct wined3d_gl_info *gl_info = &device_impl->adapter->gl_info;
union {
WINED3DLINEPATTERN lp;
DWORD d;
/* Note this may have a large overhead but it should only be executed
once, in order to initialize the complete state of the device and
all opengl equivalents */
- TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, ThisDevice);
+ TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, device);
/* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */
This->blockType = WINED3DSBT_INIT;
TRACE("Render states\n");
/* Render states: */
- if (ThisDevice->auto_depth_stencil_buffer != NULL) {
+ if (device_impl->auto_depth_stencil)
IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_TRUE);
- } else {
+ else
IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_FALSE);
- }
IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE, WINED3DFILL_SOLID);
IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE, WINED3DSHADE_GOURAUD);
lp.lp.wRepeatFactor = 0;
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION (*gl_info)
-
static void surface_cleanup(IWineD3DSurfaceImpl *This)
{
IWineD3DDeviceImpl *device = This->resource.device;
* target, Uninit3D() will activate a context before doing anything. */
if (device->render_targets && device->render_targets[0])
{
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
}
ENTER_GL();
if (context) context_release(context);
}
-UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT alignment, UINT width, UINT height)
+UINT surface_calculate_size(const struct wined3d_format_desc *format_desc, UINT alignment, UINT width, UINT height)
{
UINT size;
return size;
}
+struct blt_info
+{
+ GLenum binding;
+ GLenum bind_target;
+ enum tex_types tex_type;
+ GLfloat coords[4][3];
+};
+
+struct float_rect
+{
+ float l;
+ float t;
+ float r;
+ float b;
+};
+
+static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f)
+{
+ f->l = ((r->left * 2.0f) / w) - 1.0f;
+ f->t = ((r->top * 2.0f) / h) - 1.0f;
+ f->r = ((r->right * 2.0f) / w) - 1.0f;
+ f->b = ((r->bottom * 2.0f) / h) - 1.0f;
+}
+
+static void surface_get_blt_info(GLenum target, const RECT *rect_in, GLsizei w, GLsizei h, struct blt_info *info)
+{
+ GLfloat (*coords)[3] = info->coords;
+ RECT rect;
+ struct float_rect f;
+
+ if (rect_in)
+ rect = *rect_in;
+ else
+ {
+ rect.left = 0;
+ rect.top = h;
+ rect.right = w;
+ rect.bottom = 0;
+ }
+
+ switch (target)
+ {
+ default:
+ FIXME("Unsupported texture target %#x\n", target);
+ /* Fall back to GL_TEXTURE_2D */
+ case GL_TEXTURE_2D:
+ info->binding = GL_TEXTURE_BINDING_2D;
+ info->bind_target = GL_TEXTURE_2D;
+ info->tex_type = tex_2d;
+ coords[0][0] = (float)rect.left / w;
+ coords[0][1] = (float)rect.top / h;
+ coords[0][2] = 0.0f;
+
+ coords[1][0] = (float)rect.right / w;
+ coords[1][1] = (float)rect.top / h;
+ coords[1][2] = 0.0f;
+
+ coords[2][0] = (float)rect.left / w;
+ coords[2][1] = (float)rect.bottom / h;
+ coords[2][2] = 0.0f;
+
+ coords[3][0] = (float)rect.right / w;
+ coords[3][1] = (float)rect.bottom / h;
+ coords[3][2] = 0.0f;
+ break;
+
+ case GL_TEXTURE_RECTANGLE_ARB:
+ info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
+ info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
+ info->tex_type = tex_rect;
+ coords[0][0] = rect.left; coords[0][1] = rect.top; coords[0][2] = 0.0f;
+ coords[1][0] = rect.right; coords[1][1] = rect.top; coords[1][2] = 0.0f;
+ coords[2][0] = rect.left; coords[2][1] = rect.bottom; coords[2][2] = 0.0f;
+ coords[3][0] = rect.right; coords[3][1] = rect.bottom; coords[3][2] = 0.0f;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(&rect, w, h, &f);
+
+ coords[0][0] = 1.0f; coords[0][1] = -f.t; coords[0][2] = -f.l;
+ coords[1][0] = 1.0f; coords[1][1] = -f.t; coords[1][2] = -f.r;
+ coords[2][0] = 1.0f; coords[2][1] = -f.b; coords[2][2] = -f.l;
+ coords[3][0] = 1.0f; coords[3][1] = -f.b; coords[3][2] = -f.r;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(&rect, w, h, &f);
+
+ coords[0][0] = -1.0f; coords[0][1] = -f.t; coords[0][2] = f.l;
+ coords[1][0] = -1.0f; coords[1][1] = -f.t; coords[1][2] = f.r;
+ coords[2][0] = -1.0f; coords[2][1] = -f.b; coords[2][2] = f.l;
+ coords[3][0] = -1.0f; coords[3][1] = -f.b; coords[3][2] = f.r;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(&rect, w, h, &f);
+
+ coords[0][0] = f.l; coords[0][1] = 1.0f; coords[0][2] = f.t;
+ coords[1][0] = f.r; coords[1][1] = 1.0f; coords[1][2] = f.t;
+ coords[2][0] = f.l; coords[2][1] = 1.0f; coords[2][2] = f.b;
+ coords[3][0] = f.r; coords[3][1] = 1.0f; coords[3][2] = f.b;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(&rect, w, h, &f);
+
+ coords[0][0] = f.l; coords[0][1] = -1.0f; coords[0][2] = -f.t;
+ coords[1][0] = f.r; coords[1][1] = -1.0f; coords[1][2] = -f.t;
+ coords[2][0] = f.l; coords[2][1] = -1.0f; coords[2][2] = -f.b;
+ coords[3][0] = f.r; coords[3][1] = -1.0f; coords[3][2] = -f.b;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(&rect, w, h, &f);
+
+ coords[0][0] = f.l; coords[0][1] = -f.t; coords[0][2] = 1.0f;
+ coords[1][0] = f.r; coords[1][1] = -f.t; coords[1][2] = 1.0f;
+ coords[2][0] = f.l; coords[2][1] = -f.b; coords[2][2] = 1.0f;
+ coords[3][0] = f.r; coords[3][1] = -f.b; coords[3][2] = 1.0f;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(&rect, w, h, &f);
+
+ coords[0][0] = -f.l; coords[0][1] = -f.t; coords[0][2] = -1.0f;
+ coords[1][0] = -f.r; coords[1][1] = -f.t; coords[1][2] = -1.0f;
+ coords[2][0] = -f.l; coords[2][1] = -f.b; coords[2][2] = -1.0f;
+ coords[3][0] = -f.r; coords[3][1] = -f.b; coords[3][2] = -1.0f;
+ break;
+ }
+}
+
+static inline void surface_get_rect(IWineD3DSurfaceImpl *This, const RECT *rect_in, RECT *rect_out)
+{
+ if (rect_in)
+ *rect_out = *rect_in;
+ else
+ {
+ rect_out->left = 0;
+ rect_out->top = 0;
+ rect_out->right = This->currentDesc.Width;
+ rect_out->bottom = This->currentDesc.Height;
+ }
+}
+
+/* GL locking and context activation is done by the caller */
+void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter)
+{
+ IWineD3DBaseTextureImpl *texture;
+ struct blt_info info;
+
+ surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info);
+
+ glEnable(info.bind_target);
+ checkGLcall("glEnable(bind_target)");
+
+ /* Bind the texture */
+ glBindTexture(info.bind_target, src_surface->texture_name);
+ checkGLcall("glBindTexture");
+
+ /* Filtering for StretchRect */
+ glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER,
+ wined3d_gl_mag_filter(magLookup, Filter));
+ checkGLcall("glTexParameteri");
+ glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER,
+ wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
+ checkGLcall("glTexParameteri");
+ glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ checkGLcall("glTexEnvi");
+
+ /* Draw a quad */
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord3fv(info.coords[0]);
+ glVertex2i(dst_rect->left, dst_rect->top);
+
+ glTexCoord3fv(info.coords[1]);
+ glVertex2i(dst_rect->right, dst_rect->top);
+
+ glTexCoord3fv(info.coords[2]);
+ glVertex2i(dst_rect->left, dst_rect->bottom);
+
+ glTexCoord3fv(info.coords[3]);
+ glVertex2i(dst_rect->right, dst_rect->bottom);
+ glEnd();
+
+ /* Unbind the texture */
+ glBindTexture(info.bind_target, 0);
+ checkGLcall("glBindTexture(info->bind_target, 0)");
+
+ /* We changed the filtering settings on the texture. Inform the
+ * container about this to get the filters reset properly next draw. */
+ if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DBaseTexture, (void **)&texture)))
+ {
+ texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
+ texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
+ texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
+ IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture);
+ }
+}
+
HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info);
void (*cleanup)(IWineD3DSurfaceImpl *This);
unsigned int resource_size;
HRESULT hr;
}
/* Mark the texture as dirty so that it gets loaded first time around. */
- surface_add_dirty_rect((IWineD3DSurface *)surface, NULL);
+ surface_add_dirty_rect(surface, NULL);
list_init(&surface->renderbuffers);
TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size);
return hr;
}
-static void surface_force_reload(IWineD3DSurface *iface)
+static void surface_force_reload(IWineD3DSurfaceImpl *surface)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-
- This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
+ surface->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
}
-void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb)
+void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint new_name, BOOL srgb)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
GLuint *name;
DWORD flag;
+ TRACE("surface %p, new_name %u, srgb %#x.\n", surface, new_name, srgb);
+
if(srgb)
{
- name = &This->texture_name_srgb;
+ name = &surface->texture_name_srgb;
flag = SFLAG_INSRGBTEX;
}
else
{
- name = &This->texture_name;
+ name = &surface->texture_name;
flag = SFLAG_INTEXTURE;
}
- TRACE("(%p) : setting texture name %u\n", This, new_name);
-
if (!*name && new_name)
{
/* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the
* surface has no texture name yet. See if we can get rid of this. */
- if (This->Flags & flag)
+ if (surface->Flags & flag)
ERR("Surface has SFLAG_INTEXTURE set, but no texture name\n");
- IWineD3DSurface_ModifyLocation(iface, flag, FALSE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, flag, FALSE);
}
*name = new_name;
- surface_force_reload(iface);
+ surface_force_reload(surface);
}
-void surface_set_texture_target(IWineD3DSurface *iface, GLenum target)
+void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+ TRACE("surface %p, target %#x.\n", surface, target);
- TRACE("(%p) : setting target %#x\n", This, target);
-
- if (This->texture_target != target)
+ if (surface->texture_target != target)
{
if (target == GL_TEXTURE_RECTANGLE_ARB)
{
- This->Flags &= ~SFLAG_NORMCOORD;
+ surface->Flags &= ~SFLAG_NORMCOORD;
}
- else if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ else if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB)
{
- This->Flags |= SFLAG_NORMCOORD;
+ surface->Flags |= SFLAG_NORMCOORD;
}
}
- This->texture_target = target;
- surface_force_reload(iface);
+ surface->texture_target = target;
+ surface_force_reload(surface);
}
/* Context activation is done by the caller. */
/* This function checks if the primary render target uses the 8bit paletted format. */
static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
{
- if (device->render_targets && device->render_targets[0]) {
- IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0];
+ if (device->render_targets && device->render_targets[0])
+ {
+ IWineD3DSurfaceImpl *render_target = device->render_targets[0];
if ((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET)
&& (render_target->resource.format_desc->format == WINED3DFMT_P8_UINT))
return TRUE;
return FALSE;
}
-#undef GLINFO_LOCATION
-
-#define GLINFO_LOCATION This->resource.device->adapter->gl_info
-
/* This call just downloads data, the caller is responsible for binding the
* correct texture. */
/* Context activation is done by the caller. */
-static void surface_download_data(IWineD3DSurfaceImpl *This) {
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+static void surface_download_data(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info)
+{
+ const struct wined3d_format_desc *format_desc = This->resource.format_desc;
/* Only support read back of converted P8 surfaces */
if (This->Flags & SFLAG_CONVERTED && format_desc->format != WINED3DFMT_P8_UINT)
/* This call just uploads data, the caller is responsible for binding the
* correct texture. */
/* Context activation is done by the caller. */
-static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) {
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+static void surface_upload_data(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_format_desc *format_desc, BOOL srgb, const GLvoid *data)
+{
+ GLsizei width = This->currentDesc.Width;
+ GLsizei height = This->currentDesc.Height;
+ GLenum internal;
+
+ if (srgb)
+ {
+ internal = format_desc->glGammaInternal;
+ }
+ else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(This))
+ {
+ internal = format_desc->rtInternal;
+ }
+ else
+ {
+ internal = format_desc->glInternal;
+ }
TRACE("This %p, internal %#x, width %d, height %d, format %#x, type %#x, data %p.\n",
- This, internal, width, height, format, type, data);
+ This, internal, width, height, format_desc->glFormat, format_desc->glType, data);
TRACE("target %#x, level %u, resource size %u.\n",
This->texture_target, This->texture_level, This->resource.size);
TRACE("Calling glTexSubImage2D.\n");
glTexSubImage2D(This->texture_target, This->texture_level,
- 0, 0, width, height, format, type, data);
+ 0, 0, width, height, format_desc->glFormat, format_desc->glType, data);
checkGLcall("glTexSubImage2D");
}
}
LEAVE_GL();
+
+ if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE)
+ {
+ IWineD3DDeviceImpl *device = This->resource.device;
+ unsigned int i;
+
+ for (i = 0; i < device->numContexts; ++i)
+ {
+ context_surface_update(device->contexts[i], This);
+ }
+ }
}
/* This call just allocates the texture, the caller is responsible for binding
* the correct texture. */
/* Context activation is done by the caller. */
-static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) {
- const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+static void surface_allocate_surface(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_format_desc *format_desc, BOOL srgb)
+{
BOOL enable_client_storage = FALSE;
+ GLsizei width = This->pow2Width;
+ GLsizei height = This->pow2Height;
const BYTE *mem = NULL;
+ GLenum internal;
+
+ if (srgb)
+ {
+ internal = format_desc->glGammaInternal;
+ }
+ else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(This))
+ {
+ internal = format_desc->rtInternal;
+ }
+ else
+ {
+ internal = format_desc->glInternal;
+ }
if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
TRACE("(%p) : Creating surface (target %#x) level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
This, This->texture_target, This->texture_level, debug_d3dformat(format_desc->format),
- internal, width, height, format, type);
+ internal, width, height, format_desc->glFormat, format_desc->glType);
ENTER_GL();
if (gl_info->supported[APPLE_CLIENT_STORAGE])
{
- if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_OVERSIZE | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) {
+ if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) {
/* In some cases we want to disable client storage.
* SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
* SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
- * SFLAG_OVERSIZE: The gl texture is smaller than the allocated memory
* SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface
* allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively
*/
else
{
glTexImage2D(This->texture_target, This->texture_level,
- internal, width, height, 0, format, type, mem);
+ internal, width, height, 0, format_desc->glFormat, format_desc->glType, mem);
checkGLcall("glTexImage2D");
}
* render target dimensions. With FBOs, the dimensions have to be an exact match. */
/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
/* GL locking is done by the caller */
-void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) {
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
+void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height)
+{
+ const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
renderbuffer_entry_t *entry;
GLuint renderbuffer = 0;
unsigned int src_width, src_height;
- src_width = This->pow2Width;
- src_height = This->pow2Height;
+ src_width = surface->pow2Width;
+ src_height = surface->pow2Height;
/* A depth stencil smaller than the render target is not valid */
if (width > src_width || height > src_height) return;
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
|| (width == src_width && height == src_height))
{
- This->current_renderbuffer = NULL;
+ surface->current_renderbuffer = NULL;
return;
}
/* Look if we've already got a renderbuffer of the correct dimensions */
- LIST_FOR_EACH_ENTRY(entry, &This->renderbuffers, renderbuffer_entry_t, entry) {
- if (entry->width == width && entry->height == height) {
+ LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, renderbuffer_entry_t, entry)
+ {
+ if (entry->width == width && entry->height == height)
+ {
renderbuffer = entry->id;
- This->current_renderbuffer = entry;
+ surface->current_renderbuffer = entry;
break;
}
}
- if (!renderbuffer) {
+ if (!renderbuffer)
+ {
gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
- This->resource.format_desc->glInternal, width, height);
+ surface->resource.format_desc->glInternal, width, height);
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(renderbuffer_entry_t));
entry->width = width;
entry->height = height;
entry->id = renderbuffer;
- list_add_head(&This->renderbuffers, &entry->entry);
+ list_add_head(&surface->renderbuffers, &entry->entry);
- This->current_renderbuffer = entry;
+ surface->current_renderbuffer = entry;
}
checkGLcall("set_compatible_renderbuffer");
}
-GLenum surface_get_gl_buffer(IWineD3DSurface *iface)
+GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->container;
+ IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container;
- TRACE("iface %p.\n", iface);
+ TRACE("surface %p.\n", surface);
- if (!(This->Flags & SFLAG_SWAPCHAIN))
+ if (!(surface->Flags & SFLAG_SWAPCHAIN))
{
- ERR("Surface %p is not on a swapchain.\n", iface);
+ ERR("Surface %p is not on a swapchain.\n", surface);
return GL_NONE;
}
- if (swapchain->backBuffer && swapchain->backBuffer[0] == iface)
+ if (swapchain->back_buffers && swapchain->back_buffers[0] == surface)
{
if (swapchain->render_to_fbo)
{
TRACE("Returning GL_BACK\n");
return GL_BACK;
}
- else if (swapchain->frontBuffer == iface)
+ else if (surface == swapchain->front_buffer)
{
TRACE("Returning GL_FRONT\n");
return GL_FRONT;
}
/* Slightly inefficient way to handle multiple dirty rects but it works :) */
-void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect)
+void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DBaseTexture *baseTexture = NULL;
- if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE))
- IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */);
+ TRACE("surface %p, dirty_rect %s.\n", surface, wine_dbgstr_rect(dirty_rect));
+
+ if (!(surface->Flags & SFLAG_INSYSMEM) && (surface->Flags & SFLAG_INTEXTURE))
+ /* No partial locking for textures yet. */
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL);
- IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, TRUE);
if (dirty_rect)
{
- This->dirtyRect.left = min(This->dirtyRect.left, dirty_rect->left);
- This->dirtyRect.top = min(This->dirtyRect.top, dirty_rect->top);
- This->dirtyRect.right = max(This->dirtyRect.right, dirty_rect->right);
- This->dirtyRect.bottom = max(This->dirtyRect.bottom, dirty_rect->bottom);
+ surface->dirtyRect.left = min(surface->dirtyRect.left, dirty_rect->left);
+ surface->dirtyRect.top = min(surface->dirtyRect.top, dirty_rect->top);
+ surface->dirtyRect.right = max(surface->dirtyRect.right, dirty_rect->right);
+ surface->dirtyRect.bottom = max(surface->dirtyRect.bottom, dirty_rect->bottom);
}
else
{
- This->dirtyRect.left = 0;
- This->dirtyRect.top = 0;
- This->dirtyRect.right = This->currentDesc.Width;
- This->dirtyRect.bottom = This->currentDesc.Height;
+ surface->dirtyRect.left = 0;
+ surface->dirtyRect.top = 0;
+ surface->dirtyRect.right = surface->currentDesc.Width;
+ surface->dirtyRect.bottom = surface->currentDesc.Height;
}
- TRACE("(%p) : Dirty: yes, Rect:(%d, %d, %d, %d)\n", This, This->dirtyRect.left,
- This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
-
/* if the container is a basetexture then mark it dirty. */
- if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
+ if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
+ &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
{
TRACE("Passing to container\n");
IWineD3DBaseTexture_SetDirty(baseTexture, TRUE);
}
}
-static inline BOOL surface_can_stretch_rect(IWineD3DSurfaceImpl *src, IWineD3DSurfaceImpl *dst)
+static BOOL surface_convert_color_to_argb(IWineD3DSurfaceImpl *This, DWORD color, DWORD *argb_color)
{
- return ((src->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
- || (src->resource.usage & WINED3DUSAGE_RENDERTARGET))
- && ((dst->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
- || (dst->resource.usage & WINED3DUSAGE_RENDERTARGET))
- && (src->resource.format_desc->format == dst->resource.format_desc->format
- || (is_identity_fixup(src->resource.format_desc->color_fixup)
- && is_identity_fixup(dst->resource.format_desc->color_fixup)));
+ IWineD3DDeviceImpl *device = This->resource.device;
+
+ switch(This->resource.format_desc->format)
+ {
+ case WINED3DFMT_P8_UINT:
+ {
+ DWORD alpha;
+
+ if (primary_render_target_is_p8(device))
+ alpha = color << 24;
+ else
+ alpha = 0xFF000000;
+
+ if (This->palette) {
+ *argb_color = (alpha |
+ (This->palette->palents[color].peRed << 16) |
+ (This->palette->palents[color].peGreen << 8) |
+ (This->palette->palents[color].peBlue));
+ } else {
+ *argb_color = alpha;
+ }
+ }
+ break;
+
+ case WINED3DFMT_B5G6R5_UNORM:
+ {
+ if (color == 0xFFFF) {
+ *argb_color = 0xFFFFFFFF;
+ } else {
+ *argb_color = ((0xFF000000) |
+ ((color & 0xF800) << 8) |
+ ((color & 0x07E0) << 5) |
+ ((color & 0x001F) << 3));
+ }
+ }
+ break;
+
+ case WINED3DFMT_B8G8R8_UNORM:
+ case WINED3DFMT_B8G8R8X8_UNORM:
+ *argb_color = 0xFF000000 | color;
+ break;
+
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ *argb_color = color;
+ break;
+
+ default:
+ ERR("Unhandled conversion from %s to ARGB!\n", debug_d3dformat(This->resource.format_desc->format));
+ return FALSE;
+ }
+ return TRUE;
}
static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
IWineD3DSurface IWineD3DResource parts follow
**************************************************** */
-void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb)
+void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb)
{
/* TODO: check for locks */
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- IWineD3DDeviceImpl *device = This->resource.device;
+ IWineD3DDeviceImpl *device = surface->resource.device;
IWineD3DBaseTexture *baseTexture = NULL;
- TRACE("(%p)Checking to see if the container is a base texture\n", This);
- if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
- IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture;
+ TRACE("(%p)Checking to see if the container is a base texture\n", surface);
+ if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
+ &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
+ {
+ IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *)baseTexture;
TRACE("Passing to container\n");
tex_impl->baseTexture.internal_preload(baseTexture, srgb);
IWineD3DBaseTexture_Release(baseTexture);
} else {
struct wined3d_context *context = NULL;
- TRACE("(%p) : About to load surface\n", This);
+ TRACE("(%p) : About to load surface\n", surface);
- if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ if (!device->isInDraw) context = context_acquire(device, NULL);
- if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
- || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
+ if (surface->resource.format_desc->format == WINED3DFMT_P8_UINT
+ || surface->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
{
- if(palette9_changed(This)) {
+ if (palette9_changed(surface))
+ {
TRACE("Reloading surface because the d3d8/9 palette was changed\n");
/* TODO: This is not necessarily needed with hw palettized texture support */
- IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL);
/* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
- IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE);
}
}
- IWineD3DSurface_LoadTexture(iface, srgb == SRGB_SRGB ? TRUE : FALSE);
+ IWineD3DSurface_LoadTexture((IWineD3DSurface *)surface, srgb == SRGB_SRGB ? TRUE : FALSE);
- if (This->resource.pool == WINED3DPOOL_DEFAULT) {
+ if (surface->resource.pool == WINED3DPOOL_DEFAULT)
+ {
/* Tell opengl to try and keep this texture in video ram (well mostly) */
GLclampf tmp;
tmp = 0.9f;
ENTER_GL();
- glPrioritizeTextures(1, &This->texture_name, &tmp);
+ glPrioritizeTextures(1, &surface->texture_name, &tmp);
LEAVE_GL();
}
}
}
-static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
- surface_internal_preload(iface, SRGB_ANY);
+static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface)
+{
+ surface_internal_preload((IWineD3DSurfaceImpl *)iface, SRGB_ANY);
}
/* Context activation is done by the caller. */
-static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
+static void surface_remove_pbo(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info)
+{
This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
This->resource.allocatedMemory =
(BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
This->Flags &= ~SFLAG_PBO;
}
-BOOL surface_init_sysmem(IWineD3DSurface *iface)
+BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
-
- if(!This->resource.allocatedMemory)
+ if (!surface->resource.allocatedMemory)
{
- This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
- if(!This->resource.heapMemory)
+ surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ surface->resource.size + RESOURCE_ALIGNMENT);
+ if (!surface->resource.heapMemory)
{
ERR("Out of memory\n");
return FALSE;
}
- This->resource.allocatedMemory =
- (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ surface->resource.allocatedMemory =
+ (BYTE *)(((ULONG_PTR)surface->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
}
else
{
- memset(This->resource.allocatedMemory, 0, This->resource.size);
+ memset(surface->resource.allocatedMemory, 0, surface->resource.size);
}
- IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, TRUE);
return TRUE;
}
* or the depth stencil into an FBO the texture or render buffer will be removed
* and all flags get lost
*/
- surface_init_sysmem(iface);
- } else {
+ surface_init_sysmem(This);
+ }
+ else
+ {
/* Load the surface into system memory */
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE);
This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
gl_info = context->gl_info;
/* Destroy PBOs, but load them into real sysmem before */
- if(This->Flags & SFLAG_PBO) {
- surface_remove_pbo(This);
- }
+ if (This->Flags & SFLAG_PBO)
+ surface_remove_pbo(This, gl_info);
/* Destroy fbo render buffers. This is needed for implicit render targets, for
* all application-created targets the application has to release the surface
/* Read the framebuffer back into the surface */
static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, void *dest, UINT pitch)
{
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
BYTE *mem;
GLint fmt;
* should help here. Furthermore unlockrect will need the context set up for blitting. The context manager will find
* context->last_was_blit set on the unlock.
*/
- context = context_acquire(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
+ context = context_acquire(device, This);
+ context_apply_blit_state(context, device);
+ gl_info = context->gl_info;
+
ENTER_GL();
/* Select the correct read buffer, and give some debug output.
* There is no need to keep track of the current read buffer or reset it, every part of the code
* that reads sets the read buffer as desired.
*/
- if (surface_is_offscreen((IWineD3DSurface *) This))
+ if (surface_is_offscreen(This))
{
/* Locking the primary render target which is not on a swapchain(=offscreen render target).
* Read from the back buffer
*/
TRACE("Locking offscreen render target\n");
- glReadBuffer(myDevice->offscreenBuffer);
+ glReadBuffer(device->offscreenBuffer);
srcIsUpsideDown = TRUE;
}
else
{
/* Onscreen surfaces are always part of a swapchain */
- GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This);
+ GLenum buffer = surface_get_gl_buffer(This);
TRACE("Locking %#x buffer\n", buffer);
glReadBuffer(buffer);
checkGLcall("glReadBuffer");
{
case WINED3DFMT_P8_UINT:
{
- if(primary_render_target_is_p8(myDevice)) {
+ if (primary_render_target_is_p8(device))
+ {
/* In case of P8 render targets the index is stored in the alpha component */
fmt = GL_ALPHA;
type = GL_UNSIGNED_BYTE;
* the same color but we have no choice.
* In case of P8 render targets, the index is stored in the alpha component so no conversion is needed.
*/
- if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(myDevice))
+ if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(device))
{
const PALETTEENTRY *pal = NULL;
DWORD width = pitch / 3;
static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb)
{
IWineD3DDeviceImpl *device = This->resource.device;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
- int bpp;
- GLenum format, internal, type;
- CONVERT_TYPES convert;
GLint prevRead;
- BOOL alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
-
- d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb);
/* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer
* locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any
* states in the stateblock, and no driver was found yet that had bugs in that regard.
*/
- context = context_acquire(device, (IWineD3DSurface *) This, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, This);
+ gl_info = context->gl_info;
+
+ surface_prepare_texture(This, gl_info, srgb);
surface_bind_and_dirtify(This, srgb);
ENTER_GL();
* There is no need to keep track of the current read buffer or reset it, every part of the code
* that reads sets the read buffer as desired.
*/
- if (!surface_is_offscreen((IWineD3DSurface *)This))
+ if (!surface_is_offscreen(This))
{
- GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This);
+ GLenum buffer = surface_get_gl_buffer(This);
TRACE("Locking %#x buffer\n", buffer);
ENTER_GL();
LEAVE_GL();
}
- if(!(This->Flags & alloc_flag)) {
- surface_allocate_surface(This, internal, This->pow2Width,
- This->pow2Height, format, type);
- This->Flags |= alloc_flag;
- }
-
ENTER_GL();
/* If !SrcIsUpsideDown we should flip the surface.
* This can be done using glCopyTexSubImage2D but this
}
/* Context activation is done by the caller. */
-void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb)
+static void surface_prepare_texture_internal(IWineD3DSurfaceImpl *surface,
+ const struct wined3d_gl_info *gl_info, BOOL srgb)
{
DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
- GLenum format, internal, type;
- GLsizei width, height;
CONVERT_TYPES convert;
- int bpp;
+ struct wined3d_format_desc desc;
if (surface->Flags & alloc_flag) return;
- d3dfmt_get_conv(surface, TRUE, TRUE, &format, &internal, &type, &convert, &bpp, srgb);
- if(convert != NO_CONVERSION) surface->Flags |= SFLAG_CONVERTED;
+ d3dfmt_get_conv(surface, TRUE, TRUE, &desc, &convert);
+ if(convert != NO_CONVERSION || desc.convert) surface->Flags |= SFLAG_CONVERTED;
else surface->Flags &= ~SFLAG_CONVERTED;
- if ((surface->Flags & SFLAG_NONPOW2) && !(surface->Flags & SFLAG_OVERSIZE))
- {
- width = surface->pow2Width;
- height = surface->pow2Height;
- }
- else
+ surface_bind_and_dirtify(surface, srgb);
+ surface_allocate_surface(surface, gl_info, &desc, srgb);
+ surface->Flags |= alloc_flag;
+}
+
+/* Context activation is done by the caller. */
+void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info, BOOL srgb)
+{
+ IWineD3DBaseTextureImpl *texture;
+
+ if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
+ &IID_IWineD3DBaseTexture, (void **)&texture)))
{
- width = surface->glRect.right - surface->glRect.left;
- height = surface->glRect.bottom - surface->glRect.top;
+ UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
+ UINT i;
+
+ TRACE("surface %p is a subresource of texture %p.\n", surface, texture);
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ IWineD3DSurfaceImpl *s = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+ surface_prepare_texture_internal(s, gl_info, srgb);
+ }
+
+ IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture);
}
- surface_bind_and_dirtify(surface, srgb);
- surface_allocate_surface(surface, internal, width, height, format, type);
- surface->Flags |= alloc_flag;
+ surface_prepare_texture_internal(surface, gl_info, srgb);
}
static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This)
GLenum error;
struct wined3d_context *context;
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
ENTER_GL();
GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
const RECT *pass_rect = pRect;
- TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
+ TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n",
+ iface, pLockedRect, wine_dbgstr_rect(pRect), Flags);
/* This is also done in the base class, but we have to verify this before loading any data from
* gl into the sysmem copy. The PBO may be mapped, a different rectangle locked, the discard flag
}
if (!(wined3d_settings.rendertargetlock_mode == RTL_DISABLE
- && ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0])))
+ && ((This->Flags & SFLAG_SWAPCHAIN) || This == device->render_targets[0])))
{
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect);
}
lock_end:
if (This->Flags & SFLAG_PBO)
{
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
- context = context_acquire(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
* Dirtify on lock
* as seen in msdn docs
*/
- surface_add_dirty_rect(iface, pRect);
+ surface_add_dirty_rect(This, pRect);
/** Dirtify Container if needed */
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) {
GLint prev_rasterpos[4];
GLint skipBytes = 0;
UINT pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This); /* target is argb, 4 byte */
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
/* Activate the correct context for the render target */
- context = context_acquire(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
+ context = context_acquire(device, This);
+ context_apply_blit_state(context, device);
+ gl_info = context->gl_info;
+
ENTER_GL();
- if (!surface_is_offscreen((IWineD3DSurface *)This))
+ if (!surface_is_offscreen(This))
{
- GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This);
+ GLenum buffer = surface_get_gl_buffer(This);
TRACE("Unlocking %#x buffer.\n", buffer);
context_set_draw_buffer(context, buffer);
}
{
/* Primary offscreen render target */
TRACE("Offscreen render target.\n");
- context_set_draw_buffer(context, myDevice->offscreenBuffer);
+ context_set_draw_buffer(context, device->offscreenBuffer);
}
glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
BOOL fullsurface;
if (!(This->Flags & SFLAG_LOCKED)) {
if (This->Flags & SFLAG_PBO)
{
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
TRACE("Freeing PBO memory\n");
- context = context_acquire(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
goto unlock_end;
}
- if ((This->Flags & SFLAG_SWAPCHAIN) || (myDevice->render_targets && iface == myDevice->render_targets[0]))
+ if ((This->Flags & SFLAG_SWAPCHAIN) || (device->render_targets && This == device->render_targets[0]))
{
if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) {
static BOOL warned = FALSE;
This->dirtyRect.top = This->currentDesc.Height;
This->dirtyRect.right = 0;
This->dirtyRect.bottom = 0;
- } else if(iface == myDevice->stencilBufferTarget) {
+ }
+ else if (This == device->depth_stencil)
+ {
FIXME("Depth Stencil buffer locking is not implemented\n");
} else {
/* The rest should be a normal texture */
* states need resetting
*/
if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) {
- if(impl->baseTexture.bindCount) {
- IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_SAMPLER(impl->baseTexture.sampler));
- }
+ if (impl->baseTexture.bindCount)
+ IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(impl->baseTexture.sampler));
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl);
}
}
return WINED3D_OK;
}
-static void surface_release_client_storage(IWineD3DSurface *iface)
+static void surface_release_client_storage(IWineD3DSurfaceImpl *surface)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
struct wined3d_context *context;
- context = context_acquire(This->resource.device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(surface->resource.device, NULL);
ENTER_GL();
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
- if(This->texture_name)
+ if (surface->texture_name)
{
- surface_bind_and_dirtify(This, FALSE);
- glTexImage2D(This->texture_target, This->texture_level,
- GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ surface_bind_and_dirtify(surface, FALSE);
+ glTexImage2D(surface->texture_target, surface->texture_level,
+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
- if(This->texture_name_srgb)
+ if (surface->texture_name_srgb)
{
- surface_bind_and_dirtify(This, TRUE);
- glTexImage2D(This->texture_target, This->texture_level,
- GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ surface_bind_and_dirtify(surface, TRUE);
+ glTexImage2D(surface->texture_target, surface->texture_level,
+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
LEAVE_GL();
context_release(context);
- IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE);
- IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
- surface_force_reload(iface);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSRGBTEX, FALSE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE);
+ surface_force_reload(surface);
}
static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC)
if(!This->hDC) {
if(This->Flags & SFLAG_CLIENT) {
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
- surface_release_client_storage(iface);
+ surface_release_client_storage(This);
}
hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface);
if(FAILED(hr)) return WINED3DERR_INVALIDCALL;
IWineD3DSurfaceImpl *dds_primary;
IWineD3DSwapChainImpl *swapchain;
swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0];
- dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
+ dds_primary = swapchain->front_buffer;
if (dds_primary && dds_primary->palette)
pal = dds_primary->palette->palents;
}
IWineD3DSurface Internal (No mapping to directx api) parts follow
****************************************************** */
-HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) {
+HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, struct wined3d_format_desc *desc, CONVERT_TYPES *convert)
+{
BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT);
- const struct GlPixelFormatDesc *glDesc = This->resource.format_desc;
IWineD3DDeviceImpl *device = This->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ BOOL blit_supported = FALSE;
+ RECT rect = {0, 0, This->pow2Width, This->pow2Height};
- /* Default values: From the surface */
- *format = glDesc->glFormat;
- *type = glDesc->glType;
+ /* Copy the default values from the surface. Below we might perform fixups */
+ /* TODO: get rid of color keying desc fixups by using e.g. a table. */
+ *desc = *This->resource.format_desc;
*convert = NO_CONVERSION;
- *target_bpp = glDesc->byte_count;
-
- if(srgb_mode) {
- *internal = glDesc->glGammaInternal;
- }
- else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET
- && surface_is_offscreen((IWineD3DSurface *) This))
- {
- *internal = glDesc->rtInternal;
- } else {
- *internal = glDesc->glInternal;
- }
/* Ok, now look if we have to do any conversion */
switch(This->resource.format_desc->format)
Paletted Texture
**************** */
- /* Use conversion when the paletted texture extension OR fragment shaders are available. When either
- * of the two is available make sure texturing is requested as neither of the two works in
- * conjunction with calls like glDraw-/glReadPixels. Further also use conversion in case of color keying.
+ blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT,
+ &rect, This->resource.usage, This->resource.pool,
+ This->resource.format_desc, &rect, This->resource.usage,
+ This->resource.pool, This->resource.format_desc);
+
+ /* Use conversion when the blit_shader backend supports it. It only supports this in case of
+ * texturing. Further also use conversion in case of color keying.
* Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations
* in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
* conflicts with this.
*/
- if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)
- && device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0]))
+ if (!((blit_supported && device->render_targets && This == device->render_targets[0]))
|| colorkey_active || !use_texturing)
{
- *format = GL_RGBA;
- *internal = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
- *target_bpp = 4;
+ desc->glFormat = GL_RGBA;
+ desc->glInternal = GL_RGBA;
+ desc->glType = GL_UNSIGNED_BYTE;
+ desc->conv_byte_count = 4;
if(colorkey_active) {
*convert = CONVERT_PALETTED_CK;
} else {
*convert = CONVERT_PALETTED;
}
}
- else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup))
- {
- *format = GL_ALPHA;
- *type = GL_UNSIGNED_BYTE;
- *target_bpp = 1;
- }
-
break;
case WINED3DFMT_B2G3R3_UNORM:
case WINED3DFMT_B5G6R5_UNORM:
if (colorkey_active) {
*convert = CONVERT_CK_565;
- *format = GL_RGBA;
- *internal = GL_RGB5_A1;
- *type = GL_UNSIGNED_SHORT_5_5_5_1;
+ desc->glFormat = GL_RGBA;
+ desc->glInternal = GL_RGB5_A1;
+ desc->glType = GL_UNSIGNED_SHORT_5_5_5_1;
+ desc->conv_byte_count = 2;
}
break;
case WINED3DFMT_B5G5R5X1_UNORM:
if (colorkey_active) {
*convert = CONVERT_CK_5551;
- *format = GL_BGRA;
- *internal = GL_RGB5_A1;
- *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ desc->glFormat = GL_BGRA;
+ desc->glInternal = GL_RGB5_A1;
+ desc->glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ desc->conv_byte_count = 2;
}
break;
case WINED3DFMT_B8G8R8_UNORM:
if (colorkey_active) {
*convert = CONVERT_CK_RGB24;
- *format = GL_RGBA;
- *internal = GL_RGBA8;
- *type = GL_UNSIGNED_INT_8_8_8_8;
- *target_bpp = 4;
+ desc->glFormat = GL_RGBA;
+ desc->glInternal = GL_RGBA8;
+ desc->glType = GL_UNSIGNED_INT_8_8_8_8;
+ desc->conv_byte_count = 4;
}
break;
case WINED3DFMT_B8G8R8X8_UNORM:
if (colorkey_active) {
*convert = CONVERT_RGB32_888;
- *format = GL_RGBA;
- *internal = GL_RGBA8;
- *type = GL_UNSIGNED_INT_8_8_8_8;
- }
- break;
-
- case WINED3DFMT_R8G8_SNORM:
- if (gl_info->supported[NV_TEXTURE_SHADER]) break;
- *convert = CONVERT_V8U8;
- *format = GL_BGR;
- *type = GL_UNSIGNED_BYTE;
- *target_bpp = 3;
- break;
-
- case WINED3DFMT_R5G5_SNORM_L6_UNORM:
- *convert = CONVERT_L6V5U5;
- if (gl_info->supported[NV_TEXTURE_SHADER])
- {
- *target_bpp = 3;
- /* Use format and types from table */
- } else {
- /* Load it into unsigned R5G6B5, swap L and V channels, and revert that in the shader */
- *target_bpp = 2;
- *format = GL_RGB;
- *type = GL_UNSIGNED_SHORT_5_6_5;
- }
- break;
-
- case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
- *convert = CONVERT_X8L8V8U8;
- *target_bpp = 4;
- if (gl_info->supported[NV_TEXTURE_SHADER])
- {
- /* Use formats from gl table. It is a bit unfortunate, but the conversion
- * is needed to set the X format to 255 to get 1.0 for alpha when sampling
- * the texture. OpenGL can't use GL_DSDT8_MAG8_NV as internal format with
- * the needed type and format parameter, so the internal format contains a
- * 4th component, which is returned as alpha
- */
- } else {
- *format = GL_BGRA;
- *type = GL_UNSIGNED_INT_8_8_8_8_REV;
- }
- break;
-
- case WINED3DFMT_R8G8B8A8_SNORM:
- if (gl_info->supported[NV_TEXTURE_SHADER]) break;
- *convert = CONVERT_Q8W8V8U8;
- *format = GL_BGRA;
- *type = GL_UNSIGNED_BYTE;
- *target_bpp = 4;
- break;
-
- case WINED3DFMT_R16G16_SNORM:
- if (gl_info->supported[NV_TEXTURE_SHADER]) break;
- *convert = CONVERT_V16U16;
- *format = GL_BGR;
- *type = GL_UNSIGNED_SHORT;
- *target_bpp = 6;
- break;
-
- case WINED3DFMT_L4A4_UNORM:
- /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
- * format+type combination to load it. Thus convert it to A8L8, then load it
- * with A4L4 internal, but A8L8 format+type
- */
- *convert = CONVERT_A4L4;
- *format = GL_LUMINANCE_ALPHA;
- *type = GL_UNSIGNED_BYTE;
- *target_bpp = 2;
- break;
-
- case WINED3DFMT_R16G16_UNORM:
- *convert = CONVERT_G16R16;
- *format = GL_RGB;
- *type = GL_UNSIGNED_SHORT;
- *target_bpp = 6;
- break;
-
- case WINED3DFMT_R16G16_FLOAT:
- *convert = CONVERT_R16G16F;
- *format = GL_RGB;
- *type = GL_HALF_FLOAT_ARB;
- *target_bpp = 6;
- break;
-
- case WINED3DFMT_R32G32_FLOAT:
- *convert = CONVERT_R32G32F;
- *format = GL_RGB;
- *type = GL_FLOAT;
- *target_bpp = 12;
- break;
-
- case WINED3DFMT_S1_UINT_D15_UNORM:
- if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
- || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
- {
- *convert = CONVERT_D15S1;
- *target_bpp = 4;
- }
- break;
-
- case WINED3DFMT_S4X4_UINT_D24_UNORM:
- if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
- || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
- {
- *convert = CONVERT_D24X4S4;
- }
- break;
-
- case WINED3DFMT_S8_UINT_D24_FLOAT:
- if (gl_info->supported[ARB_DEPTH_BUFFER_FLOAT])
- {
- *convert = CONVERT_D24FS8;
- *target_bpp = 8;
+ desc->glFormat = GL_RGBA;
+ desc->glInternal = GL_RGBA8;
+ desc->glType = GL_UNSIGNED_INT_8_8_8_8;
+ desc->conv_byte_count = 4;
}
break;
return WINED3D_OK;
}
-static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey)
+void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey)
{
IWineD3DDeviceImpl *device = This->resource.device;
IWineD3DPaletteImpl *pal = This->palette;
static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width,
UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This)
{
- IWineD3DDeviceImpl *device = This->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const BYTE *source;
BYTE *dest;
TRACE("(%p)->(%p),(%d,%d,%d,%d,%p)\n", src, dst, pitch, height, outpitch, convert,This);
}
break;
- case CONVERT_V8U8:
- {
- unsigned int x, y;
- const short *Source;
- unsigned char *Dest;
- for(y = 0; y < height; y++) {
- Source = (const short *)(src + y * pitch);
- Dest = dst + y * outpitch;
- for (x = 0; x < width; x++ ) {
- long color = (*Source++);
- /* B */ Dest[0] = 0xff;
- /* G */ Dest[1] = (color >> 8) + 128; /* V */
- /* R */ Dest[2] = (color) + 128; /* U */
- Dest += 3;
- }
- }
- break;
- }
-
- case CONVERT_V16U16:
- {
- unsigned int x, y;
- const DWORD *Source;
- unsigned short *Dest;
- for(y = 0; y < height; y++) {
- Source = (const DWORD *)(src + y * pitch);
- Dest = (unsigned short *) (dst + y * outpitch);
- for (x = 0; x < width; x++ ) {
- DWORD color = (*Source++);
- /* B */ Dest[0] = 0xffff;
- /* G */ Dest[1] = (color >> 16) + 32768; /* V */
- /* R */ Dest[2] = (color ) + 32768; /* U */
- Dest += 3;
- }
- }
- break;
- }
-
- case CONVERT_Q8W8V8U8:
- {
- unsigned int x, y;
- const DWORD *Source;
- unsigned char *Dest;
- for(y = 0; y < height; y++) {
- Source = (const DWORD *)(src + y * pitch);
- Dest = dst + y * outpitch;
- for (x = 0; x < width; x++ ) {
- long color = (*Source++);
- /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
- /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
- /* R */ Dest[2] = (color & 0xff) + 128; /* U */
- /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
- Dest += 4;
- }
- }
- break;
- }
-
- case CONVERT_L6V5U5:
- {
- unsigned int x, y;
- const WORD *Source;
- unsigned char *Dest;
-
- if (gl_info->supported[NV_TEXTURE_SHADER])
- {
- /* This makes the gl surface bigger(24 bit instead of 16), but it works with
- * fixed function and shaders without further conversion once the surface is
- * loaded
- */
- for(y = 0; y < height; y++) {
- Source = (const WORD *)(src + y * pitch);
- Dest = dst + y * outpitch;
- for (x = 0; x < width; x++ ) {
- short color = (*Source++);
- unsigned char l = ((color >> 10) & 0xfc);
- char v = ((color >> 5) & 0x3e);
- char u = ((color ) & 0x1f);
-
- /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
- * and doubles the positive range. Thus shift left only once, gl does the 2nd
- * shift. GL reads a signed value and converts it into an unsigned value.
- */
- /* M */ Dest[2] = l << 1;
-
- /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
- * from 5 bit values to 8 bit values.
- */
- /* V */ Dest[1] = v << 3;
- /* U */ Dest[0] = u << 3;
- Dest += 3;
- }
- }
- } else {
- for(y = 0; y < height; y++) {
- unsigned short *Dest_s = (unsigned short *) (dst + y * outpitch);
- Source = (const WORD *)(src + y * pitch);
- for (x = 0; x < width; x++ ) {
- short color = (*Source++);
- unsigned char l = ((color >> 10) & 0xfc);
- short v = ((color >> 5) & 0x3e);
- short u = ((color ) & 0x1f);
- short v_conv = v + 16;
- short u_conv = u + 16;
-
- *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
- Dest_s += 1;
- }
- }
- }
- break;
- }
-
- case CONVERT_X8L8V8U8:
- {
- unsigned int x, y;
- const DWORD *Source;
- unsigned char *Dest;
-
- if (gl_info->supported[NV_TEXTURE_SHADER])
- {
- /* This implementation works with the fixed function pipeline and shaders
- * without further modification after converting the surface.
- */
- for(y = 0; y < height; y++) {
- Source = (const DWORD *)(src + y * pitch);
- Dest = dst + y * outpitch;
- for (x = 0; x < width; x++ ) {
- long color = (*Source++);
- /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
- /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
- /* U */ Dest[0] = (color & 0xff); /* U */
- /* I */ Dest[3] = 255; /* X */
- Dest += 4;
- }
- }
- } else {
- /* Doesn't work correctly with the fixed function pipeline, but can work in
- * shaders if the shader is adjusted. (There's no use for this format in gl's
- * standard fixed function pipeline anyway).
- */
- for(y = 0; y < height; y++) {
- Source = (const DWORD *)(src + y * pitch);
- Dest = dst + y * outpitch;
- for (x = 0; x < width; x++ ) {
- long color = (*Source++);
- /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
- /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
- /* R */ Dest[2] = (color & 0xff) + 128; /* U */
- Dest += 4;
- }
- }
- }
- break;
- }
-
- case CONVERT_A4L4:
- {
- unsigned int x, y;
- const unsigned char *Source;
- unsigned char *Dest;
- for(y = 0; y < height; y++) {
- Source = src + y * pitch;
- Dest = dst + y * outpitch;
- for (x = 0; x < width; x++ ) {
- unsigned char color = (*Source++);
- /* A */ Dest[1] = (color & 0xf0) << 0;
- /* L */ Dest[0] = (color & 0x0f) << 4;
- Dest += 2;
- }
- }
- break;
- }
-
- case CONVERT_G16R16:
- case CONVERT_R16G16F:
- {
- unsigned int x, y;
- const WORD *Source;
- WORD *Dest;
-
- for(y = 0; y < height; y++) {
- Source = (const WORD *)(src + y * pitch);
- Dest = (WORD *) (dst + y * outpitch);
- for (x = 0; x < width; x++ ) {
- WORD green = (*Source++);
- WORD red = (*Source++);
- Dest[0] = green;
- Dest[1] = red;
- /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
- * shader overwrites it anyway
- */
- Dest[2] = 0xffff;
- Dest += 3;
- }
- }
- break;
- }
-
- case CONVERT_R32G32F:
- {
- unsigned int x, y;
- const float *Source;
- float *Dest;
- for(y = 0; y < height; y++) {
- Source = (const float *)(src + y * pitch);
- Dest = (float *) (dst + y * outpitch);
- for (x = 0; x < width; x++ ) {
- float green = (*Source++);
- float red = (*Source++);
- Dest[0] = green;
- Dest[1] = red;
- Dest[2] = 1.0f;
- Dest += 3;
- }
- }
- break;
- }
-
- case CONVERT_D15S1:
- {
- unsigned int x, y;
-
- for (y = 0; y < height; ++y)
- {
- const WORD *source = (const WORD *)(src + y * pitch);
- DWORD *dest = (DWORD *)(dst + y * outpitch);
-
- for (x = 0; x < width; ++x)
- {
- /* The depth data is normalized, so needs to be scaled,
- * the stencil data isn't. Scale depth data by
- * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
- WORD d15 = source[x] >> 1;
- DWORD d24 = (d15 << 9) + (d15 >> 6);
- dest[x] = (d24 << 8) | (source[x] & 0x1);
- }
- }
- break;
- }
-
- case CONVERT_D24X4S4:
- {
- unsigned int x, y;
-
- for (y = 0; y < height; ++y)
- {
- const DWORD *source = (const DWORD *)(src + y * pitch);
- DWORD *dest = (DWORD *)(dst + y * outpitch);
-
- for (x = 0; x < width; ++x)
- {
- /* Just need to clear out the X4 part. */
- dest[x] = source[x] & ~0xf0;
- }
- }
- break;
- }
-
- case CONVERT_D24FS8:
- {
- unsigned int x, y;
-
- for (y = 0; y < height; ++y)
- {
- const DWORD *source = (const DWORD *)(src + y * pitch);
- float *dest_f = (float *)(dst + y * outpitch);
- DWORD *dest_s = (DWORD *)(dst + y * outpitch);
-
- for (x = 0; x < width; ++x)
- {
- dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
- dest_s[x * 2 + 1] = source[x] & 0xff;
- }
- }
- break;
- }
-
default:
ERR("Unsupported conversion type %#x.\n", convert);
}
return WINED3D_OK;
}
-/* This function is used in case of 8bit paletted textures to upload the palette.
- It supports GL_EXT_paletted_texture and GL_ARB_fragment_program, support for other
- extensions like ATI_fragment_shaders is possible.
-*/
-/* Context activation is done by the caller. */
-static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) {
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- BYTE table[256][4];
- IWineD3DDeviceImpl *device = This->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-
- d3dfmt_p8_init_palette(This, table, (convert == CONVERT_PALETTED_CK));
-
- /* Try to use the paletted texture extension */
- if (gl_info->supported[EXT_PALETTED_TEXTURE])
- {
- TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
- ENTER_GL();
- GL_EXTCALL(glColorTableEXT(This->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
- LEAVE_GL();
- }
- else
- {
- /* Let a fragment shader do the color conversion by uploading the palette to a 1D texture.
- * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */
- TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n");
-
- device->blitter->set_shader((IWineD3DDevice *) device, This->resource.format_desc,
- This->texture_target, This->pow2Width, This->pow2Height);
-
- ENTER_GL();
- GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* Make sure we have discrete color levels. */
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table); /* Upload the palette */
-
- /* Switch back to unit 0 in which the 2D texture will be stored. */
- GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0));
-
- /* Rebind the texture because it isn't bound anymore */
- glBindTexture(This->texture_target, This->texture_name);
- LEAVE_GL();
- }
-}
-
BOOL palette9_changed(IWineD3DSurfaceImpl *This)
{
IWineD3DDeviceImpl *device = This->resource.device;
LEAVE_GL();
} else { /* bind the real texture, and make sure it up to date */
- surface_internal_preload(iface, SRGB_RGB);
+ surface_internal_preload(This, SRGB_RGB);
surface_bind_and_dirtify(This, FALSE);
}
allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4);
IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
/* For client textures opengl has to be notified */
- if(This->Flags & SFLAG_CLIENT) {
- surface_release_client_storage(iface);
- }
+ if (This->Flags & SFLAG_CLIENT)
+ surface_release_client_storage(This);
/* Now free the old memory if any */
HeapFree(GetProcessHeap(), 0, release);
if(This->resource.heapMemory != NULL) ERR("User pointer surface has heap memory allocated\n");
This->Flags &= ~SFLAG_USERPTR;
- if(This->Flags & SFLAG_CLIENT) {
- surface_release_client_storage(iface);
- }
+ if (This->Flags & SFLAG_CLIENT)
+ surface_release_client_storage(This);
}
return WINED3D_OK;
}
}
/* Flipping a OpenGL surface -> Use WineD3DDevice::Present */
- hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0);
+ hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain,
+ NULL, NULL, swapchain->win_handle, NULL, 0);
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
return hr;
}
/* Does a direct frame buffer -> texture copy. Stretching is done
* with single pixel copy calls
*/
-static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
- const WINED3DRECT *srect, const WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
+static void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *dst_surface, IWineD3DSurfaceImpl *src_surface,
+ const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter)
{
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = dst_surface->resource.device;
float xrel, yrel;
UINT row;
- IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
struct wined3d_context *context;
+ BOOL upsidedown = FALSE;
+ RECT dst_rect = *dst_rect_in;
+ /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+ * glCopyTexSubImage is a bit picky about the parameters we pass to it
+ */
+ if(dst_rect.top > dst_rect.bottom) {
+ UINT tmp = dst_rect.bottom;
+ dst_rect.bottom = dst_rect.top;
+ dst_rect.top = tmp;
+ upsidedown = TRUE;
+ }
- context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT);
- surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
+ context = context_acquire(device, src_surface);
+ context_apply_blit_state(context, device);
+ surface_internal_preload(dst_surface, SRGB_RGB);
ENTER_GL();
/* Bind the target texture */
- glBindTexture(This->texture_target, This->texture_name);
+ glBindTexture(dst_surface->texture_target, dst_surface->texture_name);
checkGLcall("glBindTexture");
- if(surface_is_offscreen(SrcSurface)) {
+ if (surface_is_offscreen(src_surface))
+ {
TRACE("Reading from an offscreen target\n");
upsidedown = !upsidedown;
- glReadBuffer(myDevice->offscreenBuffer);
+ glReadBuffer(device->offscreenBuffer);
}
else
{
- glReadBuffer(surface_get_gl_buffer(SrcSurface));
+ glReadBuffer(surface_get_gl_buffer(src_surface));
}
checkGLcall("glReadBuffer");
- xrel = (float) (srect->x2 - srect->x1) / (float) (drect->x2 - drect->x1);
- yrel = (float) (srect->y2 - srect->y1) / (float) (drect->y2 - drect->y1);
+ xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left);
+ yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top);
if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
{
{
/* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */
- glCopyTexSubImage2D(This->texture_target, This->texture_level,
- drect->x1 /*xoffset */, drect->y1 /* y offset */,
- srect->x1, Src->currentDesc.Height - srect->y2,
- drect->x2 - drect->x1, drect->y2 - drect->y1);
+ glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+ dst_rect.left /*xoffset */, dst_rect.top /* y offset */,
+ src_rect->left, src_surface->currentDesc.Height - src_rect->bottom,
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
} else {
- UINT yoffset = Src->currentDesc.Height - srect->y1 + drect->y1 - 1;
+ UINT yoffset = src_surface->currentDesc.Height - src_rect->top + dst_rect.top - 1;
/* I have to process this row by row to swap the image,
* otherwise it would be upside down, so stretching in y direction
* doesn't cost extra time
*
* However, stretching in x direction can be avoided if not necessary
*/
- for(row = drect->y1; row < drect->y2; row++) {
+ for(row = dst_rect.top; row < dst_rect.bottom; row++) {
if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
{
/* Well, that stuff works, but it's very slow.
*/
UINT col;
- for(col = drect->x1; col < drect->x2; col++) {
- glCopyTexSubImage2D(This->texture_target, This->texture_level,
- drect->x1 + col /* x offset */, row /* y offset */,
- srect->x1 + col * xrel, yoffset - (int) (row * yrel), 1, 1);
+ for (col = dst_rect.left; col < dst_rect.right; ++col)
+ {
+ glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+ dst_rect.left + col /* x offset */, row /* y offset */,
+ src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1);
}
- } else {
- glCopyTexSubImage2D(This->texture_target, This->texture_level,
- drect->x1 /* x offset */, row /* y offset */,
- srect->x1, yoffset - (int) (row * yrel), drect->x2-drect->x1, 1);
+ }
+ else
+ {
+ glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+ dst_rect.left /* x offset */, row /* y offset */,
+ src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1);
}
}
}
/* The texture is now most up to date - If the surface is a render target and has a drawable, this
* path is never entered
*/
- IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INTEXTURE, TRUE);
}
/* Uses the hardware to stretch and flip the image */
-static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
- IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect,
- BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
+static void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *dst_surface, IWineD3DSurfaceImpl *src_surface,
+ const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter)
{
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = dst_surface->resource.device;
GLuint src, backup = 0;
- IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
+ IWineD3DSwapChainImpl *src_swapchain = NULL;
float left, right, top, bottom; /* Texture coordinates */
- UINT fbwidth = Src->currentDesc.Width;
- UINT fbheight = Src->currentDesc.Height;
+ UINT fbwidth = src_surface->currentDesc.Width;
+ UINT fbheight = src_surface->currentDesc.Height;
struct wined3d_context *context;
GLenum drawBuffer = GL_BACK;
GLenum texture_target;
BOOL noBackBufferBackup;
BOOL src_offscreen;
+ BOOL upsidedown = FALSE;
+ RECT dst_rect = *dst_rect_in;
TRACE("Using hwstretch blit\n");
/* Activate the Proper context for reading from the source surface, set it up for blitting */
- context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT);
- surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
+ context = context_acquire(device, src_surface);
+ context_apply_blit_state(context, device);
+ surface_internal_preload(dst_surface, SRGB_RGB);
- src_offscreen = surface_is_offscreen(SrcSurface);
+ src_offscreen = surface_is_offscreen(src_surface);
noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
- if (!noBackBufferBackup && !Src->texture_name)
+ if (!noBackBufferBackup && !src_surface->texture_name)
{
/* Get it a description */
- surface_internal_preload(SrcSurface, SRGB_RGB);
+ surface_internal_preload(src_surface, SRGB_RGB);
}
ENTER_GL();
/* Got more than one aux buffer? Use the 2nd aux buffer */
drawBuffer = GL_AUX1;
}
- else if ((!src_offscreen || myDevice->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1)
+ else if ((!src_offscreen || device->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1)
{
/* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */
drawBuffer = GL_AUX0;
/* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
* we are reading from the back buffer, the backup can be used as source texture
*/
- texture_target = Src->texture_target;
- glBindTexture(texture_target, Src->texture_name);
- checkGLcall("glBindTexture(texture_target, Src->texture_name)");
+ texture_target = src_surface->texture_target;
+ glBindTexture(texture_target, src_surface->texture_name);
+ checkGLcall("glBindTexture(texture_target, src_surface->texture_name)");
glEnable(texture_target);
checkGLcall("glEnable(texture_target)");
/* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
- Src->Flags &= ~SFLAG_INTEXTURE;
+ src_surface->Flags &= ~SFLAG_INTEXTURE;
+ }
+
+ /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+ * glCopyTexSubImage is a bit picky about the parameters we pass to it
+ */
+ if(dst_rect.top > dst_rect.bottom) {
+ UINT tmp = dst_rect.bottom;
+ dst_rect.bottom = dst_rect.top;
+ dst_rect.top = tmp;
+ upsidedown = TRUE;
}
if (src_offscreen)
{
TRACE("Reading from an offscreen target\n");
upsidedown = !upsidedown;
- glReadBuffer(myDevice->offscreenBuffer);
+ glReadBuffer(device->offscreenBuffer);
}
else
{
- glReadBuffer(surface_get_gl_buffer(SrcSurface));
+ glReadBuffer(surface_get_gl_buffer(src_surface));
}
/* TODO: Only back up the part that will be overwritten */
wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
checkGLcall("glTexParameteri");
- if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
- src = backup ? backup : Src->texture_name;
- } else {
+ IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&src_swapchain);
+ if (src_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)src_swapchain);
+ if (!src_swapchain || src_surface == src_swapchain->back_buffers[0])
+ {
+ src = backup ? backup : src_surface->texture_name;
+ }
+ else
+ {
glReadBuffer(GL_FRONT);
checkGLcall("glReadBuffer(GL_FRONT)");
glBindTexture(GL_TEXTURE_2D, src);
checkGLcall("glBindTexture(GL_TEXTURE_2D, src)");
- /* TODO: Only copy the part that will be read. Use srect->x1, srect->y2 as origin, but with the width watch
+ /* TODO: Only copy the part that will be read. Use src_rect->left, src_rect->bottom as origin, but with the width watch
* out for power of 2 sizes
*/
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Src->pow2Width, Src->pow2Height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_surface->pow2Width,
+ src_surface->pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
checkGLcall("glTexImage2D");
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0 /* read offsets */,
}
checkGLcall("glEnd and previous");
- left = srect->x1;
- right = srect->x2;
+ left = src_rect->left;
+ right = src_rect->right;
- if(upsidedown) {
- top = Src->currentDesc.Height - srect->y1;
- bottom = Src->currentDesc.Height - srect->y2;
- } else {
- top = Src->currentDesc.Height - srect->y2;
- bottom = Src->currentDesc.Height - srect->y1;
+ if (upsidedown)
+ {
+ top = src_surface->currentDesc.Height - src_rect->top;
+ bottom = src_surface->currentDesc.Height - src_rect->bottom;
+ }
+ else
+ {
+ top = src_surface->currentDesc.Height - src_rect->bottom;
+ bottom = src_surface->currentDesc.Height - src_rect->top;
}
- if(Src->Flags & SFLAG_NORMCOORD) {
- left /= Src->pow2Width;
- right /= Src->pow2Width;
- top /= Src->pow2Height;
- bottom /= Src->pow2Height;
+ if (src_surface->Flags & SFLAG_NORMCOORD)
+ {
+ left /= src_surface->pow2Width;
+ right /= src_surface->pow2Width;
+ top /= src_surface->pow2Height;
+ bottom /= src_surface->pow2Height;
}
/* draw the source texture stretched and upside down. The correct surface is bound already */
/* top left */
glTexCoord2f(left, top);
- glVertex2i(0, fbheight - drect->y2 - drect->y1);
+ glVertex2i(0, fbheight - dst_rect.bottom - dst_rect.top);
/* top right */
glTexCoord2f(right, top);
- glVertex2i(drect->x2 - drect->x1, fbheight - drect->y2 - drect->y1);
+ glVertex2i(dst_rect.right - dst_rect.left, fbheight - dst_rect.bottom - dst_rect.top);
/* bottom right */
glTexCoord2f(right, bottom);
- glVertex2i(drect->x2 - drect->x1, fbheight);
+ glVertex2i(dst_rect.right - dst_rect.left, fbheight);
glEnd();
checkGLcall("glEnd and previous");
- if (texture_target != This->texture_target)
+ if (texture_target != dst_surface->texture_target)
{
glDisable(texture_target);
- glEnable(This->texture_target);
- texture_target = This->texture_target;
+ glEnable(dst_surface->texture_target);
+ texture_target = dst_surface->texture_target;
}
/* Now read the stretched and upside down image into the destination texture */
- glBindTexture(texture_target, This->texture_name);
+ glBindTexture(texture_target, dst_surface->texture_name);
checkGLcall("glBindTexture");
glCopyTexSubImage2D(texture_target,
0,
- drect->x1, drect->y1, /* xoffset, yoffset */
+ dst_rect.left, dst_rect.top, /* xoffset, yoffset */
0, 0, /* We blitted the image to the origin */
- drect->x2 - drect->x1, drect->y2 - drect->y1);
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
checkGLcall("glCopyTexSubImage2D");
if(drawBuffer == GL_BACK) {
}
glBindTexture(GL_TEXTURE_2D, backup);
checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
- } else {
- if (texture_target != Src->texture_target)
- {
- glDisable(texture_target);
- glEnable(Src->texture_target);
- texture_target = Src->texture_target;
+ }
+ else
+ {
+ if (texture_target != src_surface->texture_target)
+ {
+ glDisable(texture_target);
+ glEnable(src_surface->texture_target);
+ texture_target = src_surface->texture_target;
}
- glBindTexture(Src->texture_target, Src->texture_name);
- checkGLcall("glBindTexture(Src->texture_target, Src->texture_name)");
+ glBindTexture(src_surface->texture_target, src_surface->texture_name);
+ checkGLcall("glBindTexture(src_surface->texture_target, src_surface->texture_name)");
}
glBegin(GL_QUADS);
/* top left */
- glTexCoord2f(0.0f, (float)fbheight / (float)Src->pow2Height);
+ glTexCoord2f(0.0f, (float)fbheight / (float)src_surface->pow2Height);
glVertex2i(0, 0);
/* bottom left */
glVertex2i(0, fbheight);
/* bottom right */
- glTexCoord2f((float)fbwidth / (float)Src->pow2Width, 0.0f);
- glVertex2i(fbwidth, Src->currentDesc.Height);
+ glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, 0.0f);
+ glVertex2i(fbwidth, src_surface->currentDesc.Height);
/* top right */
- glTexCoord2f((float) fbwidth / (float) Src->pow2Width, (float) fbheight / (float) Src->pow2Height);
+ glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width,
+ (float)fbheight / (float)src_surface->pow2Height);
glVertex2i(fbwidth, 0);
glEnd();
}
checkGLcall("glDisable(texture_target)");
/* Cleanup */
- if (src != Src->texture_name && src != backup)
+ if (src != src_surface->texture_name && src != backup)
{
glDeleteTextures(1, &src);
checkGLcall("glDeleteTextures(1, &src)");
LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
/* The texture is now most up to date - If the surface is a render target and has a drawable, this
* path is never entered
*/
- IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INTEXTURE, TRUE);
+}
+
+/* Until the blit_shader is ready, define some prototypes here. */
+static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+ const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+ const struct wined3d_format_desc *src_format_desc,
+ const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+ const struct wined3d_format_desc *dst_format_desc);
+
+/* Front buffer coordinates are always full screen coordinates, but our GL
+ * drawable is limited to the window's client area. The sysmem and texture
+ * copies do have the full screen size. Note that GL has a bottom-left
+ * origin, while D3D has a top-left origin. */
+void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect)
+{
+ POINT offset = {0, surface->currentDesc.Height};
+ RECT windowsize;
+
+ GetClientRect(window, &windowsize);
+ offset.y -= windowsize.bottom - windowsize.top;
+ ScreenToClient(window, &offset);
+ OffsetRect(rect, offset.x, offset.y);
}
/* Not called from the VTable */
-static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const RECT *DestRect,
- IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx,
+static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface, const RECT *DestRect,
+ IWineD3DSurfaceImpl *src_surface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx,
WINED3DTEXTUREFILTERTYPE Filter)
{
- IWineD3DDeviceImpl *myDevice = This->resource.device;
- WINED3DRECT rect;
+ IWineD3DDeviceImpl *device = dst_surface->resource.device;
IWineD3DSwapChainImpl *srcSwapchain = NULL, *dstSwapchain = NULL;
- IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
+ RECT dst_rect, src_rect;
- TRACE("(%p)->(%p,%p,%p,%08x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n",
+ dst_surface, wine_dbgstr_rect(DestRect), src_surface, wine_dbgstr_rect(SrcRect),
+ Flags, DDBltFx, debug_d3dtexturefiltertype(Filter));
/* Get the swapchain. One of the surfaces has to be a primary surface */
- if(This->resource.pool == WINED3DPOOL_SYSTEMMEM) {
+ if (dst_surface->resource.pool == WINED3DPOOL_SYSTEMMEM)
+ {
WARN("Destination is in sysmem, rejecting gl blt\n");
return WINED3DERR_INVALIDCALL;
}
- IWineD3DSurface_GetContainer( (IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&dstSwapchain);
- if(dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) dstSwapchain);
- if(Src) {
- if(Src->resource.pool == WINED3DPOOL_SYSTEMMEM) {
+ IWineD3DSurface_GetContainer((IWineD3DSurface *)dst_surface, &IID_IWineD3DSwapChain, (void **)&dstSwapchain);
+ if (dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)dstSwapchain);
+ if (src_surface)
+ {
+ if (src_surface->resource.pool == WINED3DPOOL_SYSTEMMEM)
+ {
WARN("Src is in sysmem, rejecting gl blt\n");
return WINED3DERR_INVALIDCALL;
}
- IWineD3DSurface_GetContainer( (IWineD3DSurface *) Src, &IID_IWineD3DSwapChain, (void **)&srcSwapchain);
- if(srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) srcSwapchain);
+ IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&srcSwapchain);
+ if (srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)srcSwapchain);
}
/* Early sort out of cases where no render target is used */
- if(!dstSwapchain && !srcSwapchain &&
- SrcSurface != myDevice->render_targets[0] && This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
- TRACE("No surface is render target, not using hardware blit. Src = %p, dst = %p\n", Src, This);
+ if (!dstSwapchain && !srcSwapchain
+ && src_surface != device->render_targets[0]
+ && dst_surface != device->render_targets[0])
+ {
+ TRACE("No surface is render target, not using hardware blit.\n");
return WINED3DERR_INVALIDCALL;
}
return WINED3DERR_INVALIDCALL;
}
- if (DestRect) {
- rect.x1 = DestRect->left;
- rect.y1 = DestRect->top;
- rect.x2 = DestRect->right;
- rect.y2 = DestRect->bottom;
- } else {
- rect.x1 = 0;
- rect.y1 = 0;
- rect.x2 = This->currentDesc.Width;
- rect.y2 = This->currentDesc.Height;
- }
+ surface_get_rect(dst_surface, DestRect, &dst_rect);
+ if (src_surface) surface_get_rect(src_surface, SrcRect, &src_rect);
/* The only case where both surfaces on a swapchain are supported is a back buffer -> front buffer blit on the same swapchain */
- if(dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->backBuffer &&
- ((IWineD3DSurface *) This == dstSwapchain->frontBuffer) && SrcSurface == dstSwapchain->backBuffer[0]) {
+ if (dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->back_buffers
+ && dst_surface == dstSwapchain->front_buffer
+ && src_surface == dstSwapchain->back_buffers[0])
+ {
/* Half-life does a Blt from the back buffer to the front buffer,
* Full surface size, no flags... Use present instead
*
/* Check rects - IWineD3DDevice_Present doesn't handle them */
while(1)
{
- RECT mySrcRect;
TRACE("Looking if a Present can be done...\n");
/* Source Rectangle must be full surface */
- if( SrcRect ) {
- if(SrcRect->left != 0 || SrcRect->top != 0 ||
- SrcRect->right != Src->currentDesc.Width || SrcRect->bottom != Src->currentDesc.Height) {
- TRACE("No, Source rectangle doesn't match\n");
- break;
- }
+ if (src_rect.left || src_rect.top
+ || src_rect.right != src_surface->currentDesc.Width
+ || src_rect.bottom != src_surface->currentDesc.Height)
+ {
+ TRACE("No, Source rectangle doesn't match\n");
+ break;
}
- mySrcRect.left = 0;
- mySrcRect.top = 0;
- mySrcRect.right = Src->currentDesc.Width;
- mySrcRect.bottom = Src->currentDesc.Height;
/* No stretching may occur */
- if(mySrcRect.right != rect.x2 - rect.x1 ||
- mySrcRect.bottom != rect.y2 - rect.y1) {
+ if(src_rect.right != dst_rect.right - dst_rect.left ||
+ src_rect.bottom != dst_rect.bottom - dst_rect.top) {
TRACE("No, stretching is done\n");
break;
}
/* Destination must be full surface or match the clipping rectangle */
- if(This->clipper && ((IWineD3DClipperImpl *) This->clipper)->hWnd)
+ if (dst_surface->clipper && ((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd)
{
RECT cliprect;
POINT pos[2];
- GetClientRect(((IWineD3DClipperImpl *) This->clipper)->hWnd, &cliprect);
- pos[0].x = rect.x1;
- pos[0].y = rect.y1;
- pos[1].x = rect.x2;
- pos[1].y = rect.y2;
- MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *) This->clipper)->hWnd,
- pos, 2);
+ GetClientRect(((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd, &cliprect);
+ pos[0].x = dst_rect.left;
+ pos[0].y = dst_rect.top;
+ pos[1].x = dst_rect.right;
+ pos[1].y = dst_rect.bottom;
+ MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd, pos, 2);
if(pos[0].x != cliprect.left || pos[0].y != cliprect.top ||
pos[1].x != cliprect.right || pos[1].y != cliprect.bottom)
{
TRACE("No, dest rectangle doesn't match(clipper)\n");
- TRACE("Clip rect at (%d,%d)-(%d,%d)\n", cliprect.left, cliprect.top, cliprect.right, cliprect.bottom);
- TRACE("Blt dest: (%d,%d)-(%d,%d)\n", rect.x1, rect.y1, rect.x2, rect.y2);
+ TRACE("Clip rect at %s\n", wine_dbgstr_rect(&cliprect));
+ TRACE("Blt dest: %s\n", wine_dbgstr_rect(&dst_rect));
break;
}
}
- else
+ else if (dst_rect.left || dst_rect.top
+ || dst_rect.right != dst_surface->currentDesc.Width
+ || dst_rect.bottom != dst_surface->currentDesc.Height)
{
- if(rect.x1 != 0 || rect.y1 != 0 ||
- rect.x2 != This->currentDesc.Width || rect.y2 != This->currentDesc.Height) {
- TRACE("No, dest rectangle doesn't match(surface size)\n");
- break;
- }
+ TRACE("No, dest rectangle doesn't match(surface size)\n");
+ break;
}
TRACE("Yes\n");
dstSwapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE;
TRACE("Full screen back buffer -> front buffer blt, performing a flip instead\n");
- IWineD3DSwapChain_Present((IWineD3DSwapChain *) dstSwapchain, NULL, NULL, 0, NULL, 0);
+ IWineD3DSwapChain_Present((IWineD3DSwapChain *)dstSwapchain,
+ NULL, NULL, dstSwapchain->win_handle, NULL, 0);
dstSwapchain->presentParms.SwapEffect = orig_swap;
} else if(dstSwapchain && srcSwapchain) {
FIXME("Implement hardware blit between two different swapchains\n");
return WINED3DERR_INVALIDCALL;
- } else if(dstSwapchain) {
- if(SrcSurface == myDevice->render_targets[0]) {
+ }
+ else if (dstSwapchain)
+ {
+ /* Handled with regular texture -> swapchain blit */
+ if (src_surface == device->render_targets[0])
TRACE("Blit from active render target to a swapchain\n");
- /* Handled with regular texture -> swapchain blit */
- }
- } else if(srcSwapchain && This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
+ }
+ else if (srcSwapchain && dst_surface == device->render_targets[0])
+ {
FIXME("Implement blit from a swapchain to the active render target\n");
return WINED3DERR_INVALIDCALL;
}
- if((srcSwapchain || SrcSurface == myDevice->render_targets[0]) && !dstSwapchain) {
+ if ((srcSwapchain || src_surface == device->render_targets[0]) && !dstSwapchain)
+ {
/* Blit from render target to texture */
- WINED3DRECT srect;
- BOOL upsideDown, stretchx;
- BOOL paletteOverride = FALSE;
+ BOOL stretchx;
+
+ /* P8 read back is not implemented */
+ if (src_surface->resource.format_desc->format == WINED3DFMT_P8_UINT
+ || dst_surface->resource.format_desc->format == WINED3DFMT_P8_UINT)
+ {
+ TRACE("P8 read back not supported by frame buffer to texture blit\n");
+ return WINED3DERR_INVALIDCALL;
+ }
if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
TRACE("Color keying not supported by frame buffer to texture blit\n");
/* Destination color key is checked above */
}
- /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
- * glCopyTexSubImage is a bit picky about the parameters we pass to it
- */
- if(SrcRect) {
- if(SrcRect->top < SrcRect->bottom) {
- srect.y1 = SrcRect->top;
- srect.y2 = SrcRect->bottom;
- upsideDown = FALSE;
- } else {
- srect.y1 = SrcRect->bottom;
- srect.y2 = SrcRect->top;
- upsideDown = TRUE;
- }
- srect.x1 = SrcRect->left;
- srect.x2 = SrcRect->right;
- } else {
- srect.x1 = 0;
- srect.y1 = 0;
- srect.x2 = Src->currentDesc.Width;
- srect.y2 = Src->currentDesc.Height;
- upsideDown = FALSE;
- }
- if(rect.x1 > rect.x2) {
- UINT tmp = rect.x2;
- rect.x2 = rect.x1;
- rect.x1 = tmp;
- upsideDown = !upsideDown;
- }
-
- if(rect.x2 - rect.x1 != srect.x2 - srect.x1) {
+ if(dst_rect.right - dst_rect.left != src_rect.right - src_rect.left) {
stretchx = TRUE;
} else {
stretchx = FALSE;
}
- /* When blitting from a render target a texture, the texture isn't required to have a palette.
- * In this case grab the palette from the render target. */
- if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !This->palette)
- {
- paletteOverride = TRUE;
- TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This);
- This->palette = Src->palette;
- }
-
/* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot
* flip the image nor scale it.
*
* FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
* backends.
*/
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
- && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer
- && surface_can_stretch_rect(Src, This))
+ if (fbo_blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT,
+ &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format_desc,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format_desc))
+ {
+ stretch_rect_fbo(device, src_surface, &src_rect, dst_surface, &dst_rect, Filter);
+ }
+ else if (!stretchx || dst_rect.right - dst_rect.left > src_surface->currentDesc.Width
+ || dst_rect.bottom - dst_rect.top > src_surface->currentDesc.Height)
{
- stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect,
- (IWineD3DSurface *)This, &rect, Filter, upsideDown);
- } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width ||
- rect.y2 - rect.y1 > Src->currentDesc.Height) {
TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n");
- fb_copy_to_texture_direct(This, SrcSurface, &srect, &rect, upsideDown, Filter);
+ fb_copy_to_texture_direct(dst_surface, src_surface, &src_rect, &dst_rect, Filter);
} else {
TRACE("Using hardware stretching to flip / stretch the texture\n");
- fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter);
+ fb_copy_to_texture_hwstretch(dst_surface, src_surface, &src_rect, &dst_rect, Filter);
}
- /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
- if(paletteOverride)
- This->palette = NULL;
-
- if(!(This->Flags & SFLAG_DONOTFREE)) {
- HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
- This->resource.allocatedMemory = NULL;
- This->resource.heapMemory = NULL;
- } else {
- This->Flags &= ~SFLAG_INSYSMEM;
+ if (!(dst_surface->Flags & SFLAG_DONOTFREE))
+ {
+ HeapFree(GetProcessHeap(), 0, dst_surface->resource.heapMemory);
+ dst_surface->resource.allocatedMemory = NULL;
+ dst_surface->resource.heapMemory = NULL;
+ }
+ else
+ {
+ dst_surface->Flags &= ~SFLAG_INSYSMEM;
}
return WINED3D_OK;
- } else if(Src) {
+ }
+ else if (src_surface)
+ {
/* Blit from offscreen surface to render target */
- float glTexCoord[4];
- DWORD oldCKeyFlags = Src->CKeyFlags;
- WINEDDCOLORKEY oldBltCKey = Src->SrcBltCKey;
+ DWORD oldCKeyFlags = src_surface->CKeyFlags;
+ WINEDDCOLORKEY oldBltCKey = src_surface->SrcBltCKey;
struct wined3d_context *context;
- RECT SourceRectangle;
- BOOL paletteOverride = FALSE;
- TRACE("Blt from surface %p to rendertarget %p\n", Src, This);
+ TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
- if(SrcRect) {
- SourceRectangle.left = SrcRect->left;
- SourceRectangle.right = SrcRect->right;
- SourceRectangle.top = SrcRect->top;
- SourceRectangle.bottom = SrcRect->bottom;
- } else {
- SourceRectangle.left = 0;
- SourceRectangle.right = Src->currentDesc.Width;
- SourceRectangle.top = 0;
- SourceRectangle.bottom = Src->currentDesc.Height;
- }
-
- /* When blitting from an offscreen surface to a rendertarget, the source
- * surface is not required to have a palette. Our rendering / conversion
- * code further down the road retrieves the palette from the surface, so
- * it must have a palette set. */
- if (Src->resource.format_desc->format == WINED3DFMT_P8_UINT && !Src->palette)
- {
- paletteOverride = TRUE;
- TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This);
- Src->palette = This->palette;
- }
-
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
- && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer
- && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
- && surface_can_stretch_rect(Src, This))
+ if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
+ && fbo_blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT,
+ &src_rect, src_surface->resource.usage, src_surface->resource.pool,
+ src_surface->resource.format_desc,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool,
+ dst_surface->resource.format_desc))
{
TRACE("Using stretch_rect_fbo\n");
/* The source is always a texture, but never the currently active render target, and the texture
- * contents are never upside down
- */
- stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, (WINED3DRECT *) &SourceRectangle,
- (IWineD3DSurface *)This, &rect, Filter, FALSE);
-
- /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
- if(paletteOverride)
- Src->palette = NULL;
+ * contents are never upside down. */
+ stretch_rect_fbo(device, src_surface, &src_rect, dst_surface, &dst_rect, Filter);
return WINED3D_OK;
}
- if(!CalculateTexRect(Src, &SourceRectangle, glTexCoord)) {
- /* Fall back to software */
- WARN("(%p) Source texture area (%d,%d)-(%d,%d) is too big\n", Src,
- SourceRectangle.left, SourceRectangle.top,
- SourceRectangle.right, SourceRectangle.bottom);
- return WINED3DERR_INVALIDCALL;
+ if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
+ && arbfp_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT,
+ &src_rect, src_surface->resource.usage, src_surface->resource.pool,
+ src_surface->resource.format_desc,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool,
+ dst_surface->resource.format_desc))
+ {
+ return arbfp_blit_surface(device, src_surface, &src_rect, dst_surface, &dst_rect, BLIT_OP_BLIT, Filter);
}
/* Color keying: Check if we have to do a color keyed blt,
/* Use color key from surface */
} else if(Flags & WINEDDBLT_KEYSRCOVERRIDE) {
/* Use color key from DDBltFx */
- Src->CKeyFlags |= WINEDDSD_CKSRCBLT;
- Src->SrcBltCKey = DDBltFx->ddckSrcColorkey;
+ src_surface->CKeyFlags |= WINEDDSD_CKSRCBLT;
+ src_surface->SrcBltCKey = DDBltFx->ddckSrcColorkey;
} else {
/* Do not use color key */
- Src->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
+ src_surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
}
/* Now load the surface */
- surface_internal_preload((IWineD3DSurface *) Src, SRGB_RGB);
+ surface_internal_preload(src_surface, SRGB_RGB);
/* Activate the destination context, set it up for blitting */
- context = context_acquire(myDevice, (IWineD3DSurface *)This, CTXUSAGE_BLIT);
+ context = context_acquire(device, dst_surface);
+ context_apply_blit_state(context, device);
- /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates',
- * while OpenGL coordinates are window relative.
- * Also beware of the origin difference(top left vs bottom left).
- * Also beware that the front buffer's surface size is screen width x screen height,
- * whereas the real gl drawable size is the size of the window.
- */
- if (dstSwapchain && (IWineD3DSurface *)This == dstSwapchain->frontBuffer) {
- RECT windowsize;
- POINT offset = {0,0};
- UINT h;
- ClientToScreen(dstSwapchain->win_handle, &offset);
- GetClientRect(dstSwapchain->win_handle, &windowsize);
- h = windowsize.bottom - windowsize.top;
- rect.x1 -= offset.x; rect.x2 -=offset.x;
- rect.y1 -= offset.y; rect.y2 -=offset.y;
- rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h;
- }
-
- if (!is_identity_fixup(This->resource.format_desc->color_fixup))
- {
- FIXME("Destination format %s has a fixup, this is not supported.\n",
- debug_d3dformat(This->resource.format_desc->format));
- dump_color_fixup_desc(This->resource.format_desc->color_fixup);
- }
+ if (dstSwapchain && dst_surface == dstSwapchain->front_buffer)
+ surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect);
- if (!myDevice->blitter->color_fixup_supported(Src->resource.format_desc->color_fixup))
+ if (!device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT,
+ &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format_desc,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format_desc))
{
- FIXME("Source format %s has an unsupported fixup:\n",
- debug_d3dformat(Src->resource.format_desc->format));
- dump_color_fixup_desc(Src->resource.format_desc->color_fixup);
+ FIXME("Unsupported blit operation falling back to software\n");
+ return WINED3DERR_INVALIDCALL;
}
- myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format_desc,
- Src->texture_target, Src->pow2Width, Src->pow2Height);
+ device->blitter->set_shader((IWineD3DDevice *)device, src_surface);
ENTER_GL();
- /* Bind the texture */
- glBindTexture(Src->texture_target, Src->texture_name);
- checkGLcall("glBindTexture");
-
- /* Filtering for StretchRect */
- glTexParameteri(Src->texture_target, GL_TEXTURE_MAG_FILTER,
- wined3d_gl_mag_filter(magLookup, Filter));
- checkGLcall("glTexParameteri");
- glTexParameteri(Src->texture_target, GL_TEXTURE_MIN_FILTER,
- wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
- checkGLcall("glTexParameteri");
- glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- checkGLcall("glTexEnvi");
-
/* This is for color keying */
if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
glEnable(GL_ALPHA_TEST);
/* When the primary render target uses P8, the alpha component contains the palette index.
* Which means that the colorkey is one of the palette entries. In other cases pixels that
* should be masked away have alpha set to 0. */
- if(primary_render_target_is_p8(myDevice))
- glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0f);
+ if (primary_render_target_is_p8(device))
+ glAlphaFunc(GL_NOTEQUAL, (float)src_surface->SrcBltCKey.dwColorSpaceLowValue / 256.0f);
else
glAlphaFunc(GL_NOTEQUAL, 0.0f);
checkGLcall("glAlphaFunc");
/* Draw a textured quad
*/
- glBegin(GL_QUADS);
-
- glColor3f(1.0f, 1.0f, 1.0f);
- glTexCoord2f(glTexCoord[0], glTexCoord[2]);
- glVertex3f(rect.x1, rect.y1, 0.0f);
-
- glTexCoord2f(glTexCoord[0], glTexCoord[3]);
- glVertex3f(rect.x1, rect.y2, 0.0f);
-
- glTexCoord2f(glTexCoord[1], glTexCoord[3]);
- glVertex3f(rect.x2, rect.y2, 0.0f);
-
- glTexCoord2f(glTexCoord[1], glTexCoord[2]);
- glVertex3f(rect.x2, rect.y1, 0.0f);
-
- glEnd();
- checkGLcall("glEnd");
+ draw_textured_quad(src_surface, &src_rect, &dst_rect, Filter);
if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
glDisable(GL_ALPHA_TEST);
checkGLcall("glDisable(GL_ALPHA_TEST)");
}
- glBindTexture(Src->texture_target, 0);
- checkGLcall("glBindTexture(Src->texture_target, 0)");
-
/* Restore the color key parameters */
- Src->CKeyFlags = oldCKeyFlags;
- Src->SrcBltCKey = oldBltCKey;
-
- /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
- if(paletteOverride)
- Src->palette = NULL;
+ src_surface->CKeyFlags = oldCKeyFlags;
+ src_surface->SrcBltCKey = oldBltCKey;
LEAVE_GL();
/* Leave the opengl state valid for blitting */
- myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice);
+ device->blitter->unset_shader((IWineD3DDevice *)device);
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ if (wined3d_settings.strict_draw_ordering || (dstSwapchain
+ && (dst_surface == dstSwapchain->front_buffer
+ || dstSwapchain->num_contexts > 1)))
+ wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
/* The surface is now in the drawable. On onscreen surfaces or without fbos the texture
* is outdated now
*/
- IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INDRAWABLE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE);
return WINED3D_OK;
} else {
/* Source-Less Blit to render target */
if (Flags & WINEDDBLT_COLORFILL) {
- /* This is easy to handle for the D3D Device... */
DWORD color;
TRACE("Colorfill\n");
- /* This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0] || dstSwapchain
- must be true if we are here */
- if (This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0] &&
- !(This == (IWineD3DSurfaceImpl*) dstSwapchain->frontBuffer ||
- (dstSwapchain->backBuffer && This == (IWineD3DSurfaceImpl*) dstSwapchain->backBuffer[0]))) {
- TRACE("Surface is higher back buffer, falling back to software\n");
- return WINED3DERR_INVALIDCALL;
- }
-
/* The color as given in the Blt function is in the format of the frame-buffer...
* 'clear' expect it in ARGB format => we need to do some conversion :-)
*/
- if (This->resource.format_desc->format == WINED3DFMT_P8_UINT)
- {
- DWORD alpha;
-
- if (primary_render_target_is_p8(myDevice)) alpha = DDBltFx->u5.dwFillColor << 24;
- else alpha = 0xFF000000;
-
- if (This->palette) {
- color = (alpha |
- (This->palette->palents[DDBltFx->u5.dwFillColor].peRed << 16) |
- (This->palette->palents[DDBltFx->u5.dwFillColor].peGreen << 8) |
- (This->palette->palents[DDBltFx->u5.dwFillColor].peBlue));
- } else {
- color = alpha;
- }
- }
- else if (This->resource.format_desc->format == WINED3DFMT_B5G6R5_UNORM)
+ if (!surface_convert_color_to_argb(dst_surface, DDBltFx->u5.dwFillColor, &color))
{
- if (DDBltFx->u5.dwFillColor == 0xFFFF) {
- color = 0xFFFFFFFF;
- } else {
- color = ((0xFF000000) |
- ((DDBltFx->u5.dwFillColor & 0xF800) << 8) |
- ((DDBltFx->u5.dwFillColor & 0x07E0) << 5) |
- ((DDBltFx->u5.dwFillColor & 0x001F) << 3));
- }
+ /* The color conversion function already prints an error, so need to do it here */
+ return WINED3DERR_INVALIDCALL;
}
- else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8_UNORM
- || This->resource.format_desc->format == WINED3DFMT_B8G8R8X8_UNORM)
+
+ if (ffp_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_COLOR_FILL,
+ NULL, 0, 0, NULL,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool,
+ dst_surface->resource.format_desc))
{
- color = 0xFF000000 | DDBltFx->u5.dwFillColor;
+ return ffp_blit.color_fill(device, dst_surface, &dst_rect, color);
}
- else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)
+ else if (cpu_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_COLOR_FILL,
+ NULL, 0, 0, NULL,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool,
+ dst_surface->resource.format_desc))
{
- color = DDBltFx->u5.dwFillColor;
+ return cpu_blit.color_fill(device, dst_surface, &dst_rect, color);
}
- else {
- ERR("Wrong surface type for BLT override(Format doesn't match) !\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- TRACE("(%p) executing Render Target override, color = %x\n", This, color);
- IWineD3DDeviceImpl_ClearSurface(myDevice, This, 1 /* Number of rectangles */,
- &rect, WINED3DCLEAR_TARGET, color, 0.0f /* Z */, 0 /* Stencil */);
- return WINED3D_OK;
+ return WINED3DERR_INVALIDCALL;
}
}
static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *DestRect,
IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx)
{
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
float depth;
if (Flags & WINEDDBLT_DEPTHFILL) {
ERR("Unexpected format for depth fill: %s\n", debug_d3dformat(This->resource.format_desc->format));
}
- return IWineD3DDevice_Clear((IWineD3DDevice *) myDevice,
- DestRect == NULL ? 0 : 1,
- (const WINED3DRECT *)DestRect,
- WINED3DCLEAR_ZBUFFER,
- 0x00000000,
- depth,
- 0x00000000);
+ return IWineD3DDevice_Clear((IWineD3DDevice *)device, DestRect ? 1 : 0, (const WINED3DRECT *)DestRect,
+ WINED3DCLEAR_ZBUFFER, 0x00000000, depth, 0x00000000);
}
FIXME("(%p): Unsupp depthstencil blit\n", This);
const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage));
/* Accessing the depth stencil is supposed to fail between a BeginScene and EndScene pair,
* except depth blits, which seem to work
*/
- if(iface == myDevice->stencilBufferTarget || (SrcSurface && SrcSurface == myDevice->stencilBufferTarget)) {
- if(myDevice->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) {
+ if (This == device->depth_stencil || (Src && Src == device->depth_stencil))
+ {
+ if (device->inScene && !(Flags & WINEDDBLT_DEPTHFILL))
+ {
TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
} else if(IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx) == WINED3D_OK) {
}
/* Special cases for RenderTargets */
- if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) ||
- ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) {
- if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK;
+ if ((This->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ || (Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET)))
+ {
+ if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(This, DestRect, Src, SrcRect, Flags, DDBltFx, Filter)))
+ return WINED3D_OK;
}
/* For the rest call the X11 surface implementation.
{
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
IWineD3DSurfaceImpl *srcImpl = (IWineD3DSurfaceImpl *) Source;
- IWineD3DDeviceImpl *myDevice = This->resource.device;
+ IWineD3DDeviceImpl *device = This->resource.device;
TRACE("(%p)->(%d, %d, %p, %p, %08x\n", iface, dstx, dsty, Source, rsrc, trans);
return WINEDDERR_SURFACEBUSY;
}
- if(myDevice->inScene &&
- (iface == myDevice->stencilBufferTarget ||
- (Source == myDevice->stencilBufferTarget))) {
+ if (device->inScene && (This == device->depth_stencil || srcImpl == device->depth_stencil))
+ {
TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
RECT SrcRect, DstRect;
DWORD Flags=0;
- if(rsrc) {
- SrcRect.left = rsrc->left;
- SrcRect.top= rsrc->top;
- SrcRect.bottom = rsrc->bottom;
- SrcRect.right = rsrc->right;
- } else {
- SrcRect.left = 0;
- SrcRect.top = 0;
- SrcRect.right = srcImpl->currentDesc.Width;
- SrcRect.bottom = srcImpl->currentDesc.Height;
- }
+ surface_get_rect(srcImpl, rsrc, &SrcRect);
DstRect.left = dstx;
DstRect.top=dsty;
if(trans & WINEDDBLTFAST_DONOTWAIT)
Flags |= WINEDDBLT_DONOTWAIT;
- if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL, WINED3DTEXF_POINT) == WINED3D_OK) return WINED3D_OK;
+ if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(This,
+ &DstRect, srcImpl, &SrcRect, Flags, NULL, WINED3DTEXF_POINT)))
+ return WINED3D_OK;
}
if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
|| This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
{
- int bpp;
- GLenum format, internal, type;
- CONVERT_TYPES convert;
-
- /* Check if we are using a RTL mode which uses texturing for uploads */
- BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX);
-
- /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */
- d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE);
-
- if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION))
+ if(This->resource.usage & WINED3DUSAGE_RENDERTARGET)
{
- IWineD3DDeviceImpl *device = This->resource.device;
- struct wined3d_context *context;
-
/* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */
IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL);
/* We want to force a palette refresh, so mark the drawable as not being up to date */
IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
-
- /* Re-upload the palette */
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
- d3dfmt_p8_upload_palette(iface, convert);
- context_release(context);
} else {
if(!(This->Flags & SFLAG_INSYSMEM)) {
TRACE("Palette changed with surface that does not have an up to date system memory copy\n");
3: WARN and return WINED3DERR_NOTAVAILABLE;
4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target.
*/
- WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n",
- This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height);
- This->Flags |= SFLAG_OVERSIZE;
-
- /* This will be initialized on the first blt */
- This->glRect.left = 0;
- This->glRect.top = 0;
- This->glRect.right = 0;
- This->glRect.bottom = 0;
- } else {
- /* Check this after the oversize check - do not make an oversized surface a texture_rectangle one.
- Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
+ if(This->resource.pool == WINED3DPOOL_DEFAULT || This->resource.pool == WINED3DPOOL_MANAGED)
+ {
+ WARN("(%p) Unable to allocate a surface which exceeds the maximum OpenGL texture size\n", This);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* We should never use this surface in combination with OpenGL! */
+ TRACE("(%p) Creating an oversized surface: %ux%u\n", This, This->pow2Width, This->pow2Height);
+ }
+ else
+ {
+ /* 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.
*/
This->pow2Height = This->currentDesc.Height;
This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
}
-
- /* No oversize, gl rect is the full texture size */
- This->Flags &= ~SFLAG_OVERSIZE;
- This->glRect.left = 0;
- This->glRect.top = 0;
- This->glRect.right = This->pow2Width;
- This->glRect.bottom = This->pow2Height;
}
if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
switch(wined3d_settings.offscreen_rendering_mode) {
case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break;
- case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break;
case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break;
}
}
return WINED3D_OK;
}
-struct depth_blt_info
-{
- GLenum binding;
- GLenum bind_target;
- enum tex_types tex_type;
- GLfloat coords[4][3];
-};
-
-static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, struct depth_blt_info *info)
-{
- GLfloat (*coords)[3] = info->coords;
-
- switch (target)
- {
- default:
- FIXME("Unsupported texture target %#x\n", target);
- /* Fall back to GL_TEXTURE_2D */
- case GL_TEXTURE_2D:
- info->binding = GL_TEXTURE_BINDING_2D;
- info->bind_target = GL_TEXTURE_2D;
- info->tex_type = tex_2d;
- coords[0][0] = 0.0f; coords[0][1] = 1.0f; coords[0][2] = 0.0f;
- coords[1][0] = 1.0f; coords[1][1] = 1.0f; coords[1][2] = 0.0f;
- coords[2][0] = 0.0f; coords[2][1] = 0.0f; coords[2][2] = 0.0f;
- coords[3][0] = 1.0f; coords[3][1] = 0.0f; coords[3][2] = 0.0f;
- break;
-
- case GL_TEXTURE_RECTANGLE_ARB:
- info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
- info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
- info->tex_type = tex_rect;
- coords[0][0] = 0.0f; coords[0][1] = h; coords[0][2] = 0.0f;
- coords[1][0] = w; coords[1][1] = h; coords[1][2] = 0.0f;
- coords[2][0] = 0.0f; coords[2][1] = 0.0f; coords[2][2] = 0.0f;
- coords[3][0] = w; coords[3][1] = 0.0f; coords[3][2] = 0.0f;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- info->tex_type = tex_cube;
- coords[0][0] = 1.0f; coords[0][1] = -1.0f; coords[0][2] = 1.0f;
- coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f;
- coords[2][0] = 1.0f; coords[2][1] = 1.0f; coords[2][2] = 1.0f;
- coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- info->tex_type = tex_cube;
- coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f;
- coords[1][0] = -1.0f; coords[1][1] = -1.0f; coords[1][2] = 1.0f;
- coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f;
- coords[3][0] = -1.0f; coords[3][1] = 1.0f; coords[3][2] = 1.0f;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- info->tex_type = tex_cube;
- coords[0][0] = -1.0f; coords[0][1] = 1.0f; coords[0][2] = 1.0f;
- coords[1][0] = 1.0f; coords[1][1] = 1.0f; coords[1][2] = 1.0f;
- coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f;
- coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- info->tex_type = tex_cube;
- coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f;
- coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f;
- coords[2][0] = -1.0f; coords[2][1] = -1.0f; coords[2][2] = 1.0f;
- coords[3][0] = 1.0f; coords[3][1] = -1.0f; coords[3][2] = 1.0f;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- info->tex_type = tex_cube;
- coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = 1.0f;
- coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = 1.0f;
- coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = 1.0f;
- coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = 1.0f;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- info->tex_type = tex_cube;
- coords[0][0] = 1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f;
- coords[1][0] = -1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f;
- coords[2][0] = 1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f;
- coords[3][0] = -1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f;
- }
-}
-
/* GL locking is done by the caller */
-static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target)
+static void surface_depth_blt(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info,
+ GLuint texture, GLsizei w, GLsizei h, GLenum target)
{
IWineD3DDeviceImpl *device = This->resource.device;
- struct depth_blt_info info;
+ GLint compare_mode = GL_NONE;
+ struct blt_info info;
GLint old_binding = 0;
glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glViewport(0, 0, w, h);
- surface_get_depth_blt_info(target, w, h, &info);
+ surface_get_blt_info(target, NULL, w, h, &info);
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
glGetIntegerv(info.binding, &old_binding);
glBindTexture(info.bind_target, texture);
+ if (gl_info->supported[ARB_SHADOW])
+ {
+ glGetTexParameteriv(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, &compare_mode);
+ if (compare_mode != GL_NONE) glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ }
- device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, info.tex_type);
+ device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device,
+ info.tex_type, &This->ds_current_size);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord3fv(info.coords[0]);
glVertex2f(1.0f, 1.0f);
glEnd();
+ if (compare_mode != GL_NONE) glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, compare_mode);
glBindTexture(info.bind_target, old_binding);
glPopAttrib();
device->shader_backend->shader_deselect_depth_blt((IWineD3DDevice *)device);
}
-void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) {
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-
- TRACE("(%p) New location %#x\n", This, location);
+void surface_modify_ds_location(IWineD3DSurfaceImpl *surface,
+ DWORD location, UINT w, UINT h)
+{
+ TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h);
- if (location & ~SFLAG_DS_LOCATIONS) {
- FIXME("(%p) Invalid location (%#x) specified\n", This, location);
- }
+ if (location & ~SFLAG_DS_LOCATIONS)
+ FIXME("Invalid location (%#x) specified.\n", location);
- This->Flags &= ~SFLAG_DS_LOCATIONS;
- This->Flags |= location;
+ surface->ds_current_size.cx = w;
+ surface->ds_current_size.cy = h;
+ surface->Flags &= ~SFLAG_DS_LOCATIONS;
+ surface->Flags |= location;
}
/* Context activation is done by the caller. */
-void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location)
+void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_context *context, DWORD location)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- IWineD3DDeviceImpl *device = This->resource.device;
+ IWineD3DDeviceImpl *device = surface->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
- TRACE("(%p) New location %#x\n", This, location);
+ TRACE("surface %p, new location %#x.\n", surface, location);
/* TODO: Make this work for modes other than FBO */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return;
- if (This->Flags & location) {
- TRACE("(%p) Location (%#x) is already up to date\n", This, location);
- return;
+ if (!(surface->Flags & location))
+ {
+ surface->ds_current_size.cx = 0;
+ surface->ds_current_size.cy = 0;
}
- if (This->current_renderbuffer) {
- FIXME("(%p) Not supported with fixed up depth stencil\n", This);
+ if (surface->ds_current_size.cx == surface->currentDesc.Width
+ && surface->ds_current_size.cy == surface->currentDesc.Height)
+ {
+ TRACE("Location (%#x) is already up to date.\n", location);
return;
}
- if (location == SFLAG_DS_OFFSCREEN) {
- if (This->Flags & SFLAG_DS_ONSCREEN) {
- GLint old_binding = 0;
- GLenum bind_target;
-
- TRACE("(%p) Copying onscreen depth buffer to depth texture\n", This);
-
- ENTER_GL();
-
- if (!device->depth_blt_texture) {
- glGenTextures(1, &device->depth_blt_texture);
- }
+ if (surface->current_renderbuffer)
+ {
+ FIXME("Not supported with fixed up depth stencil.\n");
+ return;
+ }
- /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
- * directly on the FBO texture. That's because we need to flip. */
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
- if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
- {
- glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
- bind_target = GL_TEXTURE_RECTANGLE_ARB;
- } else {
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
- bind_target = GL_TEXTURE_2D;
- }
- glBindTexture(bind_target, device->depth_blt_texture);
- glCopyTexImage2D(bind_target, This->texture_level, This->resource.format_desc->glInternal,
- 0, 0, This->currentDesc.Width, This->currentDesc.Height, 0);
- glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
- glBindTexture(bind_target, old_binding);
-
- /* Setup the destination */
- if (!device->depth_blt_rb) {
- gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb);
- checkGLcall("glGenRenderbuffersEXT");
- }
- if (device->depth_blt_rb_w != This->currentDesc.Width
- || device->depth_blt_rb_h != This->currentDesc.Height) {
- gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb);
- checkGLcall("glBindRenderbufferEXT");
- gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
- This->currentDesc.Width, This->currentDesc.Height);
- checkGLcall("glRenderbufferStorageEXT");
- device->depth_blt_rb_w = This->currentDesc.Width;
- device->depth_blt_rb_h = This->currentDesc.Height;
- }
+ if (!(surface->Flags & SFLAG_LOCATIONS))
+ {
+ FIXME("No up to date depth stencil location.\n");
+ surface->Flags |= location;
+ return;
+ }
- context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
- gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb);
- checkGLcall("glFramebufferRenderbufferEXT");
- context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, iface, FALSE);
+ if (location == SFLAG_DS_OFFSCREEN)
+ {
+ GLint old_binding = 0;
+ GLenum bind_target;
- /* Do the actual blit */
- surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target);
- checkGLcall("depth_blt");
+ TRACE("Copying onscreen depth buffer to depth texture.\n");
- if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
- else context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ ENTER_GL();
- LEAVE_GL();
+ if (!device->depth_blt_texture)
+ {
+ glGenTextures(1, &device->depth_blt_texture);
+ }
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
+ * directly on the FBO texture. That's because we need to flip. */
+ context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
+ bind_target = GL_TEXTURE_RECTANGLE_ARB;
}
else
{
- FIXME("No up to date depth stencil location\n");
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
+ bind_target = GL_TEXTURE_2D;
+ }
+ glBindTexture(bind_target, device->depth_blt_texture);
+ glCopyTexImage2D(bind_target, surface->texture_level, surface->resource.format_desc->glInternal,
+ 0, 0, surface->currentDesc.Width, surface->currentDesc.Height, 0);
+ glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
+ glBindTexture(bind_target, old_binding);
+
+ /* Setup the destination */
+ if (!device->depth_blt_rb)
+ {
+ gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb);
+ checkGLcall("glGenRenderbuffersEXT");
+ }
+ if (device->depth_blt_rb_w != surface->currentDesc.Width
+ || device->depth_blt_rb_h != surface->currentDesc.Height)
+ {
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb);
+ checkGLcall("glBindRenderbufferEXT");
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
+ surface->currentDesc.Width, surface->currentDesc.Height);
+ checkGLcall("glRenderbufferStorageEXT");
+ device->depth_blt_rb_w = surface->currentDesc.Width;
+ device->depth_blt_rb_h = surface->currentDesc.Height;
}
- } else if (location == SFLAG_DS_ONSCREEN) {
- if (This->Flags & SFLAG_DS_OFFSCREEN) {
- TRACE("(%p) Copying depth texture to onscreen depth buffer\n", This);
- ENTER_GL();
+ context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb);
+ checkGLcall("glFramebufferRenderbufferEXT");
+ context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, surface, FALSE);
- context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
- surface_depth_blt(This, This->texture_name, This->currentDesc.Width,
- This->currentDesc.Height, This->texture_target);
- checkGLcall("depth_blt");
+ /* Do the actual blit */
+ surface_depth_blt(surface, gl_info, device->depth_blt_texture,
+ surface->currentDesc.Width, surface->currentDesc.Height, bind_target);
+ checkGLcall("depth_blt");
- if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
+ if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
+ else context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
- LEAVE_GL();
+ LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
- }
- else
- {
- FIXME("No up to date depth stencil location\n");
- }
- } else {
- ERR("(%p) Invalid location (%#x) specified\n", This, location);
+ if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
}
+ else if (location == SFLAG_DS_ONSCREEN)
+ {
+ TRACE("Copying depth texture to onscreen depth buffer.\n");
+
+ ENTER_GL();
+
+ context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
+ surface_depth_blt(surface, gl_info, surface->texture_name,
+ surface->currentDesc.Width, surface->currentDesc.Height, surface->texture_target);
+ checkGLcall("depth_blt");
+
+ if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
+
+ LEAVE_GL();
- This->Flags |= location;
+ if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
+ }
+ else
+ {
+ ERR("Invalid location (%#x) specified.\n", location);
+ }
+
+ surface->Flags |= location;
+ surface->ds_current_size.cx = surface->currentDesc.Width;
+ surface->ds_current_size.cy = surface->currentDesc.Height;
}
static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) {
TRACE("(%p)->(%s, %s)\n", iface, debug_surflocation(flag),
persistent ? "TRUE" : "FALSE");
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- if (surface_is_offscreen(iface))
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ if (surface_is_offscreen(This))
{
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
}
}
-struct coords {
- GLfloat x, y, z;
-};
-
-struct float_rect
-{
- float l;
- float t;
- float r;
- float b;
-};
-
-static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f)
-{
- f->l = ((r->left * 2.0f) / w) - 1.0f;
- f->t = ((r->top * 2.0f) / h) - 1.0f;
- f->r = ((r->right * 2.0f) / w) - 1.0f;
- f->b = ((r->bottom * 2.0f) / h) - 1.0f;
-}
-
static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
{
IWineD3DDeviceImpl *device = This->resource.device;
- IWineD3DBaseTextureImpl *texture;
+ IWineD3DSwapChainImpl *swapchain;
struct wined3d_context *context;
- struct coords coords[4];
- RECT rect;
- GLenum bind_target;
- struct float_rect f;
+ RECT src_rect, dst_rect;
- if(rect_in) {
- rect = *rect_in;
- } else {
- rect.left = 0;
- rect.top = 0;
- rect.right = This->currentDesc.Width;
- rect.bottom = This->currentDesc.Height;
- }
+ surface_get_rect(This, rect_in, &src_rect);
- switch (This->texture_target)
+ context = context_acquire(device, This);
+ context_apply_blit_state(context, device);
+ if (context->render_offscreen)
{
- case GL_TEXTURE_2D:
- bind_target = GL_TEXTURE_2D;
-
- coords[0].x = (float)rect.left / This->pow2Width;
- coords[0].y = (float)rect.top / This->pow2Height;
- coords[0].z = 0;
-
- coords[1].x = (float)rect.left / This->pow2Width;
- coords[1].y = (float)rect.bottom / This->pow2Height;
- coords[1].z = 0;
-
- coords[2].x = (float)rect.right / This->pow2Width;
- coords[2].y = (float)rect.bottom / This->pow2Height;
- coords[2].z = 0;
-
- coords[3].x = (float)rect.right / This->pow2Width;
- coords[3].y = (float)rect.top / This->pow2Height;
- coords[3].z = 0;
- break;
-
- case GL_TEXTURE_RECTANGLE_ARB:
- bind_target = GL_TEXTURE_RECTANGLE_ARB;
- coords[0].x = rect.left; coords[0].y = rect.top; coords[0].z = 0;
- coords[1].x = rect.left; coords[1].y = rect.bottom; coords[1].z = 0;
- coords[2].x = rect.right; coords[2].y = rect.bottom; coords[2].z = 0;
- coords[3].x = rect.right; coords[3].y = rect.top; coords[3].z = 0;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
- coords[0].x = 1; coords[0].y = -f.t; coords[0].z = -f.l;
- coords[1].x = 1; coords[1].y = -f.b; coords[1].z = -f.l;
- coords[2].x = 1; coords[2].y = -f.b; coords[2].z = -f.r;
- coords[3].x = 1; coords[3].y = -f.t; coords[3].z = -f.r;
- break;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
- coords[0].x = -1; coords[0].y = -f.t; coords[0].z = f.l;
- coords[1].x = -1; coords[1].y = -f.b; coords[1].z = f.l;
- coords[2].x = -1; coords[2].y = -f.b; coords[2].z = f.r;
- coords[3].x = -1; coords[3].y = -f.t; coords[3].z = f.r;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
- coords[0].x = f.l; coords[0].y = 1; coords[0].z = f.t;
- coords[1].x = f.l; coords[1].y = 1; coords[1].z = f.b;
- coords[2].x = f.r; coords[2].y = 1; coords[2].z = f.b;
- coords[3].x = f.r; coords[3].y = 1; coords[3].z = f.t;
- break;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
- coords[0].x = f.l; coords[0].y = -1; coords[0].z = -f.t;
- coords[1].x = f.l; coords[1].y = -1; coords[1].z = -f.b;
- coords[2].x = f.r; coords[2].y = -1; coords[2].z = -f.b;
- coords[3].x = f.r; coords[3].y = -1; coords[3].z = -f.t;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
- coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1;
- coords[1].x = f.l; coords[1].y = -f.b; coords[1].z = 1;
- coords[2].x = f.r; coords[2].y = -f.b; coords[2].z = 1;
- coords[3].x = f.r; coords[3].y = -f.t; coords[3].z = 1;
- break;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
- coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1;
- coords[1].x = -f.l; coords[1].y = -f.b; coords[1].z = -1;
- coords[2].x = -f.r; coords[2].y = -f.b; coords[2].z = -1;
- coords[3].x = -f.r; coords[3].y = -f.t; coords[3].z = -1;
- break;
-
- default:
- ERR("Unexpected texture target %#x\n", This->texture_target);
- return;
+ dst_rect.left = src_rect.left;
+ dst_rect.right = src_rect.right;
+ dst_rect.top = src_rect.bottom;
+ dst_rect.bottom = src_rect.top;
}
-
- context = context_acquire(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);
-
- ENTER_GL();
-
- glEnable(bind_target);
- checkGLcall("glEnable(bind_target)");
- glBindTexture(bind_target, This->texture_name);
- checkGLcall("glBindTexture(bind_target, This->texture_name)");
- glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- checkGLcall("glTexParameteri");
- glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- checkGLcall("glTexParameteri");
-
- if (context->render_offscreen)
+ else
{
- LONG tmp = rect.top;
- rect.top = rect.bottom;
- rect.bottom = tmp;
+ dst_rect = src_rect;
}
- glBegin(GL_QUADS);
- glTexCoord3fv(&coords[0].x);
- glVertex2i(rect.left, rect.top);
-
- glTexCoord3fv(&coords[1].x);
- glVertex2i(rect.left, rect.bottom);
-
- glTexCoord3fv(&coords[2].x);
- glVertex2i(rect.right, rect.bottom);
-
- glTexCoord3fv(&coords[3].x);
- glVertex2i(rect.right, rect.top);
- glEnd();
- checkGLcall("glEnd");
+ if ((This->Flags & SFLAG_SWAPCHAIN) && This == ((IWineD3DSwapChainImpl *)This->container)->front_buffer)
+ surface_translate_frontbuffer_coords(This, context->win_handle, &dst_rect);
- glDisable(bind_target);
- checkGLcall("glDisable(bind_target)");
+ device->blitter->set_shader((IWineD3DDevice *) device, This);
+ ENTER_GL();
+ draw_textured_quad(This, &src_rect, &dst_rect, WINED3DTEXF_POINT);
LEAVE_GL();
- wglFlush(); /* Flush to ensure ordering across contexts. */
+ device->blitter->set_shader((IWineD3DDevice *) device, This);
- /* We changed the filtering settings on the texture. Inform the
- * container about this to get the filters reset properly next draw. */
- if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)This, &IID_IWineD3DBaseTexture, (void **)&texture)))
- {
- texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
- texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
- texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
- IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture);
- }
+ swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL;
+ if (wined3d_settings.strict_draw_ordering || (swapchain
+ && (This == swapchain->front_buffer || swapchain->num_contexts > 1)))
+ wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
}
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
IWineD3DDeviceImpl *device = This->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- GLenum format, internal, type;
+ struct wined3d_format_desc desc;
CONVERT_TYPES convert;
- int bpp;
int width, pitch, outpitch;
BYTE *mem;
BOOL drawable_read_ok = TRUE;
BOOL in_fbo = FALSE;
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- if (surface_is_offscreen(iface))
+ if (This->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ if (flag == SFLAG_INTEXTURE)
+ {
+ struct wined3d_context *context = context_acquire(device, NULL);
+ surface_load_ds_location(This, context, SFLAG_DS_OFFSCREEN);
+ context_release(context);
+ return WINED3D_OK;
+ }
+ else
+ {
+ FIXME("Unimplemented location %#x for depth/stencil buffers.\n", flag);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ if (surface_is_offscreen(This))
{
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets.
* Prefer SFLAG_INTEXTURE. */
{
struct wined3d_context *context = NULL;
- if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ if (!device->isInDraw) context = context_acquire(device, NULL);
surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE));
- surface_download_data(This);
+ surface_download_data(This, gl_info);
if (context) context_release(context);
}
if(This->Flags & SFLAG_INTEXTURE) {
surface_blt_to_drawable(This, rect);
} else {
+ int byte_count;
if((This->Flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX) {
/* This needs a shader to convert the srgb data sampled from the GL texture into RGB
* values, otherwise we get incorrect values in the target. For now go the slow way
IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
}
- d3dfmt_get_conv(This, TRUE /* We need color keying */, FALSE /* We won't use textures */, &format, &internal, &type, &convert, &bpp, FALSE);
+ d3dfmt_get_conv(This, FALSE /* We need color keying */, FALSE /* We won't use textures */, &desc, &convert);
/* The width is in 'length' not in bytes */
width = This->currentDesc.Width;
TRACE("Removing the pbo attached to surface %p\n", This);
- if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
- surface_remove_pbo(This);
+ if (!device->isInDraw) context = context_acquire(device, NULL);
+ surface_remove_pbo(This, gl_info);
if (context) context_release(context);
}
if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
int height = This->currentDesc.Height;
+ byte_count = desc.conv_byte_count;
/* Stick to the alignment for the converted surface too, makes it easier to load the surface */
- outpitch = width * bpp;
+ outpitch = width * byte_count;
outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
} else {
This->Flags &= ~SFLAG_CONVERTED;
mem = This->resource.allocatedMemory;
+ byte_count = desc.byte_count;
}
- flush_to_framebuffer_drawpixels(This, format, type, bpp, mem);
+ flush_to_framebuffer_drawpixels(This, desc.glFormat, desc.glType, byte_count, mem);
/* Don't delete PBO memory */
if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO))
struct wined3d_context *context = NULL;
d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */,
- &format, &internal, &type, &convert, &bpp, srgb);
+ &desc, &convert);
if(srgb) {
if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) {
IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
}
- if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ if (!device->isInDraw) context = context_acquire(device, NULL);
- surface_prepare_texture(This, srgb);
+ surface_prepare_texture(This, gl_info, srgb);
surface_bind_and_dirtify(This, srgb);
if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
/* Don't use PBOs for converted surfaces. During PBO conversion we look at SFLAG_CONVERTED
* but it isn't set (yet) in all cases it is getting called. */
- if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) {
+ if(((convert != NO_CONVERSION) || desc.convert) && (This->Flags & SFLAG_PBO)) {
TRACE("Removing the pbo attached to surface %p\n", This);
- surface_remove_pbo(This);
+ surface_remove_pbo(This, gl_info);
}
- if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
+ if(desc.convert) {
+ /* This code is entered for texture formats which need a fixup. */
int height = This->currentDesc.Height;
/* Stick to the alignment for the converted surface too, makes it easier to load the surface */
- outpitch = width * bpp;
+ outpitch = width * desc.conv_byte_count;
+ outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+
+ mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
+ if(!mem) {
+ ERR("Out of memory %d, %d!\n", outpitch, height);
+ if (context) context_release(context);
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+ desc.convert(This->resource.allocatedMemory, mem, pitch, width, height);
+ } else if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
+ /* This code is only entered for color keying fixups */
+ int height = This->currentDesc.Height;
+
+ /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
+ outpitch = width * desc.conv_byte_count;
outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
return WINED3DERR_OUTOFVIDEOMEMORY;
}
d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);
- }
- else if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
- && (gl_info->supported[EXT_PALETTED_TEXTURE] || device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)))
- {
- d3dfmt_p8_upload_palette(iface, convert);
- mem = This->resource.allocatedMemory;
} else {
mem = This->resource.allocatedMemory;
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
LEAVE_GL();
- if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
- TRACE("non power of two support\n");
- if (mem || (This->Flags & SFLAG_PBO)) {
- surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
- }
- } else {
- /* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory
- * changed. So also keep track of memory changes. In this case the texture has to be reallocated
- */
- if (mem || (This->Flags & SFLAG_PBO)) {
- surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem);
- }
- }
+ if (mem || (This->Flags & SFLAG_PBO))
+ surface_upload_data(This, gl_info, &desc, srgb, mem);
/* Restore the default pitch */
ENTER_GL();
} else if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
switch(wined3d_settings.offscreen_rendering_mode) {
case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break;
- case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break;
case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break;
}
}
return hr;
}
-BOOL surface_is_offscreen(IWineD3DSurface *iface)
+BOOL surface_is_offscreen(IWineD3DSurfaceImpl *surface)
{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
- IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) This->container;
+ IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container;
/* Not on a swapchain - must be offscreen */
- if (!(This->Flags & SFLAG_SWAPCHAIN)) return TRUE;
+ if (!(surface->Flags & SFLAG_SWAPCHAIN)) return TRUE;
/* The front buffer is always onscreen */
- if(iface == swapchain->frontBuffer) return FALSE;
+ if (surface == swapchain->front_buffer) return FALSE;
/* If the swapchain is rendered to an FBO, the backbuffer is
* offscreen, otherwise onscreen */
IWineD3DSurfaceImpl_GetImplType,
IWineD3DSurfaceImpl_DrawOverlay
};
-#undef GLINFO_LOCATION
-#define GLINFO_LOCATION device->adapter->gl_info
static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
/* Context activation is done by the caller. */
static void ffp_blit_free(IWineD3DDevice *iface) { }
+/* This function is used in case of 8bit paletted textures using GL_EXT_paletted_texture */
+/* Context activation is done by the caller. */
+static void ffp_blit_p8_upload_palette(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info)
+{
+ BYTE table[256][4];
+ BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) ? TRUE : FALSE;
+
+ d3dfmt_p8_init_palette(surface, table, colorkey_active);
+
+ TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
+ ENTER_GL();
+ GL_EXTCALL(glColorTableEXT(surface->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
+ LEAVE_GL();
+}
+
/* Context activation is done by the caller. */
-static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
- GLenum textype, UINT width, UINT height)
+static HRESULT ffp_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface)
{
+ IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ enum complex_fixup fixup = get_complex_fixup(surface->resource.format_desc->color_fixup);
+
+ /* When EXT_PALETTED_TEXTURE is around, palette conversion is done by the GPU
+ * else the surface is converted in software at upload time in LoadLocation.
+ */
+ if(fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE])
+ ffp_blit_p8_upload_palette(surface, gl_info);
+
ENTER_GL();
- glEnable(textype);
- checkGLcall("glEnable(textype)");
+ glEnable(surface->texture_target);
+ checkGLcall("glEnable(surface->texture_target)");
LEAVE_GL();
return WINED3D_OK;
}
LEAVE_GL();
}
-static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup)
+static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+ const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+ const struct wined3d_format_desc *src_format_desc,
+ const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+ const struct wined3d_format_desc *dst_format_desc)
{
+ enum complex_fixup src_fixup;
+
+ if (blit_op == BLIT_OP_COLOR_FILL)
+ {
+ if (!(dst_usage & WINED3DUSAGE_RENDERTARGET))
+ {
+ TRACE("Color fill not supported\n");
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ src_fixup = get_complex_fixup(src_format_desc->color_fixup);
if (TRACE_ON(d3d_surface) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
- dump_color_fixup_desc(fixup);
+ dump_color_fixup_desc(src_format_desc->color_fixup);
+ }
+
+ if (blit_op != BLIT_OP_BLIT)
+ {
+ TRACE("Unsupported blit_op=%d\n", blit_op);
+ return FALSE;
+ }
+
+ if (!is_identity_fixup(dst_format_desc->color_fixup))
+ {
+ TRACE("Destination fixups are not supported\n");
+ return FALSE;
+ }
+
+ if (src_fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE])
+ {
+ TRACE("P8 fixup supported\n");
+ return TRUE;
}
/* We only support identity conversions. */
- if (is_identity_fixup(fixup))
+ if (is_identity_fixup(src_format_desc->color_fixup))
{
TRACE("[OK]\n");
return TRUE;
return FALSE;
}
+static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color)
+{
+ return IWineD3DDeviceImpl_ClearSurface(device, dst_surface, 1 /* Number of rectangles */,
+ (const WINED3DRECT*)dst_rect, WINED3DCLEAR_TARGET, fill_color, 0.0f /* Z */, 0 /* Stencil */);
+}
+
const struct blit_shader ffp_blit = {
ffp_blit_alloc,
ffp_blit_free,
ffp_blit_set,
ffp_blit_unset,
- ffp_blit_color_fixup_supported
+ ffp_blit_supported,
+ ffp_blit_color_fill
};
+
+static HRESULT cpu_blit_alloc(IWineD3DDevice *iface)
+{
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void cpu_blit_free(IWineD3DDevice *iface)
+{
+}
+
+/* Context activation is done by the caller. */
+static HRESULT cpu_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface)
+{
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void cpu_blit_unset(IWineD3DDevice *iface)
+{
+}
+
+static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+ const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+ const struct wined3d_format_desc *src_format_desc,
+ const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+ const struct wined3d_format_desc *dst_format_desc)
+{
+ if (blit_op == BLIT_OP_COLOR_FILL)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static HRESULT cpu_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color)
+{
+ WINEDDBLTFX BltFx;
+ memset(&BltFx, 0, sizeof(BltFx));
+ BltFx.dwSize = sizeof(BltFx);
+ BltFx.u5.dwFillColor = color_convert_argb_to_fmt(fill_color, dst_surface->resource.format_desc->format);
+ return IWineD3DBaseSurfaceImpl_Blt((IWineD3DSurface*)dst_surface, dst_rect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
+}
+
+const struct blit_shader cpu_blit = {
+ cpu_blit_alloc,
+ cpu_blit_free,
+ cpu_blit_set,
+ cpu_blit_unset,
+ cpu_blit_supported,
+ cpu_blit_color_fill
+};
+
+static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+ const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+ const struct wined3d_format_desc *src_format_desc,
+ const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+ const struct wined3d_format_desc *dst_format_desc)
+{
+ if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
+ return FALSE;
+
+ /* We only support blitting. Things like color keying / color fill should
+ * be handled by other blitters.
+ */
+ if (blit_op != BLIT_OP_BLIT)
+ return FALSE;
+
+ /* Source and/or destination need to be on the GL side */
+ if (src_pool == WINED3DPOOL_SYSTEMMEM || dst_pool == WINED3DPOOL_SYSTEMMEM)
+ return FALSE;
+
+ if(!((src_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (src_usage & WINED3DUSAGE_RENDERTARGET))
+ && ((dst_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
+ return FALSE;
+
+ if (!is_identity_fixup(src_format_desc->color_fixup) ||
+ !is_identity_fixup(dst_format_desc->color_fixup))
+ return FALSE;
+
+ if (!(src_format_desc->format == dst_format_desc->format
+ || (is_identity_fixup(src_format_desc->color_fixup)
+ && is_identity_fixup(dst_format_desc->color_fixup))))
+ return FALSE;
+
+ return TRUE;
+}
return ret;
}
-
-/* Do NOT define GLINFO_LOCATION in this file. THIS CODE MUST NOT USE IT */
-
/* *******************************************
IWineD3DSurface IUnknown parts follow
******************************************* */
DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+ const struct wined3d_format_desc *format_desc = This->resource.format_desc;
DWORD ret;
TRACE("(%p)\n", This);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format,
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format,
&This->resource.device->adapter->gl_info);
if (This->resource.format_desc->format != WINED3DFMT_UNKNOWN)
HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+ const struct wined3d_format_desc *format_desc = This->resource.format_desc;
int extraline = 0;
SYSTEM_INFO sysInfo;
BITMAPINFO* b_info;
}
}
+static inline BYTE cliptobyte(int x)
+{
+ return (BYTE) ((x < 0) ? 0 : ((x > 255) ? 255 : x));
+}
+
+static void convert_yuy2_x8r8g8b8(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ unsigned int x, y;
+ int c2, d, e, r2 = 0, g2 = 0, b2 = 0;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ const BYTE *src_line = src + y * pitch_in;
+ DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV:
+ * C = Y - 16; D = U - 128; E = V - 128;
+ * R = cliptobyte((298 * C + 409 * E + 128) >> 8);
+ * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8);
+ * B = cliptobyte((298 * C + 516 * D + 128) >> 8);
+ * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V .
+ * U and V are shared between the pixels.
+ */
+ if (!(x & 1)) /* for every even pixel, read new U and V */
+ {
+ d = (int) src_line[1] - 128;
+ e = (int) src_line[3] - 128;
+ r2 = 409 * e + 128;
+ g2 = - 100 * d - 208 * e + 128;
+ b2 = 516 * d + 128;
+ }
+ c2 = 298 * ((int) src_line[0] - 16);
+ dst_line[x] = 0xff000000
+ | cliptobyte((c2 + r2) >> 8) << 16 /* red */
+ | cliptobyte((c2 + g2) >> 8) << 8 /* green */
+ | cliptobyte((c2 + b2) >> 8); /* blue */
+ /* Scale RGB values to 0..255 range,
+ * then clip them if still not in range (may be negative),
+ * then shift them within DWORD if necessary.
+ */
+ src_line += 2;
+ }
+ }
+}
+
struct d3dfmt_convertor_desc {
WINED3DFORMAT from, to;
void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
{WINED3DFMT_R32_FLOAT, WINED3DFMT_R16_FLOAT, convert_r32_float_r16_float},
{WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_r5g6b5_x8r8g8b8},
{WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_a8r8g8b8_x8r8g8b8},
+ {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8},
};
static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to)
/*****************************************************************************
* IWineD3DSurface::Blt, SW emulation version
*
- * Performs blits to a surface, eigher from a source of source-less blts
+ * Performs a blit to a surface, with or without a source surface.
* This is the main functionality of DirectDraw
*
* Params:
HRESULT ret = WINED3D_OK;
WINED3DLOCKED_RECT dlock, slock;
int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
- const struct GlPixelFormatDesc *sEntry, *dEntry;
+ const struct wined3d_format_desc *sEntry, *dEntry;
int x, y;
const BYTE *sbuf;
BYTE *dbuf;
FIXME("Filters not supported in software blit\n");
}
- /* First check for the validity of source / destination rectangles. This was
- * verified using a test application + by MSDN.
- */
- if ((Src != NULL) && (SrcRect != NULL) &&
- ((SrcRect->bottom > Src->currentDesc.Height)||(SrcRect->bottom < 0) ||
- (SrcRect->top > Src->currentDesc.Height)||(SrcRect->top < 0) ||
- (SrcRect->left > Src->currentDesc.Width) ||(SrcRect->left < 0) ||
- (SrcRect->right > Src->currentDesc.Width) ||(SrcRect->right < 0) ||
- (SrcRect->right < SrcRect->left) ||(SrcRect->bottom < SrcRect->top)))
- {
- WARN("Application gave us bad source rectangle for Blt.\n");
- return WINEDDERR_INVALIDRECT;
- }
- /* For the Destination rect, it can be out of bounds on the condition that a clipper
- * is set for the given surface.
- */
- if ((/*This->clipper == NULL*/ TRUE) && (DestRect) &&
- ((DestRect->bottom > This->currentDesc.Height)||(DestRect->bottom < 0) ||
- (DestRect->top > This->currentDesc.Height)||(DestRect->top < 0) ||
- (DestRect->left > This->currentDesc.Width) ||(DestRect->left < 0) ||
- (DestRect->right > This->currentDesc.Width) ||(DestRect->right < 0) ||
- (DestRect->right < DestRect->left) ||(DestRect->bottom < DestRect->top)))
+ /* First check for the validity of source / destination rectangles.
+ * This was verified using a test application + by MSDN. */
+
+ if (SrcRect)
{
- WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n");
- return WINEDDERR_INVALIDRECT;
- }
+ if (Src)
+ {
+ if (SrcRect->right < SrcRect->left || SrcRect->bottom < SrcRect->top
+ || SrcRect->left > Src->currentDesc.Width || SrcRect->left < 0
+ || SrcRect->top > Src->currentDesc.Height || SrcRect->top < 0
+ || SrcRect->right > Src->currentDesc.Width || SrcRect->right < 0
+ || SrcRect->bottom > Src->currentDesc.Height || SrcRect->bottom < 0)
+ {
+ WARN("Application gave us bad source rectangle for Blt.\n");
+ return WINEDDERR_INVALIDRECT;
+ }
- /* Now handle negative values in the rectangles. Warning: only supported for now
- in the 'simple' cases (ie not in any stretching / rotation cases).
+ if (!SrcRect->right || !SrcRect->bottom
+ || SrcRect->left == (int)Src->currentDesc.Width
+ || SrcRect->top == (int)Src->currentDesc.Height)
+ {
+ TRACE("Nothing to be done.\n");
+ return WINED3D_OK;
+ }
+ }
- First, the case where nothing is to be done.
- */
- if ((DestRect && ((DestRect->bottom <= 0) || (DestRect->right <= 0) ||
- (DestRect->top >= (int) This->currentDesc.Height) ||
- (DestRect->left >= (int) This->currentDesc.Width))) ||
- ((Src != NULL) && (SrcRect != NULL) &&
- ((SrcRect->bottom <= 0) || (SrcRect->right <= 0) ||
- (SrcRect->top >= (int) Src->currentDesc.Height) ||
- (SrcRect->left >= (int) Src->currentDesc.Width)) ))
- {
- TRACE("Nothing to be done !\n");
- return WINED3D_OK;
+ xsrc = *SrcRect;
}
-
- if (DestRect)
+ else if (Src)
{
- xdst = *DestRect;
+ xsrc.left = 0;
+ xsrc.top = 0;
+ xsrc.right = Src->currentDesc.Width;
+ xsrc.bottom = Src->currentDesc.Height;
}
else
{
- xdst.top = 0;
- xdst.bottom = This->currentDesc.Height;
- xdst.left = 0;
- xdst.right = This->currentDesc.Width;
+ memset(&xsrc, 0, sizeof(xsrc));
}
- if (SrcRect)
- {
- xsrc = *SrcRect;
- }
- else
+ if (DestRect)
{
- if (Src)
+ /* For the Destination rect, it can be out of bounds on the condition
+ * that a clipper is set for the given surface. */
+ if (!This->clipper && (DestRect->right < DestRect->left || DestRect->bottom < DestRect->top
+ || DestRect->left > This->currentDesc.Width || DestRect->left < 0
+ || DestRect->top > This->currentDesc.Height || DestRect->top < 0
+ || DestRect->right > This->currentDesc.Width || DestRect->right < 0
+ || DestRect->bottom > This->currentDesc.Height || DestRect->bottom < 0))
{
- xsrc.top = 0;
- xsrc.bottom = Src->currentDesc.Height;
- xsrc.left = 0;
- xsrc.right = Src->currentDesc.Width;
+ WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n");
+ return WINEDDERR_INVALIDRECT;
}
- else
+
+ if (DestRect->right <= 0 || DestRect->bottom <= 0
+ || DestRect->left >= (int)This->currentDesc.Width
+ || DestRect->top >= (int)This->currentDesc.Height)
{
- memset(&xsrc,0,sizeof(xsrc));
+ TRACE("Nothing to be done.\n");
+ return WINED3D_OK;
}
- }
- /* The easy case : the source-less blits.... */
- if (Src == NULL && DestRect)
- {
- RECT full_rect;
- RECT temp_rect; /* No idea if intersect rect can be the same as one of the source rect */
+ if (!Src)
+ {
+ RECT full_rect;
- full_rect.left = 0;
- full_rect.top = 0;
- full_rect.right = This->currentDesc.Width;
- full_rect.bottom = This->currentDesc.Height;
- IntersectRect(&temp_rect, &full_rect, DestRect);
- xdst = temp_rect;
- }
- else if (DestRect)
- {
- /* Only handle clipping on the destination rectangle */
- int clip_horiz = (DestRect->left < 0) || (DestRect->right > (int) This->currentDesc.Width );
- int clip_vert = (DestRect->top < 0) || (DestRect->bottom > (int) This->currentDesc.Height);
- if (clip_vert || clip_horiz)
+ full_rect.left = 0;
+ full_rect.top = 0;
+ full_rect.right = This->currentDesc.Width;
+ full_rect.bottom = This->currentDesc.Height;
+ IntersectRect(&xdst, &full_rect, DestRect);
+ }
+ else
{
- /* Now check if this is a special case or not... */
- if ((((DestRect->bottom - DestRect->top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) ||
- (((DestRect->right - DestRect->left) != (xsrc.right - xsrc.left)) && clip_horiz) ||
- (Flags & WINEDDBLT_DDFX))
- {
- WARN("Out of screen rectangle in special case. Not handled right now.\n");
- return WINED3D_OK;
- }
+ BOOL clip_horiz, clip_vert;
- if (clip_horiz)
+ xdst = *DestRect;
+ clip_horiz = xdst.left < 0 || xdst.right > (int)This->currentDesc.Width;
+ clip_vert = xdst.top < 0 || xdst.bottom > (int)This->currentDesc.Height;
+
+ if (clip_vert || clip_horiz)
{
- if (DestRect->left < 0) { xsrc.left -= DestRect->left; xdst.left = 0; }
- if (DestRect->right > This->currentDesc.Width)
+ /* Now check if this is a special case or not... */
+ if ((Flags & WINEDDBLT_DDFX)
+ || (clip_horiz && xdst.right - xdst.left != xsrc.right - xsrc.left)
+ || (clip_vert && xdst.bottom - xdst.top != xsrc.bottom - xsrc.top))
{
- xsrc.right -= (DestRect->right - (int) This->currentDesc.Width);
- xdst.right = (int) This->currentDesc.Width;
+ WARN("Out of screen rectangle in special case. Not handled right now.\n");
+ return WINED3D_OK;
}
- }
- if (clip_vert)
- {
- if (DestRect->top < 0)
+
+ if (clip_horiz)
+ {
+ if (xdst.left < 0)
+ {
+ xsrc.left -= xdst.left;
+ xdst.left = 0;
+ }
+ if (xdst.right > This->currentDesc.Width)
+ {
+ xsrc.right -= (xdst.right - (int)This->currentDesc.Width);
+ xdst.right = (int)This->currentDesc.Width;
+ }
+ }
+
+ if (clip_vert)
{
- xsrc.top -= DestRect->top;
- xdst.top = 0;
+ if (xdst.top < 0)
+ {
+ xsrc.top -= xdst.top;
+ xdst.top = 0;
+ }
+ if (xdst.bottom > This->currentDesc.Height)
+ {
+ xsrc.bottom -= (xdst.bottom - (int)This->currentDesc.Height);
+ xdst.bottom = (int)This->currentDesc.Height;
+ }
}
- if (DestRect->bottom > This->currentDesc.Height)
+
+ /* And check if after clipping something is still to be done... */
+ if ((xdst.right <= 0) || (xdst.bottom <= 0)
+ || (xdst.left >= (int)This->currentDesc.Width)
+ || (xdst.top >= (int)This->currentDesc.Height)
+ || (xsrc.right <= 0) || (xsrc.bottom <= 0)
+ || (xsrc.left >= (int) Src->currentDesc.Width)
+ || (xsrc.top >= (int)Src->currentDesc.Height))
{
- xsrc.bottom -= (DestRect->bottom - (int) This->currentDesc.Height);
- xdst.bottom = (int) This->currentDesc.Height;
+ TRACE("Nothing to be done after clipping.\n");
+ return WINED3D_OK;
}
}
- /* And check if after clipping something is still to be done... */
- if ((xdst.bottom <= 0) || (xdst.right <= 0) ||
- (xdst.top >= (int) This->currentDesc.Height) ||
- (xdst.left >= (int) This->currentDesc.Width) ||
- (xsrc.bottom <= 0) || (xsrc.right <= 0) ||
- (xsrc.top >= (int) Src->currentDesc.Height) ||
- (xsrc.left >= (int) Src->currentDesc.Width))
- {
- TRACE("Nothing to be done after clipping !\n");
- return WINED3D_OK;
- }
}
}
+ else
+ {
+ xdst.left = 0;
+ xdst.top = 0;
+ xdst.right = This->currentDesc.Width;
+ xdst.bottom = This->currentDesc.Height;
+ }
if (Src == This)
{
RECT lock_src, lock_dst, lock_union;
const BYTE *sbuf;
BYTE *dbuf;
- const struct GlPixelFormatDesc *sEntry, *dEntry;
+ const struct wined3d_format_desc *sEntry, *dEntry;
if (TRACE_ON(d3d_surface))
{
}
else
{
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+ const struct wined3d_format_desc *format_desc = This->resource.format_desc;
TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
/* Tell the swapchain to update the screen */
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
{
- if(iface == swapchain->frontBuffer)
+ if (This == swapchain->front_buffer)
{
x11_copy_to_screen(swapchain, &This->lockedRect);
}
return WINEDDERR_NOTFLIPPABLE;
}
- hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0);
+ hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain,
+ NULL, NULL, swapchain->win_handle, NULL, 0);
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
return hr;
}
FILE* f = NULL;
UINT y = 0, x = 0;
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+ const struct wined3d_format_desc *format_desc = This->resource.format_desc;
static char *output = NULL;
static UINT size = 0;
- const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
if (This->pow2Width > size) {
output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3);
fwrite(output, 3 * This->pow2Width, 1, f);
}
} else {
- int red_shift, green_shift, blue_shift, pix_width, alpha_shift;
+ int red_shift, green_shift, blue_shift, pix_width;
pix_width = format_desc->byte_count;
red_shift = get_shift(format_desc->red_mask);
green_shift = get_shift(format_desc->green_mask);
blue_shift = get_shift(format_desc->blue_mask);
- alpha_shift = get_shift(format_desc->alpha_mask);
for (y = 0; y < This->pow2Height; y++) {
const unsigned char *src = This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface));
output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift;
comp = color & format_desc->green_mask;
output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift;
- comp = color & format_desc->alpha_mask;
- output[3 * x + 2] = alpha_shift > 0 ? comp >> alpha_shift : comp << -alpha_shift;
+ comp = color & format_desc->blue_mask;
+ output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift;
}
fwrite(output, 3 * This->pow2Width, 1, f);
}
IWineD3DSurfaceImpl *dds_primary;
IWineD3DSwapChainImpl *swapchain;
swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0];
- dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
+ dds_primary = swapchain->front_buffer;
if (dds_primary && dds_primary->palette)
pal = dds_primary->palette->palents;
}
/* Tell the swapchain to update the screen */
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
{
- if(iface == swapchain->frontBuffer)
+ if (This == swapchain->front_buffer)
{
x11_copy_to_screen(swapchain, NULL);
}
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(fps);
-#define GLINFO_LOCATION This->device->adapter->gl_info
-
/*IWineD3DSwapChain parts follow: */
static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
{
IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
- /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is
+ /* Release the swapchain's draw buffers. Make sure This->back_buffers[0] is
* the last buffer to be destroyed, FindContext() depends on that. */
- if (This->frontBuffer)
+ if (This->front_buffer)
{
- IWineD3DSurface_SetContainer(This->frontBuffer, 0);
- if (IWineD3DSurface_Release(This->frontBuffer))
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL);
+ if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer))
{
WARN("(%p) Something's still holding the front buffer (%p).\n",
- This, This->frontBuffer);
+ This, This->front_buffer);
}
- This->frontBuffer = NULL;
+ This->front_buffer = NULL;
}
- if (This->backBuffer)
+ if (This->back_buffers)
{
UINT i = This->presentParms.BackBufferCount;
while (i--)
{
- IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
- if (IWineD3DSurface_Release(This->backBuffer[i]))
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL);
+ if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
WARN("(%p) Something's still holding back buffer %u (%p).\n",
- This, i, This->backBuffer[i]);
+ This, i, This->back_buffers[i]);
}
- HeapFree(GetProcessHeap(), 0, This->backBuffer);
- This->backBuffer = NULL;
+ HeapFree(GetProcessHeap(), 0, This->back_buffers);
+ This->back_buffers = NULL;
}
for (i = 0; i < This->num_contexts; ++i)
const RECT *src_rect, const RECT *dst_rect)
{
IWineD3DDeviceImpl *device = This->device;
- IWineD3DSurfaceImpl *backbuffer = ((IWineD3DSurfaceImpl *) This->backBuffer[0]);
+ IWineD3DSurfaceImpl *backbuffer = This->back_buffers[0];
UINT src_w = src_rect->right - src_rect->left;
UINT src_h = src_rect->bottom - src_rect->top;
GLenum gl_filter;
const struct wined3d_gl_info *gl_info = context->gl_info;
+ RECT win_rect;
+ UINT win_h;
TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n",
This, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect));
else
gl_filter = GL_LINEAR;
- if (gl_info->fbo_ops.glBlitFramebuffer)
+ GetClientRect(This->win_handle, &win_rect);
+ win_h = win_rect.bottom - win_rect.top;
+
+ if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format_desc->color_fixup))
{
ENTER_GL();
- context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo);
- context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, This->backBuffer[0]);
- context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE);
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL);
context_set_draw_buffer(context, GL_BACK);
/* Note that the texture is upside down */
gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom,
- dst_rect->left, dst_rect->bottom, dst_rect->right, dst_rect->top,
- GL_COLOR_BUFFER_BIT, gl_filter);
+ dst_rect->left, win_h - dst_rect->top, dst_rect->right, win_h - dst_rect->bottom,
+ GL_COLOR_BUFFER_BIT, gl_filter);
checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n");
LEAVE_GL();
}
float tex_right = src_rect->right;
float tex_bottom = src_rect->bottom;
- context2 = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_BLIT);
+ context2 = context_acquire(This->device, This->back_buffers[0]);
+ context_apply_blit_state(context2, device);
if(backbuffer->Flags & SFLAG_NORMCOORD)
{
tex_bottom /= src_h;
}
+ if (is_complex_fixup(backbuffer->resource.format_desc->color_fixup))
+ gl_filter = GL_NEAREST;
+
ENTER_GL();
context_bind_fbo(context2, GL_DRAW_FRAMEBUFFER, NULL);
/* Set up the texture. The surface is not in a IWineD3D*Texture container,
* so there are no d3d texture settings to dirtify
*/
- device->blitter->set_shader((IWineD3DDevice *) device, backbuffer->resource.format_desc,
- backbuffer->texture_target, backbuffer->pow2Width,
- backbuffer->pow2Height);
- glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ device->blitter->set_shader((IWineD3DDevice *) device, backbuffer);
+ glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter);
+ glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter);
context_set_draw_buffer(context, GL_BACK);
/* Set the viewport to the destination rectandle, disable any projection
- * transformation set up by CTXUSAGE_BLIT, and draw a (-1,-1)-(1,1) quad.
+ * transformation set up by context_apply_blit_state(), and draw a
+ * (-1,-1)-(1,1) quad.
*
* Back up viewport and matrix to avoid breaking last_was_blit
*
- * Note that CTXUSAGE_BLIT set up viewport and ortho to match the surface
- * size - we want the GL drawable(=window) size.
- */
+ * Note that context_apply_blit_state() set up viewport and ortho to
+ * match the surface size - we want the GL drawable(=window) size. */
glPushAttrib(GL_VIEWPORT_BIT);
- glViewport(dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom);
+ glViewport(dst_rect->left, win_h - dst_rect->bottom, dst_rect->right, win_h - dst_rect->top);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+ const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
RECT src_rect, dst_rect;
BOOL render_to_fbo;
IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
- context = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(This->device, This->back_buffers[0]);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping present.\n");
+ return WINED3D_OK;
+ }
+
+ gl_info = context->gl_info;
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
if (This->device->bCursorVisible && This->device->cursorTexture)
cursor.resource.ref = 1;
cursor.resource.device = This->device;
cursor.resource.pool = WINED3DPOOL_SCRATCH;
- cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, context->gl_info);
+ cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
cursor.texture_name = This->device->cursorTexture;
cursor.texture_target = GL_TEXTURE_2D;
cursor.texture_level = 0;
cursor.currentDesc.Width = This->device->cursorWidth;
cursor.currentDesc.Height = This->device->cursorHeight;
- cursor.glRect.left = 0;
- cursor.glRect.top = 0;
- cursor.glRect.right = cursor.currentDesc.Width;
- cursor.glRect.bottom = cursor.currentDesc.Height;
/* The cursor must have pow2 sizes */
cursor.pow2Width = cursor.currentDesc.Width;
cursor.pow2Height = cursor.currentDesc.Height;
if (This->presentParms.Windowed) {
MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
}
- IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor,
+ IWineD3DSurface_Blt((IWineD3DSurface *)This->back_buffers[0], &destRect, (IWineD3DSurface *)&cursor,
NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT);
}
if (This->device->logo_surface)
{
/* Blit the logo into the upper left corner of the drawable. */
- IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
+ IWineD3DSurface_BltFast((IWineD3DSurface *)This->back_buffers[0], 0, 0,
+ This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
}
TRACE("Presenting HDC %p.\n", context->hdc);
*/
if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
- IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL);
- IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE);
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INTEXTURE, NULL);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, FALSE);
This->render_to_fbo = TRUE;
/* Force the context manager to update the render target configuration next draw. */
WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
}
- if(!This->render_to_fbo &&
- ( ((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM ||
- ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) ) {
+ if (!This->render_to_fbo && ((This->front_buffer->Flags & SFLAG_INSYSMEM)
+ || (This->back_buffers[0]->Flags & SFLAG_INSYSMEM)))
+ {
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
* Doesn't work with render_to_fbo because we're not flipping
*/
- IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
- IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
+ IWineD3DSurfaceImpl *front = This->front_buffer;
+ IWineD3DSurfaceImpl *back = This->back_buffers[0];
if(front->resource.size == back->resource.size) {
DWORD fbflags;
* This serves to update the emulated overlay, if any
*/
fbflags = front->Flags;
- IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)front, SFLAG_INDRAWABLE, TRUE);
front->Flags = fbflags;
} else {
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE);
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE);
}
- } else {
- IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE);
+ }
+ else
+ {
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->front_buffer, SFLAG_INDRAWABLE, TRUE);
/* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
* and INTEXTURE copies can keep their old content if they have any defined content.
* If the swapeffect is COPY, the content remains the same. If it is FLIP however,
* the texture / sysmem copy needs to be reloaded from the drawable
*/
- if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) {
- IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, TRUE);
+ if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP)
+ {
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, TRUE);
}
}
- if (This->device->stencilBufferTarget)
+ if (This->device->depth_stencil)
{
if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
- || ((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget)->Flags & SFLAG_DISCARD)
+ || This->device->depth_stencil->Flags & SFLAG_DISCARD)
{
- surface_modify_ds_location(This->device->stencilBufferTarget, SFLAG_DS_DISCARDED);
+ surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED,
+ This->device->depth_stencil->currentDesc.Width,
+ This->device->depth_stencil->currentDesc.Height);
+ if (This->device->depth_stencil == This->device->onscreen_depth_stencil)
+ {
+ IWineD3DSurface_Release((IWineD3DSurface *)This->device->onscreen_depth_stencil);
+ This->device->onscreen_depth_stencil = NULL;
+ }
}
}
if (This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE
- && context->gl_info->supported[SGI_VIDEO_SYNC])
+ && gl_info->supported[SGI_VIDEO_SYNC])
{
retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync));
if(retval != 0) {
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) {
- IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
- WINED3DLOCKED_RECT r;
- BYTE *mem;
-
- if (!window || window == This->win_handle) return WINED3D_OK;
-
- TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window);
- if (This->context[0] == This->device->contexts[0])
- {
- /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading
- * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
- * and reload the resources
- */
- delete_opengl_contexts((IWineD3DDevice *)This->device, iface);
- This->win_handle = window;
- create_primary_opengl_context((IWineD3DDevice *)This->device, iface);
- }
- else
- {
- This->win_handle = window;
+static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window)
+{
+ IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
- /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect
- * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code
- * So lock read only, copy the surface out, then lock with the discard flag and write back
- */
- IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY);
- mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
- memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
- IWineD3DSurface_UnlockRect(This->backBuffer[0]);
+ if (!window) window = swapchain->device_window;
+ if (window == swapchain->win_handle) return WINED3D_OK;
- context_destroy(This->device, This->context[0]);
- This->context[0] = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer,
- This->win_handle, FALSE /* pbuffer */, &This->presentParms);
- context_release(This->context[0]);
+ TRACE("Setting swapchain %p window from %p to %p\n", swapchain, swapchain->win_handle, window);
+ swapchain->win_handle = window;
- IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
- memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
- HeapFree(GetProcessHeap(), 0, mem);
- IWineD3DSurface_UnlockRect(This->backBuffer[0]);
- }
return WINED3D_OK;
}
void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h)
{
IWineD3DDeviceImpl *device = swapchain->device;
- HWND window = swapchain->win_handle;
+ HWND window = swapchain->device_window;
BOOL filter_messages;
LONG style, exstyle;
void swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain)
{
IWineD3DDeviceImpl *device = swapchain->device;
- HWND window = swapchain->win_handle;
+ HWND window = swapchain->device_window;
BOOL filter_messages;
LONG style, exstyle;
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent)
{
const struct wined3d_adapter *adapter = device->adapter;
- const struct GlPixelFormatDesc *format_desc;
+ const struct wined3d_format_desc *format_desc;
BOOL displaymode_set = FALSE;
WINED3DDISPLAYMODE mode;
RECT client_rect;
swapchain->parent = parent;
swapchain->ref = 1;
swapchain->win_handle = window;
+ swapchain->device_window = window;
if (!present_parameters->Windowed && window)
{
hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
- swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer);
+ swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */,
+ (IWineD3DSurface **)&swapchain->front_buffer);
if (FAILED(hr))
{
WARN("Failed to create front buffer, hr %#x.\n", hr);
goto err;
}
- IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain);
- ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, (IWineD3DBase *)swapchain);
+ swapchain->front_buffer->Flags |= SFLAG_SWAPCHAIN;
if (surface_type == SURFACE_OPENGL)
{
- IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
}
/* MSDN says we're only allowed a single fullscreen swapchain per device,
if (surface_type == SURFACE_OPENGL)
{
- swapchain->context[0] = context_create(device, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
- window, FALSE /* pbuffer */, present_parameters);
+ WINED3DFORMAT formats[] =
+ {
+ WINED3DFMT_D24_UNORM_S8_UINT,
+ WINED3DFMT_D32_UNORM,
+ WINED3DFMT_R24_UNORM_X8_TYPELESS,
+ WINED3DFMT_D16_UNORM,
+ WINED3DFMT_S1_UINT_D15_UNORM
+ };
+
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+ /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
+ * You are able to add a depth + stencil surface at a later stage when you need it.
+ * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
+ * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
+ * context, need torecreate shaders, textures and other resources.
+ *
+ * The context manager already takes care of the state problem and for the other tasks code from Reset
+ * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
+ * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
+ * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
+ * issue needs to be fixed. */
+ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
+ {
+ swapchain->ds_format = getFormatDescEntry(formats[i], gl_info);
+ swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format);
+ if (swapchain->context[0]) break;
+ TRACE("Depth stencil format %s is not supported, trying next format\n",
+ debug_d3dformat(formats[i]));
+ }
+
if (!swapchain->context[0])
{
WARN("Failed to create context.\n");
hr = WINED3DERR_NOTAVAILABLE;
goto err;
}
+
+ if (!present_parameters->EnableAutoDepthStencil
+ || swapchain->presentParms.AutoDepthStencilFormat != swapchain->ds_format->format)
+ {
+ FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n");
+ }
context_release(swapchain->context[0]);
}
else
if (swapchain->presentParms.BackBufferCount > 0)
{
- swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0,
- sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount);
- if (!swapchain->backBuffer)
+ swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*swapchain->back_buffers) * swapchain->presentParms.BackBufferCount);
+ if (!swapchain->back_buffers)
{
ERR("Failed to allocate backbuffer array memory.\n");
hr = E_OUTOFMEMORY;
hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
- swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]);
+ swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */,
+ (IWineD3DSurface **)&swapchain->back_buffers[i]);
if (FAILED(hr))
{
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
goto err;
}
- IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain);
- ((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN;
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[i], (IWineD3DBase *)swapchain);
+ swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN;
}
}
if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL)
{
TRACE("Creating depth/stencil buffer.\n");
- if (!device->auto_depth_stencil_buffer)
+ if (!device->auto_depth_stencil)
{
hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType,
swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */,
- &device->auto_depth_stencil_buffer);
+ (IWineD3DSurface **)&device->auto_depth_stencil);
if (FAILED(hr))
{
WARN("Failed to create the auto depth stencil, hr %#x.\n", hr);
goto err;
}
- IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL);
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)device->auto_depth_stencil, NULL);
}
}
ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
}
- if (swapchain->backBuffer)
+ if (swapchain->back_buffers)
{
for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
{
- if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]);
+ if (swapchain->back_buffers[i]) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->back_buffers[i]);
}
- HeapFree(GetProcessHeap(), 0, swapchain->backBuffer);
+ HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
}
if (swapchain->context)
HeapFree(GetProcessHeap(), 0, swapchain->context);
}
- if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer);
+ if (swapchain->front_buffer) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->front_buffer);
return hr;
}
TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
- ctx = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer,
- This->context[0]->win_handle, FALSE /* pbuffer */, &This->presentParms);
- if (!ctx)
+ if (!(ctx = context_create(This, This->front_buffer, This->ds_format)))
{
ERR("Failed to create a new context for the swapchain\n");
return NULL;
void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height)
{
- IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt;
/* The drawable size of an onscreen drawable is the surface size.
* (Actually: The window size, but the surface is created in window size) */
- *width = surface->currentDesc.Width;
- *height = surface->currentDesc.Height;
+ *width = context->current_rt->currentDesc.Width;
+ *height = context->current_rt->currentDesc.Height;
}
MapWindowPoints(This->win_handle, NULL, &start, 1);
}
- IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0);
+ IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, (IWineD3DSurface *)This->front_buffer, NULL, 0);
return WINED3D_OK;
}
* used (there This->backBuffer is always NULL). We need this because this function has
* to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default
* scissorrect dimensions. */
- if( !This->backBuffer ) {
+ if (!This->back_buffers)
+ {
*ppBackBuffer = NULL;
return WINED3DERR_INVALIDCALL;
}
- *ppBackBuffer = This->backBuffer[iBackBuffer];
+ *ppBackBuffer = (IWineD3DSurface *)This->back_buffers[iBackBuffer];
TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
/* Note inc ref on returned surface */
return hr;
}
-HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
+HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice **device)
+{
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
- *ppDevice = (IWineD3DDevice *)This->device;
+ *device = (IWineD3DDevice *)This->device;
+ IWineD3DDevice_AddRef(*device);
- /* Note Calling this method will increase the internal reference count
- on the IDirect3DDevice9 interface. */
- IWineD3DDevice_AddRef(*ppDevice);
- TRACE("(%p) : returning %p\n", This, *ppDevice);
+ TRACE("(%p) : returning %p\n", This, *device);
return WINED3D_OK;
}
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
HDC hDC;
TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags);
- hDC = GetDC(This->win_handle);
+ hDC = GetDC(This->device_window);
SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
- ReleaseDC(This->win_handle, hDC);
+ ReleaseDC(This->device_window, hDC);
return WINED3D_OK;
}
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
HDC hDC;
TRACE("(%p) : pRamp@%p\n", This, pRamp);
- hDC = GetDC(This->win_handle);
+ hDC = GetDC(This->device_window);
GetDeviceGammaRamp(hDC, pRamp);
- ReleaseDC(This->win_handle, hDC);
+ ReleaseDC(This->device_window, hDC);
return WINED3D_OK;
}
IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
/* release the ref to the front and back buffer parents */
- if(This->frontBuffer) {
- IWineD3DSurface_SetContainer(This->frontBuffer, 0);
- if (IWineD3DSurface_Release(This->frontBuffer) > 0)
+ if (This->front_buffer)
+ {
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL);
+ if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer) > 0)
{
WARN("(%p) Something's still holding the front buffer\n",This);
}
}
- if(This->backBuffer) {
+ if (This->back_buffers)
+ {
UINT i;
- for(i = 0; i < This->presentParms.BackBufferCount; i++) {
- IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
- if (IWineD3DSurface_Release(This->backBuffer[i]) > 0)
+ for (i = 0; i < This->presentParms.BackBufferCount; ++i)
+ {
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL);
+ if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
{
WARN("(%p) Something's still holding the back buffer\n",This);
}
}
- HeapFree(GetProcessHeap(), 0, This->backBuffer);
+ HeapFree(GetProcessHeap(), 0, This->back_buffers);
}
/* Restore the screen resolution if we rendered in fullscreen
*****************************************************************************/
void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc)
{
- IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
+ IWineD3DSurfaceImpl *front = This->front_buffer;
if(front->resource.usage & WINED3DUSAGE_RENDERTARGET) {
POINT offset = {0,0};
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
IWineD3DSurfaceImpl *front, *back;
- if(!This->backBuffer) {
+ if (!This->back_buffers)
+ {
WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
- front = (IWineD3DSurfaceImpl *) This->frontBuffer;
- back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
+ front = This->front_buffer;
+ back = This->back_buffers[0];
/* Flip the DC */
{
/* FPS support */
if (TRACE_ON(fps))
{
- static long prev_time, frames;
+ static LONG prev_time, frames;
DWORD time = GetTickCount();
frames++;
{
/* context_acquire() sets isInDraw to TRUE when loading a pbuffer into a texture,
* thus no danger of recursive calls. */
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
}
if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
|| This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
{
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < This->baseTexture.level_count; ++i)
{
- if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[i]))
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+ if (palette9_changed(surface))
{
TRACE("Reloading surface because the d3d8/9 palette was changed.\n");
/* TODO: This is not necessarily needed with hw palettized texture support. */
- IWineD3DSurface_LoadLocation(This->surfaces[i], SFLAG_INSYSMEM, NULL);
+ IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL);
/* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
- IWineD3DSurface_ModifyLocation(This->surfaces[i], SFLAG_INTEXTURE, FALSE);
+ IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE);
}
}
}
* since the last load then reload the surfaces. */
if (*dirty)
{
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < This->baseTexture.level_count; ++i)
{
- IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
+ IWineD3DSurface_LoadTexture((IWineD3DSurface *)This->baseTexture.sub_resources[i], srgb_mode);
}
}
else
TRACE("(%p) : Cleaning up\n", This);
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < This->baseTexture.level_count; ++i)
{
- if (This->surfaces[i])
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+ if (surface)
{
/* Clean out the texture name we gave to the surface so that the
* surface doesn't try and release it */
- surface_set_texture_name(This->surfaces[i], 0, TRUE);
- surface_set_texture_name(This->surfaces[i], 0, FALSE);
- surface_set_texture_target(This->surfaces[i], 0);
- IWineD3DSurface_SetContainer(This->surfaces[i], 0);
- IWineD3DSurface_Release(This->surfaces[i]);
+ surface_set_texture_name(surface, 0, TRUE);
+ surface_set_texture_name(surface, 0, FALSE);
+ surface_set_texture_target(surface, 0);
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL);
+ IWineD3DSurface_Release((IWineD3DSurface *)surface);
}
}
* surface before, this one will be a NOP and vice versa. Unloading an unloaded
* surface is fine
*/
- for (i = 0; i < This->baseTexture.levels; i++) {
- IWineD3DSurface_UnLoad(This->surfaces[i]);
- surface_set_texture_name(This->surfaces[i], 0, FALSE); /* Delete rgb name */
- surface_set_texture_name(This->surfaces[i], 0, TRUE); /* delete srgb name */
+ for (i = 0; i < This->baseTexture.level_count; ++i)
+ {
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+ IWineD3DSurface_UnLoad((IWineD3DSurface *)surface);
+ surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */
+ surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */
}
basetexture_unload((IWineD3DBaseTexture *)iface);
gl_tex = &This->baseTexture.texture_rgb;
}
- for (i = 0; i < This->baseTexture.levels; ++i) {
- surface_set_texture_name(This->surfaces[i], gl_tex->name, This->baseTexture.is_srgb);
+ for (i = 0; i < This->baseTexture.level_count; ++i)
+ {
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+ surface_set_texture_name(surface, gl_tex->name, This->baseTexture.is_srgb);
}
- /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect
- * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something
- * that prevents us from hitting the accelerated codepath. Thus manually set the GL state. The same applies to filtering.
- * Even if the texture has only one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW fallback on macos.
- */
+
+ /* Conditinal non power of two textures use a different clamping
+ * default. If we're using the GL_WINE_normalized_texrect partial
+ * driver emulation, we're dealing with a GL_TEXTURE_2D texture which
+ * has the address mode set to repeat - something that prevents us
+ * from hitting the accelerated codepath. Thus manually set the GL
+ * state. The same applies to filtering. Even if the texture has only
+ * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW
+ * fallback on macos. */
if(IWineD3DBaseTexture_IsCondNP2(iface)) {
ENTER_GL();
glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
/* *******************************************
IWineD3DTexture IWineD3DTexture parts follow
******************************************* */
-static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
- IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
+static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT level, WINED3DSURFACE_DESC *desc)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *surface;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
- if (Level < This->baseTexture.levels) {
- TRACE("(%p) Level (%d)\n", This, Level);
- return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc);
+ if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
- return WINED3DERR_INVALIDCALL;
+
+ return IWineD3DSurface_GetDesc(surface, desc);
}
-static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, UINT Level, IWineD3DSurface** ppSurfaceLevel) {
- IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
- HRESULT hr = WINED3DERR_INVALIDCALL;
+static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface,
+ UINT level, IWineD3DSurface **surface)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *s;
- if (Level < This->baseTexture.levels) {
- *ppSurfaceLevel = This->surfaces[Level];
- IWineD3DSurface_AddRef(This->surfaces[Level]);
- hr = WINED3D_OK;
- TRACE("(%p) : returning %p for level %d\n", This, *ppSurfaceLevel, Level);
- }
- if (WINED3D_OK != hr) {
- WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
- *ppSurfaceLevel = NULL; /* Just to be on the safe side.. */
+ TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
+
+ if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+
+ IWineD3DSurface_AddRef(s);
+ *surface = s;
+
+ TRACE("Returning surface %p.\n", *surface);
+
+ return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, UINT Level, WINED3DLOCKED_RECT *pLockedRect,
- CONST RECT *pRect, DWORD Flags) {
- IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
- HRESULT hr = WINED3DERR_INVALIDCALL;
+static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface,
+ UINT level, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *surface;
- if (Level < This->baseTexture.levels) {
- hr = IWineD3DSurface_LockRect(This->surfaces[Level], pLockedRect, pRect, Flags);
- }
- if (WINED3D_OK == hr) {
- TRACE("(%p) Level (%d) success\n", This, Level);
- } else {
- WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
+ TRACE("iface %p, level %u, locked_rect %p, rect %s, flags %#x.\n",
+ iface, level, locked_rect, wine_dbgstr_rect(rect), flags);
+
+ if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+ return IWineD3DSurface_LockRect(surface, locked_rect, rect, flags);
}
-static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT Level) {
- IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
- HRESULT hr = WINED3DERR_INVALIDCALL;
+static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT level)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurface *surface;
- if (Level < This->baseTexture.levels) {
- hr = IWineD3DSurface_UnlockRect(This->surfaces[Level]);
- }
- if ( WINED3D_OK == hr) {
- TRACE("(%p) Level (%d) success\n", This, Level);
- } else {
- WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
+ TRACE("iface %p, level %u.\n", iface, level);
+
+ if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+
+ return IWineD3DSurface_UnlockRect(surface);
}
-static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) {
- IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
- This->baseTexture.texture_rgb.dirty = TRUE;
- This->baseTexture.texture_srgb.dirty = TRUE;
- TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
- surface_add_dirty_rect(This->surfaces[0], pDirtyRect);
+static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, const RECT *dirty_rect)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DSurfaceImpl *surface;
+
+ TRACE("iface %p, dirty_rect %s.\n", iface, wine_dbgstr_rect(dirty_rect));
+
+ if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, 0, 0)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ texture->baseTexture.texture_rgb.dirty = TRUE;
+ texture->baseTexture.texture_srgb.dirty = TRUE;
+ surface_add_dirty_rect(surface, dirty_rect);
return WINED3D_OK;
}
IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info);
UINT pow2_width, pow2_height;
UINT tmp_w, tmp_h;
unsigned int i;
texture->lpVtbl = &IWineD3DTexture_Vtbl;
- hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_TEXTURE,
- device, 0, usage, format_desc, pool, parent, parent_ops);
+ hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 1, levels,
+ WINED3DRTYPE_TEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize basetexture, returning %#x.\n", hr);
/* Generate all the surfaces. */
tmp_w = width;
tmp_h = height;
- for (i = 0; i < texture->baseTexture.levels; ++i)
+ for (i = 0; i < texture->baseTexture.level_count; ++i)
{
+ IWineD3DSurface *surface;
+
/* Use the callback to create the texture surface. */
hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format,
- usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]);
- if (FAILED(hr) || ((IWineD3DSurfaceImpl *)texture->surfaces[i])->Flags & SFLAG_OVERSIZE)
+ usage, pool, i, 0, &surface);
+ if (FAILED(hr))
{
FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
- texture->surfaces[i] = NULL;
texture_cleanup(texture);
return hr;
}
- IWineD3DSurface_SetContainer(texture->surfaces[i], (IWineD3DBase *)texture);
- TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[i]);
- surface_set_texture_target(texture->surfaces[i], texture->target);
+ IWineD3DSurface_SetContainer(surface, (IWineD3DBase *)texture);
+ surface_set_texture_target((IWineD3DSurfaceImpl *)surface, texture->target);
+ texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)surface;
+ TRACE("Created surface level %u @ %p.\n", i, surface);
/* Calculate the next mipmap level. */
tmp_w = max(1, tmp_w >> 1);
tmp_h = max(1, tmp_h >> 1);
static const struct wined3d_format_base_flags format_base_flags[] =
{
- {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
- {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC},
+ {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
};
struct wined3d_format_compression_info
{WINED3DFMT_DXT3, 4, 4, 16},
{WINED3DFMT_DXT4, 4, 4, 16},
{WINED3DFMT_DXT5, 4, 4, 16},
- {WINED3DFMT_ATI2N, 4, 4, 16},
+ {WINED3DFMT_ATI2N, 1, 1, 1},
};
struct wined3d_format_vertex_info
{WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)}
};
-typedef struct {
- WINED3DFORMAT fmt;
- GLint glInternal, glGammaInternal, rtInternal, glFormat, glType;
- unsigned int Flags;
+struct wined3d_format_texture_info
+{
+ WINED3DFORMAT format;
+ GLint gl_internal;
+ GLint gl_srgb_internal;
+ GLint gl_rt_internal;
+ GLint gl_format;
+ GLint gl_type;
+ unsigned int conv_byte_count;
+ unsigned int flags;
GL_SupportedExt extension;
-} GlPixelFormatDescTemplate;
+ void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
+};
-/*****************************************************************************
- * OpenGL format template. Contains unexciting formats which do not need
- * extension checks. The order in this table is independent of the order in
- * the table StaticPixelFormatDesc above. Not all formats have to be in this
- * table.
- */
-static const GlPixelFormatDescTemplate gl_formats_template[] = {
+static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
+ * format+type combination to load it. Thus convert it to A8L8, then load it
+ * with A4L4 internal, but A8L8 format+type
+ */
+ unsigned int x, y;
+ const unsigned char *Source;
+ unsigned char *Dest;
+ UINT outpitch = pitch * 2;
+
+ for(y = 0; y < height; y++) {
+ Source = src + y * pitch;
+ Dest = dst + y * outpitch;
+ for (x = 0; x < width; x++ ) {
+ unsigned char color = (*Source++);
+ /* A */ Dest[1] = (color & 0xf0) << 0;
+ /* L */ Dest[0] = (color & 0x0f) << 4;
+ Dest += 2;
+ }
+ }
+}
+
+static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const WORD *Source;
+
+ for(y = 0; y < height; y++)
+ {
+ unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
+ Source = (const WORD *)(src + y * pitch);
+ for (x = 0; x < width; x++ )
+ {
+ short color = (*Source++);
+ unsigned char l = ((color >> 10) & 0xfc);
+ short v = ((color >> 5) & 0x3e);
+ short u = ((color ) & 0x1f);
+ short v_conv = v + 16;
+ short u_conv = u + 16;
+
+ *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
+ Dest_s += 1;
+ }
+ }
+}
+
+static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const WORD *Source;
+ unsigned char *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ /* This makes the gl surface bigger(24 bit instead of 16), but it works with
+ * fixed function and shaders without further conversion once the surface is
+ * loaded
+ */
+ for(y = 0; y < height; y++) {
+ Source = (const WORD *)(src + y * pitch);
+ Dest = dst + y * outpitch;
+ for (x = 0; x < width; x++ ) {
+ short color = (*Source++);
+ unsigned char l = ((color >> 10) & 0xfc);
+ char v = ((color >> 5) & 0x3e);
+ char u = ((color ) & 0x1f);
+
+ /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
+ * and doubles the positive range. Thus shift left only once, gl does the 2nd
+ * shift. GL reads a signed value and converts it into an unsigned value.
+ */
+ /* M */ Dest[2] = l << 1;
+
+ /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
+ * from 5 bit values to 8 bit values.
+ */
+ /* V */ Dest[1] = v << 3;
+ /* U */ Dest[0] = u << 3;
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const short *Source;
+ unsigned char *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const short *)(src + y * pitch);
+ Dest = dst + y * outpitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* B */ Dest[0] = 0xff;
+ /* G */ Dest[1] = (color >> 8) + 128; /* V */
+ /* R */ Dest[2] = (color) + 128; /* U */
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned char *Dest;
+
+ /* Doesn't work correctly with the fixed function pipeline, but can work in
+ * shaders if the shader is adjusted. (There's no use for this format in gl's
+ * standard fixed function pipeline anyway).
+ */
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = dst + y * pitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
+ /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
+ /* R */ Dest[2] = (color & 0xff) + 128; /* U */
+ Dest += 4;
+ }
+ }
+}
+
+static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned char *Dest;
+
+ /* This implementation works with the fixed function pipeline and shaders
+ * without further modification after converting the surface.
+ */
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = dst + y * pitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
+ /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
+ /* U */ Dest[0] = (color & 0xff); /* U */
+ /* I */ Dest[3] = 255; /* X */
+ Dest += 4;
+ }
+ }
+}
+
+static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned char *Dest;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = dst + y * pitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
+ /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
+ /* R */ Dest[2] = (color & 0xff) + 128; /* U */
+ /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
+ Dest += 4;
+ }
+ }
+}
+
+static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned short *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = (unsigned short *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ )
+ {
+ DWORD color = (*Source++);
+ /* B */ Dest[0] = 0xffff;
+ /* G */ Dest[1] = (color >> 16) + 32768; /* V */
+ /* R */ Dest[2] = (color ) + 32768; /* U */
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const WORD *Source;
+ WORD *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const WORD *)(src + y * pitch);
+ Dest = (WORD *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ )
+ {
+ WORD green = (*Source++);
+ WORD red = (*Source++);
+ Dest[0] = green;
+ Dest[1] = red;
+ /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
+ * shader overwrites it anyway
+ */
+ Dest[2] = 0xffff;
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const float *Source;
+ float *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const float *)(src + y * pitch);
+ Dest = (float *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ )
+ {
+ float green = (*Source++);
+ float red = (*Source++);
+ Dest[0] = green;
+ Dest[1] = red;
+ Dest[2] = 1.0f;
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ UINT outpitch = pitch * 2;
+
+ for (y = 0; y < height; ++y)
+ {
+ const WORD *source = (const WORD *)(src + y * pitch);
+ DWORD *dest = (DWORD *)(dst + y * outpitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ /* The depth data is normalized, so needs to be scaled,
+ * the stencil data isn't. Scale depth data by
+ * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
+ WORD d15 = source[x] >> 1;
+ DWORD d24 = (d15 << 9) + (d15 >> 6);
+ dest[x] = (d24 << 8) | (source[x] & 0x1);
+ }
+ }
+}
+
+static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+
+ for (y = 0; y < height; ++y)
+ {
+ const DWORD *source = (const DWORD *)(src + y * pitch);
+ DWORD *dest = (DWORD *)(dst + y * pitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ /* Just need to clear out the X4 part. */
+ dest[x] = source[x] & ~0xf0;
+ }
+ }
+}
+
+static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ UINT outpitch = pitch * 2;
+
+ for (y = 0; y < height; ++y)
+ {
+ const DWORD *source = (const DWORD *)(src + y * pitch);
+ float *dest_f = (float *)(dst + y * outpitch);
+ DWORD *dest_s = (DWORD *)(dst + y * outpitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
+ dest_s[x * 2 + 1] = source[x] & 0xff;
+ }
+ }
+}
+
+static const struct wined3d_format_texture_info format_texture_info[] =
+{
/* WINED3DFORMAT internal srgbInternal rtInternal
format type
flags
* endian machine
*/
{WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
- GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE,
+ GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0,
WINED3DFMT_FLAG_FILTERING,
- APPLE_YCBCR_422},
+ APPLE_YCBCR_422, NULL},
{WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
- GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
+ GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0,
WINED3DFMT_FLAG_FILTERING,
- APPLE_YCBCR_422},
+ APPLE_YCBCR_422, NULL},
{WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
- GL_RGBA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- EXT_TEXTURE_COMPRESSION_S3TC},
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
- GL_RGBA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- EXT_TEXTURE_COMPRESSION_S3TC},
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
- GL_RGBA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- EXT_TEXTURE_COMPRESSION_S3TC},
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
- GL_RGBA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- EXT_TEXTURE_COMPRESSION_S3TC},
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
- GL_RGBA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- EXT_TEXTURE_COMPRESSION_S3TC},
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
/* IEEE formats */
{WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
- GL_RED, GL_FLOAT,
+ GL_RED, GL_FLOAT, 0,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_FLOAT},
+ ARB_TEXTURE_FLOAT, NULL},
{WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
- GL_RED, GL_FLOAT,
+ GL_RED, GL_FLOAT, 0,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_RG},
+ ARB_TEXTURE_RG, NULL},
{WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
- GL_RGB, GL_FLOAT,
+ GL_RGB, GL_FLOAT, 12,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_FLOAT},
+ ARB_TEXTURE_FLOAT, &convert_r32g32_float},
{WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
- GL_RG, GL_FLOAT,
+ GL_RG, GL_FLOAT, 0,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_RG},
+ ARB_TEXTURE_RG, NULL},
{WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
- GL_RGBA, GL_FLOAT,
- WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_FLOAT},
+ GL_RGBA, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, NULL},
/* Float */
{WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
- GL_RED, GL_HALF_FLOAT_ARB,
+ GL_RED, GL_HALF_FLOAT_ARB, 0,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_FLOAT},
+ ARB_TEXTURE_FLOAT, NULL},
{WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
- GL_RED, GL_HALF_FLOAT_ARB,
+ GL_RED, GL_HALF_FLOAT_ARB, 0,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_RG},
+ ARB_TEXTURE_RG, NULL},
{WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
- GL_RGB, GL_HALF_FLOAT_ARB,
+ GL_RGB, GL_HALF_FLOAT_ARB, 6,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_FLOAT},
+ ARB_TEXTURE_FLOAT, &convert_r16g16},
{WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
- GL_RG, GL_HALF_FLOAT_ARB,
+ GL_RG, GL_HALF_FLOAT_ARB, 0,
WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_RG},
+ ARB_TEXTURE_RG, NULL},
{WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
- GL_RGBA, GL_HALF_FLOAT_ARB,
+ GL_RGBA, GL_HALF_FLOAT_ARB, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
- ARB_TEXTURE_FLOAT},
+ ARB_TEXTURE_FLOAT, NULL},
/* Palettized formats */
{WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
- GL_RGBA, GL_UNSIGNED_BYTE,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0,
0,
- ARB_FRAGMENT_PROGRAM},
+ ARB_FRAGMENT_PROGRAM, NULL},
{WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
- GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
+ GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
0,
- EXT_PALETTED_TEXTURE},
+ EXT_PALETTED_TEXTURE, NULL},
/* Standard ARGB formats */
{WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
- GL_BGR, GL_UNSIGNED_BYTE,
+ GL_BGR, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
- WINED3D_GL_EXT_NONE},
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
- WINED3D_GL_EXT_NONE},
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
- GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
- GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
- GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
- GL_RGB, GL_UNSIGNED_BYTE_3_3_2,
+ GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
- GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
- GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
+ GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
- GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
- GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
- GL_RGB, GL_UNSIGNED_SHORT,
+ GL_RGB, GL_UNSIGNED_SHORT, 6,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, &convert_r16g16},
{WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
- GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
+ GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
- GL_RGBA, GL_UNSIGNED_SHORT,
+ GL_RGBA, GL_UNSIGNED_SHORT, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
/* Luminance */
{WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
- GL_LUMINANCE, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
0,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, &convert_l4a4_unorm},
/* Bump mapping stuff */
{WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
- GL_BGR, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_BGR, GL_UNSIGNED_BYTE, 3,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, &convert_r8g8_snorm},
{WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
- GL_DSDT_NV, GL_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- NV_TEXTURE_SHADER},
+ GL_DSDT_NV, GL_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, NULL},
{WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm},
{WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
- GL_DSDT_MAG_NV, GL_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- NV_TEXTURE_SHADER},
+ GL_DSDT_MAG_NV, GL_BYTE, 3,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv},
{WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm},
{WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
- GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- NV_TEXTURE_SHADER},
+ GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv},
{WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
- GL_BGRA, GL_UNSIGNED_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_BGRA, GL_UNSIGNED_BYTE, 4,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm},
{WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
- GL_RGBA, GL_BYTE,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- NV_TEXTURE_SHADER},
+ GL_RGBA, GL_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, NULL},
{WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
- GL_BGR, GL_UNSIGNED_SHORT,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ GL_BGR, GL_UNSIGNED_SHORT, 6,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, &convert_r16g16_snorm},
{WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
- GL_HILO_NV, GL_SHORT,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- NV_TEXTURE_SHADER},
+ GL_HILO_NV, GL_SHORT, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, NULL},
/* Depth stencil formats */
{WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
- WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
- WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
- WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- EXT_PACKED_DEPTH_STENCIL},
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm},
{WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
- GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
- WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- ARB_FRAMEBUFFER_OBJECT},
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm},
{WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
+ | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- EXT_PACKED_DEPTH_STENCIL},
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
+ | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ EXT_PACKED_DEPTH_STENCIL, NULL},
{WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
- GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- ARB_FRAMEBUFFER_OBJECT},
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
+ | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_FRAMEBUFFER_OBJECT, NULL},
{WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
+ | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
- WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- EXT_PACKED_DEPTH_STENCIL},
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm},
{WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
- GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
- WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- ARB_FRAMEBUFFER_OBJECT},
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm},
{WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
- WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_TEXTURE},
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
+ | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
{WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
- GL_LUMINANCE, GL_UNSIGNED_SHORT,
+ GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
- WINED3D_GL_EXT_NONE},
+ WINED3D_GL_EXT_NONE, NULL},
{WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
- GL_DEPTH_COMPONENT, GL_FLOAT,
- WINED3DFMT_FLAG_DEPTH,
- ARB_DEPTH_BUFFER_FLOAT},
+ GL_DEPTH_COMPONENT, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_BUFFER_FLOAT, NULL},
{WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
- GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
- WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
- ARB_DEPTH_BUFFER_FLOAT},
+ GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float},
/* Vendor-specific formats */
{WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
0,
- ATI_TEXTURE_COMPRESSION_3DC},
+ ATI_TEXTURE_COMPRESSION_3DC, NULL},
{WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
0,
- EXT_TEXTURE_COMPRESSION_RGTC},
+ EXT_TEXTURE_COMPRESSION_RGTC, NULL},
};
static inline int getFmtIdx(WINED3DFORMAT fmt) {
for (i = 0; i < format_count; ++i)
{
- struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
+ struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
desc->format = formats[i].format;
desc->red_mask = formats[i].redMask;
desc->green_mask = formats[i].greenMask;
for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
{
- struct GlPixelFormatDesc *format_desc;
+ struct wined3d_format_desc *format_desc;
int fmt_idx = getFmtIdx(format_compression_info[i].format);
if (fmt_idx == -1)
}
/* Context activation is done by the caller. */
-static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
+static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc)
{
/* Check if the default internal format is supported as a frame buffer
* target, otherwise fall back to the render target internal.
for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
{
- struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
+ struct wined3d_format_desc *desc = &gl_info->gl_formats[i];
if (!desc->glInternal) continue;
{
unsigned int i;
- for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i)
+ for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
{
- int fmt_idx = getFmtIdx(gl_formats_template[i].fmt);
- struct GlPixelFormatDesc *desc;
+ int fmt_idx = getFmtIdx(format_texture_info[i].format);
+ struct wined3d_format_desc *desc;
if (fmt_idx == -1)
{
ERR("Format %s (%#x) not found.\n",
- debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt);
+ debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format);
return FALSE;
}
- if (!gl_info->supported[gl_formats_template[i].extension]) continue;
+ if (!gl_info->supported[format_texture_info[i].extension]) continue;
desc = &gl_info->gl_formats[fmt_idx];
- desc->glInternal = gl_formats_template[i].glInternal;
- desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
- desc->rtInternal = gl_formats_template[i].rtInternal;
- desc->glFormat = gl_formats_template[i].glFormat;
- desc->glType = gl_formats_template[i].glType;
+ desc->glInternal = format_texture_info[i].gl_internal;
+ desc->glGammaInternal = format_texture_info[i].gl_srgb_internal;
+ desc->rtInternal = format_texture_info[i].gl_rt_internal;
+ desc->glFormat = format_texture_info[i].gl_format;
+ desc->glType = format_texture_info[i].gl_type;
desc->color_fixup = COLOR_FIXUP_IDENTITY;
- desc->Flags |= gl_formats_template[i].Flags;
+ desc->Flags |= format_texture_info[i].flags;
desc->heightscale = 1.0f;
+
+ /* Texture conversion stuff */
+ desc->convert = format_texture_info[i].convert;
+ desc->conv_byte_count = format_texture_info[i].conv_byte_count;
}
return TRUE;
static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
{
+ struct wined3d_format_desc *desc;
unsigned int fmt_idx, i;
WINED3DFORMAT fmts16[] = {
WINED3DFMT_R16_FLOAT,
WINED3DFMT_R16G16B16A16_FLOAT,
};
BOOL filtered;
- struct GlPixelFormatDesc *desc;
if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
{
idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+
idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
gl_info->gl_formats[idx].heightscale = 1.5f;
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
- idx = getFmtIdx(WINED3DFMT_P8_UINT);
- gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
+ if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ idx = getFmtIdx(WINED3DFMT_P8_UINT);
+ gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
+ }
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
{
- struct GlPixelFormatDesc *format_desc;
+ struct wined3d_format_desc *format_desc;
int fmt_idx = getFmtIdx(format_vertex_info[i].format);
if (fmt_idx == -1)
return FALSE;
}
-const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
+const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
{
int idx = getFmtIdx(fmt);
const char* debug_d3drenderstate(DWORD state) {
switch (state) {
#define D3DSTATE_TO_STR(u) case u: return #u
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE );
D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS );
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS );
D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE );
D3DSTATE_TO_STR(WINED3DRS_WRAPU );
D3DSTATE_TO_STR(WINED3DRS_WRAPV );
D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE );
D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE );
D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL );
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG );
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN );
D3DSTATE_TO_STR(WINED3DRS_SRCBLEND );
D3DSTATE_TO_STR(WINED3DRS_DESTBLEND );
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND );
D3DSTATE_TO_STR(WINED3DRS_CULLMODE );
D3DSTATE_TO_STR(WINED3DRS_ZFUNC );
D3DSTATE_TO_STR(WINED3DRS_ALPHAREF );
D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE );
D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS );
D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE );
- D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR );
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU );
- D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV );
D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS );
D3DSTATE_TO_STR(WINED3DRS_ZBIAS );
D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE );
D3DSTATE_TO_STR(WINED3DRS_STENCILMASK );
D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK );
D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 );
- D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 );
D3DSTATE_TO_STR(WINED3DRS_WRAP0 );
D3DSTATE_TO_STR(WINED3DRS_WRAP1 );
D3DSTATE_TO_STR(WINED3DRS_WRAP2 );
/* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
* The later function requires individual color components. */
-BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
+BOOL getColorBits(const struct wined3d_format_desc *format_desc,
short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize)
{
TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
}
/* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
-BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize)
+BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize)
{
TRACE("fmt: %s\n", debug_d3dformat(format_desc->format));
switch(format_desc->format)
return TRUE;
}
+DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt)
+{
+ unsigned int r, g, b, a;
+ DWORD ret;
+
+ if (destfmt == WINED3DFMT_B8G8R8A8_UNORM
+ || destfmt == WINED3DFMT_B8G8R8X8_UNORM
+ || destfmt == WINED3DFMT_B8G8R8_UNORM)
+ return color;
+
+ TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt));
+
+ a = (color & 0xff000000) >> 24;
+ r = (color & 0x00ff0000) >> 16;
+ g = (color & 0x0000ff00) >> 8;
+ b = (color & 0x000000ff) >> 0;
+
+ switch(destfmt)
+ {
+ case WINED3DFMT_B5G6R5_UNORM:
+ if(r == 0xff && g == 0xff && b == 0xff) return 0xffff;
+ r = (r * 32) / 256;
+ g = (g * 64) / 256;
+ b = (b * 32) / 256;
+ ret = r << 11;
+ ret |= g << 5;
+ ret |= b;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ case WINED3DFMT_B5G5R5A1_UNORM:
+ a = (a * 2) / 256;
+ r = (r * 32) / 256;
+ g = (g * 32) / 256;
+ b = (b * 32) / 256;
+ ret = a << 15;
+ ret |= r << 10;
+ ret |= g << 5;
+ ret |= b << 0;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ case WINED3DFMT_A8_UNORM:
+ TRACE("Returning %08x\n", a);
+ return a;
+
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ a = (a * 16) / 256;
+ r = (r * 16) / 256;
+ g = (g * 16) / 256;
+ b = (b * 16) / 256;
+ ret = a << 12;
+ ret |= r << 8;
+ ret |= g << 4;
+ ret |= b << 0;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ case WINED3DFMT_B2G3R3_UNORM:
+ r = (r * 8) / 256;
+ g = (g * 8) / 256;
+ b = (b * 4) / 256;
+ ret = r << 5;
+ ret |= g << 2;
+ ret |= b << 0;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ case WINED3DFMT_R8G8B8X8_UNORM:
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ ret = a << 24;
+ ret |= b << 16;
+ ret |= g << 8;
+ ret |= r << 0;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ case WINED3DFMT_B10G10R10A2_UNORM:
+ a = (a * 4) / 256;
+ r = (r * 1024) / 256;
+ g = (g * 1024) / 256;
+ b = (b * 1024) / 256;
+ ret = a << 30;
+ ret |= r << 20;
+ ret |= g << 10;
+ ret |= b << 0;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ a = (a * 4) / 256;
+ r = (r * 1024) / 256;
+ g = (g * 1024) / 256;
+ b = (b * 1024) / 256;
+ ret = a << 30;
+ ret |= b << 20;
+ ret |= g << 10;
+ ret |= r << 0;
+ TRACE("Returning %08x\n", ret);
+ return ret;
+
+ default:
+ FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt));
+ return 0;
+ }
+}
+
/* DirectDraw stuff */
WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
switch(depth) {
return size;
}
-/***********************************************************************
- * CalculateTexRect
- *
- * Calculates the dimensions of the opengl texture used for blits.
- * Handled oversized opengl textures and updates the source rectangle
- * accordingly
- *
- * Params:
- * This: Surface to operate on
- * Rect: Requested rectangle
- *
- * Returns:
- * TRUE if the texture part can be loaded,
- * FALSE otherwise
- *
- *********************************************************************/
-BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4])
-{
- const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
- int x1 = Rect->left, x2 = Rect->right;
- int y1 = Rect->top, y2 = Rect->bottom;
- GLint maxSize = gl_info->limits.texture_size;
-
- TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
- Rect->left, Rect->top, Rect->right, Rect->bottom);
-
- /* The sizes might be reversed */
- if(Rect->left > Rect->right) {
- x1 = Rect->right;
- x2 = Rect->left;
- }
- if(Rect->top > Rect->bottom) {
- y1 = Rect->bottom;
- y2 = Rect->top;
- }
-
- /* No oversized texture? This is easy */
- if(!(This->Flags & SFLAG_OVERSIZE)) {
- /* Which rect from the texture do I need? */
- if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
- {
- glTexCoord[0] = (float) Rect->left;
- glTexCoord[2] = (float) Rect->top;
- glTexCoord[1] = (float) Rect->right;
- glTexCoord[3] = (float) Rect->bottom;
- } else {
- glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
- glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
- glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
- glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
- }
-
- return TRUE;
- } else {
- /* Check if we can succeed at all */
- if( (x2 - x1) > maxSize ||
- (y2 - y1) > maxSize ) {
- TRACE("Requested rectangle is too large for gl\n");
- return FALSE;
- }
-
- /* A part of the texture has to be picked. First, check if
- * some texture part is loaded already, if yes try to re-use it.
- * If the texture is dirty, or the part can't be used,
- * re-position the part to load
- */
- if(This->Flags & SFLAG_INTEXTURE) {
- if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
- This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
- /* Ok, the rectangle is ok, re-use it */
- TRACE("Using existing gl Texture\n");
- } else {
- /* Rectangle is not ok, dirtify the texture to reload it */
- TRACE("Dirtifying texture to force reload\n");
- This->Flags &= ~SFLAG_INTEXTURE;
- }
- }
-
- /* Now if we are dirty(no else if!) */
- if(!(This->Flags & SFLAG_INTEXTURE)) {
- /* Set the new rectangle. Use the following strategy:
- * 1) Use as big textures as possible.
- * 2) Place the texture part in the way that the requested
- * part is in the middle of the texture(well, almost)
- * 3) If the texture is moved over the edges of the
- * surface, replace it nicely
- * 4) If the coord is not limiting the texture size,
- * use the whole size
- */
- if((This->pow2Width) > maxSize) {
- This->glRect.left = x1 - maxSize / 2;
- if(This->glRect.left < 0) {
- This->glRect.left = 0;
- }
- This->glRect.right = This->glRect.left + maxSize;
- if(This->glRect.right > This->currentDesc.Width) {
- This->glRect.right = This->currentDesc.Width;
- This->glRect.left = This->glRect.right - maxSize;
- }
- } else {
- This->glRect.left = 0;
- This->glRect.right = This->pow2Width;
- }
-
- if (This->pow2Height > maxSize)
- {
- This->glRect.top = x1 - gl_info->limits.texture_size / 2;
- if(This->glRect.top < 0) This->glRect.top = 0;
- This->glRect.bottom = This->glRect.left + maxSize;
- if(This->glRect.bottom > This->currentDesc.Height) {
- This->glRect.bottom = This->currentDesc.Height;
- This->glRect.top = This->glRect.bottom - maxSize;
- }
- } else {
- This->glRect.top = 0;
- This->glRect.bottom = This->pow2Height;
- }
- TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
- This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
- }
-
- /* Re-calculate the rect to draw */
- Rect->left -= This->glRect.left;
- Rect->right -= This->glRect.left;
- Rect->top -= This->glRect.top;
- Rect->bottom -= This->glRect.top;
-
- /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
- * or the pow2Width / pow2Height of the surface.
- *
- * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
- * as regular GL_TEXTURE_2D.
- */
- glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
- glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
- glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
- glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
- }
- return TRUE;
-}
-
void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
#define ARG1 0x01
#define ARG2 0x02
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
- IWineD3DSurfaceImpl *surf;
- surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0];
+ IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
{
* and the user preferences in wined3d_settings. */
void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
{
+ BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
+
if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
- else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested)
+ else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
{
/* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
* wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
else *vs_selected = SHADER_NONE;
if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
- else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) *ps_selected = SHADER_GLSL;
+ else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
else *ps_selected = SHADER_NONE;
return WINED3D_OK;
}
-const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl =
+static const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl =
{
/* IUnknown methods */
rendertarget_view_QueryInterface,
/* IWineD3DRendertargetView methods */
rendertarget_view_GetResource,
};
+
+void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
+ IWineD3DResource *resource, IUnknown *parent)
+{
+ view->vtbl = &wined3d_rendertarget_view_vtbl;
+ view->refcount = 1;
+ IWineD3DResource_AddRef(resource);
+ view->resource = resource;
+ view->parent = parent;
+}
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
-#define GLINFO_LOCATION This->resource.device->adapter->gl_info
/* Context activation is done by the caller. */
static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
}
/* Context activation is done by the caller. */
-static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) {
- IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
- const struct GlPixelFormatDesc *glDesc = This->resource.format_desc;
+static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode)
+{
+ IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
+ const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
+ const struct wined3d_format_desc *glDesc = This->resource.format_desc;
TRACE("(%p) : level %u, format %s (0x%08x)\n", This, gl_level, debug_d3dformat(glDesc->format), glDesc->format);
IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info);
HRESULT hr;
if (!gl_info->supported[EXT_TEXTURE3D])
TRACE("(%p) : About to load texture.\n", This);
- if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ if (!device->isInDraw) context = context_acquire(device, NULL);
else if (gl_info->supported[EXT_TEXTURE_SRGB] && This->baseTexture.bindCount > 0)
{
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
* since the last load then reload the volumes. */
if (This->baseTexture.texture_rgb.dirty)
{
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < This->baseTexture.level_count; ++i)
{
- IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
+ IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i];
+ IWineD3DVolume_LoadTexture(volume, i, srgb_mode);
}
}
else if (srgb_was_toggled)
{
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < This->baseTexture.level_count; ++i)
{
- volume_add_dirty_box(This->volumes[i], NULL);
- IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
+ IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i];
+ volume_add_dirty_box(volume, NULL);
+ IWineD3DVolume_LoadTexture(volume, i, srgb_mode);
}
}
else
TRACE("(%p) : Cleaning up.\n", This);
- for (i = 0; i < This->baseTexture.levels; ++i)
+ for (i = 0; i < This->baseTexture.level_count; ++i)
{
- IWineD3DVolume *volume = This->volumes[i];
+ IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i];
if (volume)
{
* surface before, this one will be a NOP and vice versa. Unloading an unloaded
* surface is fine
*/
- for (i = 0; i < This->baseTexture.levels; i++) {
- IWineD3DVolume_UnLoad(This->volumes[i]);
+ for (i = 0; i < This->baseTexture.level_count; ++i)
+ {
+ IWineD3DVolume_UnLoad((IWineD3DVolume *)This->baseTexture.sub_resources[i]);
}
basetexture_unload((IWineD3DBaseTexture *)iface);
/* *******************************************
IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow
******************************************* */
-static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, UINT Level,WINED3DVOLUME_DESC *pDesc) {
- IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
- if (Level < This->baseTexture.levels) {
- TRACE("(%p) Level (%d)\n", This, Level);
- return IWineD3DVolume_GetDesc(This->volumes[Level], pDesc);
- } else {
- WARN("(%p) Level (%d)\n", This, Level);
+static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface,
+ UINT level, WINED3DVOLUME_DESC *desc)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DVolume *volume;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return WINED3D_OK;
+
+ return IWineD3DVolume_GetDesc(volume, desc);
}
-static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, UINT Level, IWineD3DVolume** ppVolumeLevel) {
- IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
- if (Level < This->baseTexture.levels) {
- *ppVolumeLevel = This->volumes[Level];
- IWineD3DVolume_AddRef(*ppVolumeLevel);
- TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel);
- } else {
- WARN("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
- return WINED3DERR_INVALIDCALL;
+
+static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface,
+ UINT level, IWineD3DVolume **volume)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DVolume *v;
+
+ TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
+
+ if (!(v = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return WINED3D_OK;
+ IWineD3DVolume_AddRef(v);
+ *volume = v;
+
+ TRACE("Returning volume %p.\n", *volume);
+
+ return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, UINT Level, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) {
- HRESULT hr;
- IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
- if (Level < This->baseTexture.levels) {
- hr = IWineD3DVolume_LockBox(This->volumes[Level], pLockedVolume, pBox, Flags);
- TRACE("(%p) Level (%d) success(%u)\n", This, Level, hr);
+static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface,
+ UINT level, WINED3DLOCKED_BOX *locked_box, const WINED3DBOX *box, DWORD flags)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DVolume *volume;
+
+ TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
+ iface, level, locked_box, box, flags);
- } else {
- FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
- return WINED3DERR_INVALIDCALL;
+ if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+
+ return IWineD3DVolume_LockBox(volume, locked_box, box, flags);
}
-static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT Level) {
- HRESULT hr;
- IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
+static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT level)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DVolume *volume;
- if (Level < This->baseTexture.levels) {
- hr = IWineD3DVolume_UnlockBox(This->volumes[Level]);
- TRACE("(%p) -> level(%d) success(%u)\n", This, Level, hr);
+ TRACE("iface %p, level %u.\n", iface, level);
- } else {
- FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
- return WINED3DERR_INVALIDCALL;
+ if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
}
- return hr;
+
+ return IWineD3DVolume_UnlockBox(volume);
}
-static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, CONST WINED3DBOX* pDirtyBox) {
- IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
- This->baseTexture.texture_rgb.dirty = TRUE;
- This->baseTexture.texture_srgb.dirty = TRUE;
- TRACE("(%p) : dirtyfication of volume Level (0)\n", This);
- volume_add_dirty_box(This->volumes[0], pDirtyBox);
+static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, const WINED3DBOX *dirty_box)
+{
+ IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
+ IWineD3DVolume *volume;
+
+ TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
+
+ if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, 0)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ texture->baseTexture.texture_rgb.dirty = TRUE;
+ texture->baseTexture.texture_srgb.dirty = TRUE;
+ volume_add_dirty_box(volume, dirty_box);
return WINED3D_OK;
}
WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+ const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info);
UINT tmp_w, tmp_h, tmp_d;
unsigned int i;
HRESULT hr;
texture->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
- hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_VOLUMETEXTURE,
- device, 0, usage, format_desc, pool, parent, parent_ops);
+ hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 1, levels,
+ WINED3DRTYPE_VOLUMETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize basetexture, returning %#x.\n", hr);
tmp_h = height;
tmp_d = depth;
- for (i = 0; i < texture->baseTexture.levels; ++i)
+ for (i = 0; i < texture->baseTexture.level_count; ++i)
{
+ IWineD3DVolume *volume;
+
/* Create the volume. */
hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent,
- tmp_w, tmp_h, tmp_d, format, pool, usage, &texture->volumes[i]);
+ tmp_w, tmp_h, tmp_d, format, pool, usage, &volume);
if (FAILED(hr))
{
ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr);
- texture->volumes[i] = NULL;
volumetexture_cleanup(texture);
return hr;
}
/* Set its container to this texture. */
- IWineD3DVolume_SetContainer(texture->volumes[i], (IWineD3DBase *)texture);
+ IWineD3DVolume_SetContainer(volume, (IWineD3DBase *)texture);
+ texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)volume;
/* Calculate the next mipmap level. */
tmp_w = max(1, tmp_w >> 1);
ARB_SHADER_OBJECTS,
ARB_SHADER_TEXTURE_LOD,
ARB_SHADING_LANGUAGE_100,
+ ARB_SHADOW,
ARB_SYNC,
ARB_TEXTURE_BORDER_CLAMP,
ARB_TEXTURE_COMPRESSION,
EXT_BLEND_EQUATION_SEPARATE,
EXT_BLEND_FUNC_SEPARATE,
EXT_BLEND_MINMAX,
+ EXT_DRAW_BUFFERS2,
EXT_FOG_COORD,
EXT_FRAMEBUFFER_BLIT,
EXT_FRAMEBUFFER_MULTISAMPLE,
SGIS_GENERATE_MIPMAP,
SGI_VIDEO_SYNC,
/* WGL extensions */
- WGL_ARB_PBUFFER,
WGL_ARB_PIXEL_FORMAT,
WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
/* Internally used */
#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8b8c
#endif
+/* GL_ARB_shadow */
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884c
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884d
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884e
+#endif
+
/* GL_ARB_sync */
#ifndef GL_ARB_sync
#define GL_ARB_sync 1
typedef void (WINE_GLAPI *PGLFNBLENDFUNCSEPARATEEXTPROC)(GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorAlpha, GLenum dfactorAlpha);
+/* GL_EXT_draw_buffers2 */
+typedef GLvoid (WINE_GLAPI *PGLFNCOLORMASKINDEXEDEXTPROC)(GLuint buffer_idx, GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a);
+typedef GLvoid (WINE_GLAPI *PGLFNGETBOOLEANINDEXEDVEXTPROC)(GLenum param, GLuint index, GLboolean *value);
+typedef GLvoid (WINE_GLAPI *PGLFNGETINTEGERINDEXEDVEXTPROC)(GLenum param, GLuint index, GLint *value);
+typedef GLvoid (WINE_GLAPI *PGLFNENABLEINDEXEDEXTPROC)(GLenum target, GLuint index);
+typedef GLvoid (WINE_GLAPI *PGLFNDISABLEINDEXEDEXTPROC)(GLenum target, GLuint index);
+typedef GLboolean (WINE_GLAPI *PGLFNISENABLEDINDEXEDEXTPROC)(GLenum target, GLuint index);
+
/* GL_EXT_fog_coord */
#ifndef GL_EXT_fog_coord
#define GL_EXT_fog_coord 1
#define WGL_SAMPLES_ARB 0x2042
#endif
-/* WGL_ARB_pbuffer */
-#ifndef WGL_ARB_pbuffer
-#define WGL_ARB_pbuffer 1
-#define WGL_DRAW_TO_PBUFFER_ARB 0x202d
-#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202e
-#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202f
-#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
-#define WGL_PBUFFER_LARGEST_ARB 0x2033
-#define WGL_PBUFFER_WIDTH_ARB 0x2034
-#define WGL_PBUFFER_HEIGHT_ARB 0x2035
-#define WGL_PBUFFER_LOST_ARB 0x2036
-#endif
-DECLARE_HANDLE(HPBUFFERARB);
-typedef HPBUFFERARB (WINAPI *WINED3D_PFNWGLCREATEPBUFFERARBPROC)(HDC hDC, int iPixelFormat,
- int iWidth, int iHeight, const int *piAttribList);
-typedef HDC (WINAPI *WINED3D_PFNWGLGETPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer);
-typedef int (WINAPI *WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer, HDC hDC);
-typedef BOOL (WINAPI *WINED3D_PFNWGLDESTROYPBUFFERARBPROC)(HPBUFFERARB hPbuffer);
-typedef BOOL (WINAPI *WINED3D_PFNWGLQUERYPBUFFERARBPROC)(HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
-
/* WGL_ARB_pixel_format */
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
glUniform3iARB, ARB_SHADER_OBJECTS, NULL) \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4IARBPROC, \
glUniform4iARB, ARB_SHADER_OBJECTS, NULL) \
- USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IARBPROC, \
+ USE_GL_FUNC(WINED3D_PFNGLUNIFORM1FARBPROC, \
glUniform1fARB, ARB_SHADER_OBJECTS, NULL) \
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, \
glUniform2fARB, ARB_SHADER_OBJECTS, NULL) \
/* GL_EXT_blend_func_separate */ \
USE_GL_FUNC(PGLFNBLENDEQUATIONSEPARATEEXTPROC, \
glBlendEquationSeparateEXT, EXT_BLEND_EQUATION_SEPARATE, NULL) \
+ /* GL_EXT_draw_buffers2 */ \
+ USE_GL_FUNC(PGLFNCOLORMASKINDEXEDEXTPROC, \
+ glColorMaskIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \
+ USE_GL_FUNC(PGLFNGETBOOLEANINDEXEDVEXTPROC, \
+ glGetBooleanIndexedvEXT, EXT_DRAW_BUFFERS2, NULL) \
+ USE_GL_FUNC(PGLFNGETINTEGERINDEXEDVEXTPROC, \
+ glGetIntegerIndexedvEXT, EXT_DRAW_BUFFERS2, NULL) \
+ USE_GL_FUNC(PGLFNENABLEINDEXEDEXTPROC, \
+ glEnableIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \
+ USE_GL_FUNC(PGLFNDISABLEINDEXEDEXTPROC, \
+ glDisableIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \
+ USE_GL_FUNC(PGLFNISENABLEDINDEXEDEXTPROC, \
+ glIsEnabledIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \
/* GL_EXT_fog_coord */ \
USE_GL_FUNC(PGLFNGLFOGCOORDFEXTPROC, \
glFogCoordfEXT, EXT_FOG_COORD, NULL) \
USE_GL_FUNC(WINED3D_PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB, 0, NULL) \
USE_GL_FUNC(WINED3D_PFNWGLGETPIXELFORMATATTRIBFVARBPROC, wglGetPixelFormatAttribfvARB, 0, NULL) \
USE_GL_FUNC(WINED3D_PFNWGLCHOOSEPIXELFORMATARBPROC, wglChoosePixelFormatARB, 0, NULL) \
- USE_GL_FUNC(WINED3D_PFNWGLCREATEPBUFFERARBPROC, wglCreatePbufferARB, 0, NULL) \
- USE_GL_FUNC(WINED3D_PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB, 0, NULL) \
- USE_GL_FUNC(WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB, 0, NULL) \
- USE_GL_FUNC(WINED3D_PFNWGLDESTROYPBUFFERARBPROC, wglDestroyPbufferARB, 0, NULL) \
- USE_GL_FUNC(WINED3D_PFNWGLQUERYPBUFFERARBPROC, wglQueryPbufferARB, 0, NULL) \
USE_GL_FUNC(WINED3D_PFNWGLSETPIXELFORMATWINE, wglSetPixelFormatWINE, 0, NULL)
#endif /* __WINE_WINED3D_GL */
PCI_DEVICE_NONE,/* PCI Device ID */
0, /* The default of memory is set in FillGLCaps */
NULL, /* No wine logo by default */
- FALSE /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */
+ FALSE, /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */
+ FALSE, /* No strict draw ordering. */
};
-IWineD3D* WINAPI WineDirect3DCreate(UINT dxVersion, IUnknown *parent) {
- IWineD3DImpl* object;
+IWineD3D * WINAPI WineDirect3DCreate(UINT version, IUnknown *parent)
+{
+ IWineD3DImpl *object;
+ HRESULT hr;
- object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DImpl));
- object->lpVtbl = &IWineD3D_Vtbl;
- object->dxVersion = dxVersion;
- object->ref = 1;
- object->parent = parent;
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ ERR("Failed to allocate wined3d object memory.\n");
+ return NULL;
+ }
- if (!InitAdapters(object))
+ hr = wined3d_init(object, version, parent);
+ if (FAILED(hr))
{
- WARN("Failed to initialize direct3d adapters, Direct3D will not be available\n");
- if (dxVersion > 7)
- {
- ERR("Direct3D%d is not available without opengl\n", dxVersion);
- HeapFree(GetProcessHeap(), 0, object);
- return NULL;
- }
+ WARN("Failed to initialize wined3d object, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return NULL;
}
- TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion);
+ TRACE("Created wined3d object %p for d3d%d support.\n", object, version);
return (IWineD3D *)object;
}
{
}
-static BOOL wined3d_init(HINSTANCE hInstDLL)
+static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
{
DWORD wined3d_context_tls_idx;
HMODULE mod;
TRACE("Using the backbuffer for offscreen rendering\n");
wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
}
- else if (!strcmp(buffer,"pbuffer"))
- {
- TRACE("Using PBuffers for offscreen rendering\n");
- wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
- }
else if (!strcmp(buffer,"fbo"))
{
TRACE("Using FBOs for offscreen rendering\n");
wined3d_settings.allow_multisampling = TRUE;
}
}
+ if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size)
+ && !strcmp(buffer,"enabled"))
+ {
+ TRACE("Enforcing strict draw ordering.\n");
+ wined3d_settings.strict_draw_ordering = TRUE;
+ }
}
if (wined3d_settings.vs_mode == VS_HW)
TRACE("Allow HW vertex shaders\n");
return TRUE;
}
-static BOOL wined3d_destroy(HINSTANCE hInstDLL)
+static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
{
DWORD wined3d_context_tls_idx = context_get_tls_idx();
unsigned int i;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
- return wined3d_init(hInstDLL);
+ return wined3d_dll_init(hInstDLL);
case DLL_PROCESS_DETACH:
- return wined3d_destroy(hInstDLL);
+ return wined3d_dll_destroy(hInstDLL);
case DLL_THREAD_DETACH:
{
#define WINED3D_QUIRK_GLSL_CLIP_VARYING 0x00000004
#define WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA 0x00000008
#define WINED3D_QUIRK_NV_CLIP_BROKEN 0x00000010
+#define WINED3D_QUIRK_FBO_TEX_UPDATE 0x00000020
/* Texture format fixups */
enum complex_fixup
{
- COMPLEX_FIXUP_YUY2 = 0,
- COMPLEX_FIXUP_UYVY = 1,
- COMPLEX_FIXUP_YV12 = 2,
- COMPLEX_FIXUP_P8 = 3,
+ COMPLEX_FIXUP_NONE = 0,
+ COMPLEX_FIXUP_YUY2 = 1,
+ COMPLEX_FIXUP_UYVY = 2,
+ COMPLEX_FIXUP_YV12 = 3,
+ COMPLEX_FIXUP_P8 = 4,
};
#include <pshpack2.h>
#define VBO_HW 1
#define ORM_BACKBUFFER 0
-#define ORM_PBUFFER 1
-#define ORM_FBO 2
+#define ORM_FBO 1
#define SHADER_ARB 1
#define SHADER_GLSL 2
unsigned int emulated_textureram;
char *logo;
int allow_multisampling;
+ BOOL strict_draw_ordering;
} wined3d_settings_t;
extern wined3d_settings_t wined3d_settings DECLSPEC_HIDDEN;
WORD usestexldl : 1;
WORD usesifc : 1;
WORD usescall : 1;
- WORD padding : 4;
+ WORD usesrcp : 1;
+ WORD padding : 3;
/* Whether or not loops are used in this shader, and nesting depth */
unsigned loop_depth;
float PixelShader1xMaxValue;
DWORD MaxPixelShaderConst;
- WINED3DVSHADERCAPS2_0 VS20Caps;
- WINED3DPSHADERCAPS2_0 PS20Caps;
-
- DWORD MaxVShaderInstructionsExecuted;
- DWORD MaxPShaderInstructionsExecuted;
- DWORD MaxVertexShader30InstructionSlots;
- DWORD MaxPixelShader30InstructionSlots;
-
BOOL VSClipping;
};
/* Bitmap for NP2 texcoord fixups (16 samplers max currently).
D3D9 has a limit of 16 samplers and the fixup is superfluous
in D3D10 (unconditional NP2 support mandatory). */
+ WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */
};
enum fog_src_type {
typedef struct {
void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
- void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
+ void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size);
void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
/* GL related defines */
/* ------------------ */
-#define GL_EXTCALL(FuncName) (GLINFO_LOCATION.FuncName)
+#define GL_EXTCALL(f) (gl_info->f)
#define D3DCOLOR_B_R(dw) (((dw) >> 16) & 0xFF)
#define D3DCOLOR_B_G(dw) (((dw) >> 8) & 0xFF)
(vec)[3] = D3DCOLOR_A(dw); \
} while(0)
-/* DirectX Device Limits */
-/* --------------------- */
-#define MAX_MIP_LEVELS 32 /* Maximum number of mipmap levels. */
#define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */
/* Checking of API calls */
TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__); \
\
} else do { \
- FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \
+ ERR(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \
debug_glerror(err), err, A, __FILE__, __LINE__); \
err = glGetError(); \
} while (err != GL_NO_ERROR); \
* Compilable extra diagnostics
*/
-/* Trace information per-vertex: (extremely high amount of trace) */
-#if 0 /* NOTE: Must be 0 in cvs */
-# define VTRACE(A) TRACE A
-#else
-# define VTRACE(A)
-#endif
-
/* TODO: Confirm each of these works when wined3d move completed */
#if 0 /* NOTE: Must be 0 in cvs */
/* To avoid having to get gigabytes of trace, the following can be compiled in, and at the start
struct wined3d_stream_info_element
{
- const struct GlPixelFormatDesc *format_desc;
+ const struct wined3d_format_desc *format_desc;
GLsizei stride;
const BYTE *data;
UINT stream_idx;
WINED3D_EVENT_QUERY_ERROR
};
+void wined3d_event_query_destroy(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
+enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+HRESULT wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+
struct wined3d_context
{
const struct wined3d_gl_info *gl_info;
DWORD numDirtyEntries;
DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */
- IWineD3DSurface *surface;
- IWineD3DSurface *current_rt;
+ IWineD3DSwapChainImpl *swapchain;
+ IWineD3DSurfaceImpl *current_rt;
DWORD tid; /* Thread ID which owns this context at the moment */
/* Stores some information about the context state for optimization */
HGLRC glCtx;
HWND win_handle;
HDC hdc;
- HPBUFFERARB pbuffer;
+ int pixel_format;
GLint aux_buffers;
/* FBOs */
struct list fbo_list;
struct list fbo_destroy_list;
struct fbo_entry *current_fbo;
- GLuint src_fbo;
GLuint dst_fbo;
GLuint fbo_read_binding;
GLuint fbo_draw_binding;
+ BOOL rebind_fbo;
+ IWineD3DSurfaceImpl **blit_targets;
/* Queries */
GLuint *free_occlusion_queries;
const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
+enum blit_operation
+{
+ BLIT_OP_BLIT,
+ BLIT_OP_COLOR_FILL
+};
+
/* Shaders for color conversions in blits */
struct blit_shader
{
HRESULT (*alloc_private)(IWineD3DDevice *iface);
void (*free_private)(IWineD3DDevice *iface);
- HRESULT (*set_shader)(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
- GLenum textype, UINT width, UINT height);
+ HRESULT (*set_shader)(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface);
void (*unset_shader)(IWineD3DDevice *iface);
- BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
+ BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+ const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format_desc *src_format_desc,
+ const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format_desc *dst_format_desc);
+ HRESULT (*color_fill)(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color);
};
extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN;
extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN;
+extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN;
-typedef enum ContextUsage {
- CTXUSAGE_RESOURCELOAD = 1, /* Only loads textures: No State is applied */
- CTXUSAGE_DRAWPRIM = 2, /* OpenGL states are set up for blitting DirectDraw surfaces */
- CTXUSAGE_BLIT = 3, /* OpenGL states are set up 3D drawing */
- CTXUSAGE_CLEAR = 4, /* Drawable and states are set up for clearing */
-} ContextUsage;
+/* Temporary blit_shader helper functions */
+HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect,
+ IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op,
+ DWORD Filter) DECLSPEC_HIDDEN;
-struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This,
- IWineD3DSurface *target, enum ContextUsage usage) DECLSPEC_HIDDEN;
+struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target) DECLSPEC_HIDDEN;
void context_alloc_event_query(struct wined3d_context *context,
struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_alloc_occlusion_query(struct wined3d_context *context,
struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
-void context_resource_released(IWineD3DDevice *iface,
- IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
-void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo) DECLSPEC_HIDDEN;
+void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device,
+ IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN;
+void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
+ IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN;
void context_attach_depth_stencil_fbo(struct wined3d_context *context,
- GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN;
-void context_attach_surface_fbo(const struct wined3d_context *context,
- GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) DECLSPEC_HIDDEN;
-struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win,
- BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *present_parameters) DECLSPEC_HIDDEN;
+ GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN;
+void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo) DECLSPEC_HIDDEN;
+struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
+ const struct wined3d_format_desc *ds_format_desc) DECLSPEC_HIDDEN;
void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
+void context_resource_released(IWineD3DDevice *iface,
+ IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
-
-void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN;
-HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN;
+void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN;
/* Macros for doing basic GPU detection based on opengl capabilities */
#define WINE_D3D6_CAPABLE(gl_info) (gl_info->supported[ARB_MULTITEXTURE])
#define WINE_D3D7_CAPABLE(gl_info) (gl_info->supported[ARB_TEXTURE_COMPRESSION] && gl_info->supported[ARB_TEXTURE_CUBE_MAP] && gl_info->supported[ARB_TEXTURE_ENV_DOT3])
#define WINE_D3D8_CAPABLE(gl_info) WINE_D3D7_CAPABLE(gl_info) && (gl_info->supported[ARB_MULTISAMPLE] && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
#define WINE_D3D9_CAPABLE(gl_info) WINE_D3D8_CAPABLE(gl_info) && (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[ARB_VERTEX_SHADER])
+#define WINE_D3D10_CAPABLE(gl_info) WINE_D3D9_CAPABLE(gl_info) && (gl_info->supported[EXT_GPU_SHADER4])
/*****************************************************************************
* Internal representation of a light
int redSize, greenSize, blueSize, alphaSize, colorSize;
int depthSize, stencilSize;
BOOL windowDrawable;
- BOOL pbufferDrawable;
BOOL doubleBuffer;
int auxBuffers;
int numSamples;
enum wined3d_gl_vendor
{
- GL_VENDOR_WINE,
+ GL_VENDOR_UNKNOWN,
GL_VENDOR_APPLE,
- GL_VENDOR_ATI,
+ GL_VENDOR_FGLRX,
GL_VENDOR_INTEL,
GL_VENDOR_MESA,
GL_VENDOR_NVIDIA,
enum wined3d_pci_vendor
{
- HW_VENDOR_WINE = 0x0000,
+ HW_VENDOR_SOFTWARE = 0x0000,
HW_VENDOR_ATI = 0x1002,
HW_VENDOR_NVIDIA = 0x10de,
HW_VENDOR_INTEL = 0x8086,
CARD_ATI_RADEON_XPRESS_200M = 0x5955,
CARD_ATI_RADEON_X700 = 0x5e4c,
CARD_ATI_RADEON_X1600 = 0x71c2,
- CARD_ATI_RADEON_HD2300 = 0x7210,
+ CARD_ATI_RADEON_HD2350 = 0x94c7,
CARD_ATI_RADEON_HD2600 = 0x9581,
CARD_ATI_RADEON_HD2900 = 0x9400,
CARD_ATI_RADEON_HD3200 = 0x9620,
struct wined3d_gl_info
{
+ DWORD glsl_version;
UINT vidmem;
struct wined3d_gl_limits limits;
DWORD reserved_glsl_constants;
WGL_EXT_FUNCS_GEN
#undef USE_GL_FUNC
- struct GlPixelFormatDesc *gl_formats;
+ struct wined3d_format_desc *gl_formats;
};
struct wined3d_driver_info
BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) DECLSPEC_HIDDEN;
BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
-extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram) DECLSPEC_HIDDEN;
+extern unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, unsigned int glram) DECLSPEC_HIDDEN;
extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
/*****************************************************************************
struct wined3d_adapter adapters[1];
} IWineD3DImpl;
-extern const IWineD3DVtbl IWineD3D_Vtbl DECLSPEC_HIDDEN;
-
+HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent) DECLSPEC_HIDDEN;
BOOL wined3d_register_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
-BOOL InitAdapters(IWineD3DImpl *This) DECLSPEC_HIDDEN;
-
-/* A helper function that dumps a resource list */
-void dumpResources(struct list *list) DECLSPEC_HIDDEN;
/*****************************************************************************
* IWineD3DDevice implementation structure
unsigned int highest_dirty_ps_const, highest_dirty_vs_const;
/* Render Target Support */
- IWineD3DSurface **render_targets;
- IWineD3DSurface *auto_depth_stencil_buffer;
- IWineD3DSurface *stencilBufferTarget;
+ IWineD3DSurfaceImpl **render_targets;
+ IWineD3DSurfaceImpl *auto_depth_stencil;
+ IWineD3DSurfaceImpl *onscreen_depth_stencil;
+ IWineD3DSurfaceImpl *depth_stencil;
/* palettes texture management */
UINT NumberOfPalettes;
/* Stream source management */
struct wined3d_stream_info strided_streams;
const WineDirect3DVertexStridedData *up_strided;
+ struct wined3d_event_query *buffer_queries[MAX_ATTRIBS];
+ unsigned int num_buffer_queries;
/* Context management */
struct wined3d_context **contexts;
UINT numContexts;
- struct wined3d_context *pbufferContext; /* The context that has a pbuffer as drawable */
- DWORD pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
/* High level patch management */
#define PATCHMAP_SIZE 43
struct WineD3DRectPatch *currentPatch;
};
+BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN;
HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
UINT adapter_idx, WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags,
IUnknown *parent, IWineD3DDeviceParent *device_parent) DECLSPEC_HIDDEN;
void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource) DECLSPEC_HIDDEN;
void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) DECLSPEC_HIDDEN;
+void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, struct wined3d_context *context,
+ IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN;
void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN;
WINED3DPOOL pool;
UINT size;
DWORD usage;
- const struct GlPixelFormatDesc *format_desc;
+ const struct wined3d_format_desc *format_desc;
DWORD priority;
BYTE *allocatedMemory; /* Pointer to the real data location */
BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */
HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid,
void *data, DWORD *data_size) DECLSPEC_HIDDEN;
HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type,
- IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
+ IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format_desc *format_desc,
WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface) DECLSPEC_HIDDEN;
DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority) DECLSPEC_HIDDEN;
const void *data, DWORD data_size, DWORD flags) DECLSPEC_HIDDEN;
/* Tests show that the start address of resources is 32 byte aligned */
-#define RESOURCE_ALIGNMENT 32
+#define RESOURCE_ALIGNMENT 16
/*****************************************************************************
* IWineD3DBaseTexture D3D- > openGL state map lookups
WINED3DTEXSTA_MAXMIPLEVEL = 7,
WINED3DTEXSTA_MAXANISOTROPY = 8,
WINED3DTEXSTA_SRGBTEXTURE = 9,
- WINED3DTEXSTA_ELEMENTINDEX = 10,
- WINED3DTEXSTA_DMAPOFFSET = 11,
- WINED3DTEXSTA_TSSADDRESSW = 12,
- MAX_WINETEXTURESTATES = 13,
+ WINED3DTEXSTA_SHADOW = 10,
+ MAX_WINETEXTURESTATES = 11,
} winetexturestates;
enum WINED3DSRGB
typedef struct IWineD3DBaseTextureClass
{
struct gl_texture texture_rgb, texture_srgb;
- UINT levels;
+ IWineD3DResourceImpl **sub_resources;
+ UINT layer_count;
+ UINT level_count;
float pow2Matrix[16];
UINT LOD;
WINED3DTEXTUREFILTERTYPE filterType;
void (*internal_preload)(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
} IWineD3DBaseTextureClass;
-void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
-BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
-BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
-void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) DECLSPEC_HIDDEN;
+void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
+BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN;
+BOOL surface_is_offscreen(IWineD3DSurfaceImpl *iface) DECLSPEC_HIDDEN;
+void surface_prepare_texture(IWineD3DSurfaceImpl *surface,
+ const struct wined3d_gl_info *gl_info, BOOL srgb) DECLSPEC_HIDDEN;
typedef struct IWineD3DBaseTextureImpl
{
BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN;
DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN;
DWORD basetexture_get_lod(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN;
-HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type,
- IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
- WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture,
+ UINT layer, UINT level) DECLSPEC_HIDDEN;
+HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count,
+ WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage,
+ const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent,
+ const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface,
WINED3DTEXTUREFILTERTYPE filter_type) DECLSPEC_HIDDEN;
BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty) DECLSPEC_HIDDEN;
IWineD3DBaseTextureClass baseTexture;
/* IWineD3DTexture */
- IWineD3DSurface *surfaces[MAX_MIP_LEVELS];
UINT target;
BOOL cond_np2;
const IWineD3DCubeTextureVtbl *lpVtbl;
IWineD3DResourceClass resource;
IWineD3DBaseTextureClass baseTexture;
-
- /* IWineD3DCubeTexture */
- IWineD3DSurface *surfaces[6][MAX_MIP_LEVELS];
} IWineD3DCubeTextureImpl;
HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels,
const IWineD3DVolumeTextureVtbl *lpVtbl;
IWineD3DResourceClass resource;
IWineD3DBaseTextureClass baseTexture;
-
- /* IWineD3DVolumeTexture */
- IWineD3DVolume *volumes[MAX_MIP_LEVELS];
} IWineD3DVolumeTextureImpl;
HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT height,
struct fbo_entry
{
struct list entry;
- IWineD3DSurface **render_targets;
- IWineD3DSurface *depth_stencil;
+ IWineD3DSurfaceImpl **render_targets;
+ IWineD3DSurfaceImpl *depth_stencil;
BOOL attached;
GLuint id;
};
/* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
void (*get_drawable_size)(struct wined3d_context *context, UINT *width, UINT *height);
- /* Oversized texture */
- RECT glRect;
-
/* PBO */
GLuint pbo;
GLuint texture_name;
struct list renderbuffers;
renderbuffer_entry_t *current_renderbuffer;
+ SIZE ds_current_size;
/* DirectDraw clippers */
IWineD3DClipper *clipper;
extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl DECLSPEC_HIDDEN;
extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl DECLSPEC_HIDDEN;
-UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc,
+UINT surface_calculate_size(const struct wined3d_format_desc *format_desc,
UINT alignment, UINT width, UINT height) DECLSPEC_HIDDEN;
void surface_gdi_cleanup(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN;
HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
/* Predeclare the shared Surface functions */
HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface,
void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
-void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
+void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect,
+ const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) DECLSPEC_HIDDEN;
void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPEC_HIDDEN;
/* Surface flags: */
-#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */
#define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for GetDC */
#define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */
#define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */
/* In some conditions the surface memory must not be freed:
- * SFLAG_OVERSIZE: Not all data can be kept in GL
* SFLAG_CONVERTED: Converting the data back would take too long
* SFLAG_DIBSECTION: The dib code manages the memory
* SFLAG_LOCKED: The app requires access to the surface data
* SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
* SFLAG_CLIENT: OpenGL uses our memory as backup
*/
-#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \
- SFLAG_CONVERTED | \
+#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \
SFLAG_DIBSECTION | \
SFLAG_LOCKED | \
SFLAG_DYNLOCK | \
SFLAG_DS_OFFSCREEN)
#define SFLAG_DS_DISCARDED SFLAG_DS_LOCATIONS
-BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) DECLSPEC_HIDDEN;
-
typedef enum {
NO_CONVERSION,
CONVERT_PALETTED,
CONVERT_PALETTED_CK,
CONVERT_CK_565,
CONVERT_CK_5551,
- CONVERT_CK_4444,
- CONVERT_CK_4444_ARGB,
- CONVERT_CK_1555,
- CONVERT_555,
CONVERT_CK_RGB24,
- CONVERT_CK_8888,
- CONVERT_CK_8888_ARGB,
- CONVERT_RGB32_888,
- CONVERT_V8U8,
- CONVERT_L6V5U5,
- CONVERT_X8L8V8U8,
- CONVERT_Q8W8V8U8,
- CONVERT_V16U16,
- CONVERT_A4L4,
- CONVERT_G16R16,
- CONVERT_R16G16F,
- CONVERT_R32G32F,
- CONVERT_D15S1,
- CONVERT_D24X4S4,
- CONVERT_D24FS8,
+ CONVERT_RGB32_888
} CONVERT_TYPES;
-HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format,
- GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) DECLSPEC_HIDDEN;
+HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing,
+ struct wined3d_format_desc *desc, CONVERT_TYPES *convert) DECLSPEC_HIDDEN;
+void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) DECLSPEC_HIDDEN;
BOOL palette9_changed(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN;
struct wined3d_vertex_declaration_element
{
- const struct GlPixelFormatDesc *format_desc;
+ const struct wined3d_format_desc *format_desc;
BOOL ffp_valid;
WORD input_slot;
WORD offset;
IWineD3DDeviceImpl *device, WINED3DSTATEBLOCKTYPE type) DECLSPEC_HIDDEN;
void stateblock_init_contained_states(IWineD3DStateBlockImpl *object) DECLSPEC_HIDDEN;
+static inline void stateblock_apply_state(DWORD state, IWineD3DStateBlockImpl *stateblock,
+ struct wined3d_context *context)
+{
+ const struct StateEntry *statetable = stateblock->device->StateTable;
+ DWORD rep = statetable[state].representative;
+ statetable[rep].apply(rep, stateblock, context);
+}
+
/* Direct3D terminology with little modifications. We do not have an issued state
* because only the driver knows about it, but we have a created state because d3d
* allows GetData on a created issue, but opengl doesn't
#define WINED3D_BUFFER_CREATEBO 0x04 /* Attempt to create a buffer object next PreLoad */
#define WINED3D_BUFFER_DOUBLEBUFFER 0x08 /* Use a vbo and local allocated memory */
#define WINED3D_BUFFER_FLUSH 0x10 /* Manual unmap flushing */
+#define WINED3D_BUFFER_DISCARD 0x20 /* A DISCARD lock has occurred since the last PreLoad */
+#define WINED3D_BUFFER_NOSYNC 0x40 /* All locks since the last PreLoad had NOOVERWRITE set */
+#define WINED3D_BUFFER_APPLESYNC 0x80 /* Using sync as in GL_APPLE_flush_buffer_range */
struct wined3d_buffer
{
LONG lock_count;
struct wined3d_map_range *maps;
ULONG maps_size, modified_areas;
+ struct wined3d_event_query *query;
/* conversion stuff */
UINT decl_change_count, full_conversion_count;
UINT *conversion_shift; /* NULL if no shifted conversion */
};
-const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) DECLSPEC_HIDDEN;
-BYTE *buffer_get_sysmem(struct wined3d_buffer *This) DECLSPEC_HIDDEN;
+const BYTE *buffer_get_memory(IWineD3DBuffer *iface, const struct wined3d_gl_info *gl_info,
+ GLuint *buffer_object) DECLSPEC_HIDDEN;
+BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint,
const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
IUnknown *parent;
};
-extern const IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl DECLSPEC_HIDDEN;
+void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
+ IWineD3DResource *resource, IUnknown *parent) DECLSPEC_HIDDEN;
/*****************************************************************************
* IWineD3DSwapChainImpl implementation structure (extends IUnknown)
IWineD3DDeviceImpl *device;
/* IWineD3DSwapChain fields */
- IWineD3DSurface **backBuffer;
- IWineD3DSurface *frontBuffer;
+ IWineD3DSurfaceImpl **back_buffers;
+ IWineD3DSurfaceImpl *front_buffer;
WINED3DPRESENT_PARAMETERS presentParms;
DWORD orig_width, orig_height;
WINED3DFORMAT orig_fmt;
WINED3DGAMMARAMP orig_gamma;
BOOL render_to_fbo;
+ const struct wined3d_format_desc *ds_format;
- long prev_time, frames; /* Performance tracking */
+ LONG prev_time, frames; /* Performance tracking */
unsigned int vSyncCounter;
struct wined3d_context **context;
unsigned int num_contexts;
HWND win_handle;
+ HWND device_window;
};
const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN;
HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface,
WINED3DDISPLAYMODE *pMode) DECLSPEC_HIDDEN;
HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface,
- IWineD3DDevice **ppDevice) DECLSPEC_HIDDEN;
+ IWineD3DDevice **device) DECLSPEC_HIDDEN;
HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface,
WINED3DPRESENT_PARAMETERS *pPresentationParameters) DECLSPEC_HIDDEN;
HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface,
void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN;
const char *debug_surflocation(DWORD flag) DECLSPEC_HIDDEN;
+/* Color conversion routines */
+DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) DECLSPEC_HIDDEN;
+
/* Routines for GL <-> D3D values */
GLenum StencilOp(DWORD op) DECLSPEC_HIDDEN;
GLenum CompareFunc(DWORD func) DECLSPEC_HIDDEN;
void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
-void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) DECLSPEC_HIDDEN;
-GLenum surface_get_gl_buffer(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
-void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
-void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) DECLSPEC_HIDDEN;
-void surface_set_compatible_renderbuffer(IWineD3DSurface *iface,
+void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) DECLSPEC_HIDDEN;
+GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN;
+void surface_load_ds_location(IWineD3DSurfaceImpl *surface,
+ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
+void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
+void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface,
unsigned int width, unsigned int height) DECLSPEC_HIDDEN;
-void surface_set_texture_name(IWineD3DSurface *iface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
-void surface_set_texture_target(IWineD3DSurface *iface, GLenum target) DECLSPEC_HIDDEN;
+void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
+void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) DECLSPEC_HIDDEN;
-BOOL getColorBits(const struct GlPixelFormatDesc *format_desc,
+BOOL getColorBits(const struct wined3d_format_desc *format_desc,
short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize) DECLSPEC_HIDDEN;
-BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc,
+BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc,
short *depthSize, short *stencilSize) DECLSPEC_HIDDEN;
/* Math utils */
DWORD Flags;
};
-extern const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl DECLSPEC_HIDDEN;
-DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) DECLSPEC_HIDDEN;
+HRESULT wined3d_palette_init(IWineD3DPaletteImpl *palette, IWineD3DDeviceImpl *device,
+ DWORD flags, const PALETTEENTRY *entries, IUnknown *parent) DECLSPEC_HIDDEN;
/* DirectDraw utility functions */
extern WINED3DFORMAT pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN;
*/
/* WineD3D pixel format flags */
-#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1
-#define WINED3DFMT_FLAG_FILTERING 0x2
-#define WINED3DFMT_FLAG_DEPTH 0x4
-#define WINED3DFMT_FLAG_STENCIL 0x8
-#define WINED3DFMT_FLAG_RENDERTARGET 0x10
-#define WINED3DFMT_FLAG_FOURCC 0x20
-#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x40
-#define WINED3DFMT_FLAG_COMPRESSED 0x80
-#define WINED3DFMT_FLAG_GETDC 0x100
-
-struct GlPixelFormatDesc
+#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x00000001
+#define WINED3DFMT_FLAG_FILTERING 0x00000002
+#define WINED3DFMT_FLAG_DEPTH 0x00000004
+#define WINED3DFMT_FLAG_STENCIL 0x00000008
+#define WINED3DFMT_FLAG_RENDERTARGET 0x00000010
+#define WINED3DFMT_FLAG_FOURCC 0x00000020
+#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040
+#define WINED3DFMT_FLAG_COMPRESSED 0x00000080
+#define WINED3DFMT_FLAG_GETDC 0x00000100
+#define WINED3DFMT_FLAG_FLOAT 0x00000200
+#define WINED3DFMT_FLAG_BUMPMAP 0x00000400
+#define WINED3DFMT_FLAG_SRGB_READ 0x00000800
+#define WINED3DFMT_FLAG_SRGB_WRITE 0x00001000
+#define WINED3DFMT_FLAG_VTF 0x00002000
+#define WINED3DFMT_FLAG_SHADOW 0x00004000
+
+struct wined3d_format_desc
{
WINED3DFORMAT format;
DWORD red_mask;
GLint rtInternal;
GLint glFormat;
GLint glType;
+ UINT conv_byte_count;
unsigned int Flags;
float heightscale;
struct color_fixup_desc color_fixup;
+ void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
};
-const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt,
+const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock)
return (stateblock->pixelShader && stateblock->device->ps_selected_mode != SHADER_NONE);
}
-void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface,
- WINED3DRECT *src_rect, IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect,
- const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) DECLSPEC_HIDDEN;
+void stretch_rect_fbo(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface,
+ const RECT *src_rect, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect,
+ const WINED3DTEXTUREFILTERTYPE filter) DECLSPEC_HIDDEN;
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
+#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff))
+
#endif
typedef enum _WINED3DRENDERSTATETYPE
{
- WINED3DRS_TEXTUREHANDLE = 1, /* d3d7 */
WINED3DRS_ANTIALIAS = 2, /* d3d7 */
- WINED3DRS_TEXTUREADDRESS = 3, /* d3d7 */
WINED3DRS_TEXTUREPERSPECTIVE = 4, /* d3d7 */
WINED3DRS_WRAPU = 5, /* d3d7 */
WINED3DRS_WRAPV = 6, /* d3d7 */
WINED3DRS_ZWRITEENABLE = 14,
WINED3DRS_ALPHATESTENABLE = 15,
WINED3DRS_LASTPIXEL = 16,
- WINED3DRS_TEXTUREMAG = 17, /* d3d7 */
- WINED3DRS_TEXTUREMIN = 18, /* d3d7 */
WINED3DRS_SRCBLEND = 19,
WINED3DRS_DESTBLEND = 20,
- WINED3DRS_TEXTUREMAPBLEND = 21, /* d3d7 */
WINED3DRS_CULLMODE = 22,
WINED3DRS_ZFUNC = 23,
WINED3DRS_ALPHAREF = 24,
WINED3DRS_STIPPLEENABLE = 39, /* d3d7 */
WINED3DRS_EDGEANTIALIAS = 40, /* d3d7, d3d8 */
WINED3DRS_COLORKEYENABLE = 41, /* d3d7 */
- WINED3DRS_BORDERCOLOR = 43, /* d3d7 */
- WINED3DRS_TEXTUREADDRESSU = 44, /* d3d7 */
- WINED3DRS_TEXTUREADDRESSV = 45, /* d3d7 */
WINED3DRS_MIPMAPLODBIAS = 46, /* d3d7 */
WINED3DRS_ZBIAS = 47, /* d3d7, d3d8 */
WINED3DRS_RANGEFOGENABLE = 48,
WINED3DRS_STENCILMASK = 58,
WINED3DRS_STENCILWRITEMASK = 59,
WINED3DRS_TEXTUREFACTOR = 60,
- WINED3DRS_STIPPLEPATTERN00 = 64,
- WINED3DRS_STIPPLEPATTERN01 = 65,
- WINED3DRS_STIPPLEPATTERN02 = 66,
- WINED3DRS_STIPPLEPATTERN03 = 67,
- WINED3DRS_STIPPLEPATTERN04 = 68,
- WINED3DRS_STIPPLEPATTERN05 = 69,
- WINED3DRS_STIPPLEPATTERN06 = 70,
- WINED3DRS_STIPPLEPATTERN07 = 71,
- WINED3DRS_STIPPLEPATTERN08 = 72,
- WINED3DRS_STIPPLEPATTERN09 = 73,
- WINED3DRS_STIPPLEPATTERN10 = 74,
- WINED3DRS_STIPPLEPATTERN11 = 75,
- WINED3DRS_STIPPLEPATTERN12 = 76,
- WINED3DRS_STIPPLEPATTERN13 = 77,
- WINED3DRS_STIPPLEPATTERN14 = 78,
- WINED3DRS_STIPPLEPATTERN15 = 79,
- WINED3DRS_STIPPLEPATTERN16 = 80,
- WINED3DRS_STIPPLEPATTERN17 = 81,
- WINED3DRS_STIPPLEPATTERN18 = 82,
- WINED3DRS_STIPPLEPATTERN19 = 83,
- WINED3DRS_STIPPLEPATTERN20 = 84,
- WINED3DRS_STIPPLEPATTERN21 = 85,
- WINED3DRS_STIPPLEPATTERN22 = 86,
- WINED3DRS_STIPPLEPATTERN23 = 87,
- WINED3DRS_STIPPLEPATTERN24 = 88,
- WINED3DRS_STIPPLEPATTERN25 = 89,
- WINED3DRS_STIPPLEPATTERN26 = 90,
- WINED3DRS_STIPPLEPATTERN27 = 91,
- WINED3DRS_STIPPLEPATTERN28 = 92,
- WINED3DRS_STIPPLEPATTERN29 = 93,
- WINED3DRS_STIPPLEPATTERN30 = 94,
- WINED3DRS_STIPPLEPATTERN31 = 95,
WINED3DRS_WRAP0 = 128,
WINED3DRS_WRAP1 = 129,
WINED3DRS_WRAP2 = 130,
WINED3DRS_COLORWRITEENABLE = 168,
WINED3DRS_TWEENFACTOR = 170,
WINED3DRS_BLENDOP = 171,
- WINED3DRS_POSITIONORDER = 172,
- WINED3DRS_NORMALORDER = 173,
WINED3DRS_POSITIONDEGREE = 172,
WINED3DRS_NORMALDEGREE = 173,
WINED3DRS_SCISSORTESTENABLE = 174,
[in] D3DCB_ENUMRESOURCES callback,
[in] void *data
);
+ HRESULT GetSurfaceFromDC(
+ [in] HDC dc,
+ [out] IWineD3DSurface **surface
+ );
+ HRESULT AcquireFocusWindow(
+ [in] HWND window
+ );
+ void ReleaseFocusWindow(
+ );
}
IWineD3D *WineDirect3DCreate(UINT dxVersion, IUnknown *parent);