volume.c
precomp.h)
-add_library(d3d8 MODULE
+add_library(d3d8 SHARED
${SOURCE}
guid.c
version.rc
LONG refcount;
struct wined3d_swapchain *wined3d_swapchain;
IDirect3DDevice8 *parent_device;
- unsigned int swap_interval;
};
HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
- unsigned int swap_interval, struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
+ struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
struct d3d8_surface
{
}
static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
- const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval)
+ const struct wined3d_swapchain_desc *swapchain_desc)
{
present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
= d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK;
present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
- present_parameters->FullScreen_PresentationInterval = presentation_interval;
+ present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
}
static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect)
}
}
-static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval)
-{
- switch (interval)
- {
- case D3DPRESENT_INTERVAL_IMMEDIATE:
- return WINED3D_SWAP_INTERVAL_IMMEDIATE;
- case D3DPRESENT_INTERVAL_ONE:
- return WINED3D_SWAP_INTERVAL_ONE;
- case D3DPRESENT_INTERVAL_TWO:
- return WINED3D_SWAP_INTERVAL_TWO;
- case D3DPRESENT_INTERVAL_THREE:
- return WINED3D_SWAP_INTERVAL_THREE;
- case D3DPRESENT_INTERVAL_FOUR:
- return WINED3D_SWAP_INTERVAL_FOUR;
- default:
- FIXME("Unhandled presentation interval %#x.\n", interval);
- case D3DPRESENT_INTERVAL_DEFAULT:
- return WINED3D_SWAP_INTERVAL_DEFAULT;
- }
-}
-
static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
const D3DPRESENT_PARAMETERS *present_parameters)
{
WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
return FALSE;
}
- switch (present_parameters->FullScreen_PresentationInterval)
- {
- case D3DPRESENT_INTERVAL_DEFAULT:
- case D3DPRESENT_INTERVAL_ONE:
- case D3DPRESENT_INTERVAL_TWO:
- case D3DPRESENT_INTERVAL_THREE:
- case D3DPRESENT_INTERVAL_FOUR:
- case D3DPRESENT_INTERVAL_IMMEDIATE:
- break;
- default:
- WARN("Invalid presentation interval %#x.\n",
- present_parameters->FullScreen_PresentationInterval);
- return FALSE;
- }
swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
swapchain_desc->flags
= (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
+ swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval;
swapchain_desc->auto_restore_display_mode = TRUE;
if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK)
caps->Caps = wined3d_caps->Caps;
caps->Caps2 = wined3d_caps->Caps2;
caps->Caps3 = wined3d_caps->Caps3;
- caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE;
+ caps->PresentationIntervals = wined3d_caps->PresentationIntervals;
caps->CursorCaps = wined3d_caps->CursorCaps;
caps->DevCaps = wined3d_caps->DevCaps;
caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps;
caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion;
caps->MaxPixelShaderValue = wined3d_caps->PixelShader1xMaxValue;
- caps->Caps2 &= D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_CANRENDERWINDOWED
- | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_FULLSCREENGAMMA
- | D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_RESERVED;
- caps->Caps3 &= D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_RESERVED;
- caps->PrimitiveMiscCaps &= D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP
- | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW
- | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
- | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP
- | D3DPMISCCAPS_NULLREFERENCE;
- caps->RasterCaps &= D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST
- | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_ANTIALIASEDGES
- | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR
- | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER
- | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE
- | D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE;
- caps->SrcBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
- | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
- | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
- | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
- | D3DPBLENDCAPS_BOTHINVSRCALPHA;
- caps->DestBlendCaps &= D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
- | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
- | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
- | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
- | D3DPBLENDCAPS_BOTHINVSRCALPHA;
- caps->TextureCaps &= D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA
- | D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE
- | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL
- | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP
- | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP
- | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2;
- caps->TextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
- | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT
- | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
- | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC
- | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC;
- caps->CubeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
- | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT
- | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
- | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC
- | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC;
- caps->VolumeTextureFilterCaps &= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
- | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT
- | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
- | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFAFLATCUBIC
- | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC;
- caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
- caps->VertexProcessingCaps &= D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7
- | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER
- | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_NO_VSDT_UBYTE4;
-
/* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
if (caps->PixelShaderVersion)
caps->PixelShaderVersion = D3DPS_VERSION(1, 4);
else
caps->VertexShaderVersion = D3DVS_VERSION(0, 0);
caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
+
+ caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
}
/* Handle table functions */
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
struct wined3d_swapchain_desc desc;
struct d3d8_swapchain *object;
- unsigned int swap_interval;
- unsigned int i, count;
+ UINT i, count;
HRESULT hr;
TRACE("iface %p, present_parameters %p, swapchain %p.\n",
if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters))
return D3DERR_INVALIDCALL;
- swap_interval = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval);
- if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, swap_interval, &object)))
+ if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
*swapchain = &object->IDirect3DSwapChain8_iface;
- present_parameters_from_wined3d_swapchain_desc(present_parameters,
- &desc, present_parameters->FullScreen_PresentationInterval);
+ present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
return hr;
}
NULL, reset_enum_callback, TRUE)))
{
present_parameters->BackBufferCount = swapchain_desc.backbuffer_count;
- device->implicit_swapchain->swap_interval
- = wined3dswapinterval_from_d3d(present_parameters->FullScreen_PresentationInterval);
wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE,
!!swapchain_desc.enable_auto_depth_stencil);
static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport)
{
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
- struct wined3d_sub_resource_desc rt_desc;
- struct wined3d_rendertarget_view *rtv;
- struct d3d8_surface *surface;
struct wined3d_viewport vp;
TRACE("iface %p, viewport %p.\n", iface, viewport);
- wined3d_mutex_lock();
- if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
- {
- wined3d_mutex_unlock();
- return D3DERR_NOTFOUND;
- }
- surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
- wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
-
- if (viewport->X > rt_desc.width || viewport->Width > rt_desc.width - viewport->X
- || viewport->Y > rt_desc.height || viewport->Height > rt_desc.height - viewport->Y)
- {
- WARN("Invalid viewport, returning D3DERR_INVALIDCALL.\n");
- wined3d_mutex_unlock();
- return D3DERR_INVALIDCALL;
- }
-
vp.x = viewport->X;
vp.y = viewport->Y;
vp.width = viewport->Width;
vp.min_z = viewport->MinZ;
vp.max_z = viewport->MaxZ;
- wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
+ wined3d_mutex_lock();
+ wined3d_device_set_viewport(device->wined3d_device, &vp);
wined3d_mutex_unlock();
return D3D_OK;
TRACE("iface %p, viewport %p.\n", iface, viewport);
wined3d_mutex_lock();
- wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport);
+ wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
wined3d_mutex_unlock();
viewport->X = wined3d_viewport.x;
static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface,
DWORD info_id, void *info, DWORD info_size)
{
- TRACE("iface %p, info_id %#x, info %p, info_size %u.\n", iface, info_id, info, info_size);
+ FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size);
- if (info_id < 4)
- return E_FAIL;
- return S_FALSE;
+ return D3D_OK;
}
static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface,
InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_NOT_RESET, D3D8_DEVICE_STATE_LOST);
}
-static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent,
- enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
void **parent, const struct wined3d_parent_ops **parent_ops)
{
- TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
- device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
+ struct d3d8_surface *d3d_surface;
- if (type == WINED3D_RTYPE_TEXTURE_2D)
- {
- struct d3d8_surface *d3d_surface;
+ TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
- if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
- return E_OUTOFMEMORY;
+ if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
+ return E_OUTOFMEMORY;
- surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
- *parent = d3d_surface;
- TRACE("Created surface %p.\n", d3d_surface);
- }
- else if (type == WINED3D_RTYPE_TEXTURE_3D)
- {
- struct d3d8_volume *d3d_volume;
+ surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
+ *parent = d3d_surface;
+ TRACE("Created surface %p.\n", d3d_surface);
- if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
- return E_OUTOFMEMORY;
+ return D3D_OK;
+}
- volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
- *parent = d3d_volume;
- TRACE("Created volume %p.\n", d3d_volume);
- }
- else
- {
- ERR("Unhandled resource type %#x.\n", type);
- return E_FAIL;
- }
+static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+ void **parent, const struct wined3d_parent_ops **parent_ops)
+{
+ struct d3d8_volume *d3d_volume;
+
+ TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
+
+ if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
+ return E_OUTOFMEMORY;
+
+ volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
+ *parent = d3d_volume;
+ TRACE("Created volume %p.\n", d3d_volume);
return D3D_OK;
}
TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain);
- if (FAILED(hr = d3d8_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain)))
+ if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain)))
{
WARN("Failed to create swapchain, hr %#x.\n", hr);
*swapchain = NULL;
device_parent_wined3d_device_created,
device_parent_mode_changed,
device_parent_activate,
- device_parent_texture_sub_resource_created,
+ device_parent_surface_created,
+ device_parent_volume_created,
device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
wined3d_mutex_unlock();
- present_parameters_from_wined3d_swapchain_desc(parameters,
- &swapchain_desc, parameters->FullScreen_PresentationInterval);
+ present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc);
device->declArraySize = 16;
if (!(device->decls = heap_alloc(device->declArraySize * sizeof(*device->decls))))
wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain);
- device->implicit_swapchain->swap_interval
- = wined3dswapinterval_from_d3d(parameters->FullScreen_PresentationInterval);
device->d3d_parent = &parent->IDirect3D8_iface;
IDirect3D8_AddRef(device->d3d_parent);
DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
| WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
| WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART
- | WINED3D_LEGACY_CUBEMAP_FILTERING;
+ | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT;
d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
d3d8->refcount = 1;
wined3d_mutex_lock();
hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
- src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0);
+ src_rect, dst_rect, dst_window_override, 0, 0);
wined3d_mutex_unlock();
return hr;
};
static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device,
- struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
+ struct wined3d_swapchain_desc *desc)
{
HRESULT hr;
swapchain->refcount = 1;
swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl;
- swapchain->swap_interval = swap_interval;
wined3d_mutex_lock();
hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
}
HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
- unsigned int swap_interval, struct d3d8_swapchain **swapchain)
+ struct d3d8_swapchain **swapchain)
{
struct d3d8_swapchain *object;
HRESULT hr;
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- if (FAILED(hr = swapchain_init(object, device, desc, swap_interval)))
+ if (FAILED(hr = swapchain_init(object, device, desc)))
{
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
heap_free(object);
volume.c
precomp.h)
-add_library(d3d9 MODULE
+add_library(d3d9 SHARED
${SOURCE}
guid.c
version.rc
enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags) DECLSPEC_HIDDEN;
void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
- const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) DECLSPEC_HIDDEN;
+ const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN;
void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) DECLSPEC_HIDDEN;
struct d3d9
UINT index_buffer_size;
UINT index_buffer_pos;
+ struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS];
struct d3d9_surface *render_targets[D3D_MAX_SIMULTANEOUS_RENDERTARGETS];
LONG device_state;
LONG refcount;
struct wined3d_swapchain *wined3d_swapchain;
IDirect3DDevice9Ex *parent_device;
- unsigned int swap_interval;
};
HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc,
- unsigned int swap_interval, struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN;
+ struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN;
struct d3d9_surface
{
}
void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
- const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval)
+ const struct wined3d_swapchain_desc *swapchain_desc)
{
present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
= d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK;
present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
- present_parameters->PresentationInterval = presentation_interval;
+ present_parameters->PresentationInterval = swapchain_desc->swap_interval;
}
static enum wined3d_swap_effect wined3dswapeffect_from_d3dswapeffect(D3DSWAPEFFECT effect)
}
}
-static enum wined3d_swap_interval wined3dswapinterval_from_d3d(DWORD interval)
-{
- switch (interval)
- {
- case D3DPRESENT_INTERVAL_IMMEDIATE:
- return WINED3D_SWAP_INTERVAL_IMMEDIATE;
- case D3DPRESENT_INTERVAL_ONE:
- return WINED3D_SWAP_INTERVAL_ONE;
- case D3DPRESENT_INTERVAL_TWO:
- return WINED3D_SWAP_INTERVAL_TWO;
- case D3DPRESENT_INTERVAL_THREE:
- return WINED3D_SWAP_INTERVAL_THREE;
- case D3DPRESENT_INTERVAL_FOUR:
- return WINED3D_SWAP_INTERVAL_FOUR;
- default:
- FIXME("Unhandled presentation interval %#x.\n", interval);
- case D3DPRESENT_INTERVAL_DEFAULT:
- return WINED3D_SWAP_INTERVAL_DEFAULT;
- }
-}
-
static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended)
{
WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
return FALSE;
}
- switch (present_parameters->PresentationInterval)
- {
- case D3DPRESENT_INTERVAL_DEFAULT:
- case D3DPRESENT_INTERVAL_ONE:
- case D3DPRESENT_INTERVAL_TWO:
- case D3DPRESENT_INTERVAL_THREE:
- case D3DPRESENT_INTERVAL_FOUR:
- case D3DPRESENT_INTERVAL_IMMEDIATE:
- break;
- default:
- WARN("Invalid presentation interval %#x.\n", present_parameters->PresentationInterval);
- return FALSE;
- }
swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
swapchain_desc->flags
= (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
+ swapchain_desc->swap_interval = present_parameters->PresentationInterval;
swapchain_desc->auto_restore_display_mode = TRUE;
if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK)
caps->Caps = wined3d_caps->Caps;
caps->Caps2 = wined3d_caps->Caps2;
caps->Caps3 = wined3d_caps->Caps3;
- caps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE | D3DPRESENT_INTERVAL_ONE;
+ caps->PresentationIntervals = wined3d_caps->PresentationIntervals;
caps->CursorCaps = wined3d_caps->CursorCaps;
caps->DevCaps = wined3d_caps->DevCaps;
caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps;
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
struct wined3d_swapchain_desc desc;
struct d3d9_swapchain *object;
- unsigned int swap_interval;
- unsigned int i, count;
+ UINT i, count;
HRESULT hr;
TRACE("iface %p, present_parameters %p, swapchain %p.\n",
if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters,
device->d3d_parent->extended))
return D3DERR_INVALIDCALL;
- swap_interval = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval);
- if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, swap_interval, &object)))
+ if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
*swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
- present_parameters_from_wined3d_swapchain_desc(present_parameters,
- &desc, present_parameters->PresentationInterval);
+ present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
return hr;
}
}
else
{
- device->implicit_swapchains[0]->swap_interval
- = wined3dswapinterval_from_d3d(present_parameters->PresentationInterval);
wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc);
present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width;
present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height;
device->device_state = D3D9_DEVICE_STATE_OK;
}
+ if (!device->d3d_parent->extended)
+ for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
+ device->textures[i] = NULL;
+
rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0);
device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i)
const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- struct d3d9_swapchain *swapchain;
- unsigned int i;
+ UINT i;
HRESULT hr;
TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
wined3d_mutex_lock();
for (i = 0; i < device->implicit_swapchain_count; ++i)
{
- swapchain = device->implicit_swapchains[i];
- if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
- src_rect, dst_rect, dst_window_override, swapchain->swap_interval, 0)))
+ if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
+ src_rect, dst_rect, dst_window_override, 0, 0)))
{
wined3d_mutex_unlock();
return hr;
hr = wined3d_device_copy_sub_resource_region(device->wined3d_device,
wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0,
dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture),
- src->sub_resource_idx, &src_box, 0);
+ src->sub_resource_idx, &src_box);
if (SUCCEEDED(hr) && dst->texture)
d3d9_texture_flag_auto_gen_mipmap(dst->texture);
vp.max_z = viewport->MaxZ;
wined3d_mutex_lock();
- wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
+ wined3d_device_set_viewport(device->wined3d_device, &vp);
wined3d_mutex_unlock();
return D3D_OK;
TRACE("iface %p, viewport %p.\n", iface, viewport);
wined3d_mutex_lock();
- wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport);
+ wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
wined3d_mutex_unlock();
viewport->X = wined3d_viewport.x;
wined3d_mutex_lock();
hr = wined3d_device_set_texture(device->wined3d_device, stage,
texture_impl ? texture_impl->wined3d_texture : NULL);
+ if (SUCCEEDED(hr))
+ {
+ unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage;
+
+ if (stage < ARRAY_SIZE(device->textures))
+ device->textures[i] = texture_impl;
+ }
wined3d_mutex_unlock();
return hr;
TRACE("iface %p, rect %p.\n", iface, rect);
wined3d_mutex_lock();
- wined3d_device_set_scissor_rects(device->wined3d_device, 1, rect);
+ wined3d_device_set_scissor_rect(device->wined3d_device, rect);
wined3d_mutex_unlock();
return D3D_OK;
TRACE("iface %p, rect %p.\n", iface, rect);
wined3d_mutex_lock();
- wined3d_device_get_scissor_rects(device->wined3d_device, NULL, rect);
+ wined3d_device_get_scissor_rect(device->wined3d_device, rect);
wined3d_mutex_unlock();
return D3D_OK;
/* wined3d critical section must be taken by the caller. */
static void d3d9_generate_auto_mipmaps(struct d3d9_device *device)
{
- struct wined3d_texture *texture;
- unsigned int i, stage;
+ unsigned int i;
- for (i = 0; i < D3D9_MAX_TEXTURE_UNITS; ++i)
- {
- stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i;
- if ((texture = wined3d_device_get_texture(device->wined3d_device, stage)))
- d3d9_texture_gen_auto_mipmap(wined3d_texture_get_parent(texture));
- }
+ for (i = 0; i < ARRAY_SIZE(device->textures); ++i)
+ if (device->textures[i])
+ d3d9_texture_gen_auto_mipmap(device->textures[i]);
}
static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
const RGNDATA *dirty_region, DWORD flags)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- struct d3d9_swapchain *swapchain;
- unsigned int i;
+ UINT i;
HRESULT hr;
TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
wined3d_mutex_lock();
for (i = 0; i < device->implicit_swapchain_count; ++i)
{
- swapchain = device->implicit_swapchains[i];
- if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
- src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags)))
+ if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain,
+ src_rect, dst_rect, dst_window_override, 0, flags)))
{
wined3d_mutex_unlock();
return hr;
static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
{
- struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
-
TRACE("iface %p, max_latency %u.\n", iface, max_latency);
- if (max_latency > 30)
- return D3DERR_INVALIDCALL;
-
- wined3d_mutex_lock();
- wined3d_device_set_max_frame_latency(device->wined3d_device, max_latency);
- wined3d_mutex_unlock();
+ if (max_latency)
+ FIXME("Ignoring max_latency %u.\n", max_latency);
return S_OK;
}
static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency)
{
- struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
-
- TRACE("iface %p, max_latency %p.\n", iface, max_latency);
+ FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
- wined3d_mutex_lock();
- *max_latency = wined3d_device_get_max_frame_latency(device->wined3d_device);
- wined3d_mutex_unlock();
+ *max_latency = 2;
- return S_OK;
+ return E_NOTIMPL;
}
static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_NOT_RESET, D3D9_DEVICE_STATE_LOST);
}
-static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent,
- enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
void **parent, const struct wined3d_parent_ops **parent_ops)
{
- TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
- device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
+ struct d3d9_surface *d3d_surface;
- if (type == WINED3D_RTYPE_TEXTURE_2D)
- {
- struct d3d9_surface *d3d_surface;
+ TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
- if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
- return E_OUTOFMEMORY;
+ if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface))))
+ return E_OUTOFMEMORY;
- surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
- *parent = d3d_surface;
- TRACE("Created surface %p.\n", d3d_surface);
- }
- else if (type == WINED3D_RTYPE_TEXTURE_3D)
- {
- struct d3d9_volume *d3d_volume;
+ surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
+ *parent = d3d_surface;
+ TRACE("Created surface %p.\n", d3d_surface);
- if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
- return E_OUTOFMEMORY;
+ return D3D_OK;
+}
- volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
- *parent = d3d_volume;
- TRACE("Created volume %p.\n", d3d_volume);
- }
- else
- {
- ERR("Unhandled resource type %#x.\n", type);
- return E_FAIL;
- }
+static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+ void **parent, const struct wined3d_parent_ops **parent_ops)
+{
+ struct d3d9_volume *d3d_volume;
+
+ TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
+
+ if (!(d3d_volume = heap_alloc_zero(sizeof(*d3d_volume))))
+ return E_OUTOFMEMORY;
+
+ volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
+ *parent = d3d_volume;
+ TRACE("Created volume %p.\n", d3d_volume);
return D3D_OK;
}
TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain);
- if (FAILED(hr = d3d9_swapchain_create(device, desc, WINED3D_SWAP_INTERVAL_DEFAULT, &d3d_swapchain)))
+ hr = d3d9_swapchain_create(device, desc, &d3d_swapchain);
+ if (FAILED(hr))
{
WARN("Failed to create swapchain, hr %#x.\n", hr);
*swapchain = NULL;
device_parent_wined3d_device_created,
device_parent_mode_changed,
device_parent_activate,
- device_parent_texture_sub_resource_created,
+ device_parent_surface_created,
+ device_parent_volume_created,
device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
wined3d_mutex_unlock();
return E_OUTOFMEMORY;
}
- for (i = 0; i < device->implicit_swapchain_count; ++i)
- {
- device->implicit_swapchains[i]->swap_interval
- = wined3dswapinterval_from_d3d(parameters[i].PresentationInterval);
- }
for (i = 0; i < count; ++i)
{
- present_parameters_from_wined3d_swapchain_desc(¶meters[i],
- &swapchain_desc[i], parameters[i].PresentationInterval);
+ present_parameters_from_wined3d_swapchain_desc(¶meters[i], &swapchain_desc[i]);
}
wined3d_mutex_unlock();
TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n",
iface, adapter, device_type, adapter_format, usage, resource_type, format);
- if (!adapter_format)
- {
- WARN("Invalid adapter format.\n");
- return D3DERR_INVALIDCALL;
- }
-
usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK);
switch (resource_type)
{
DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
| WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR
| WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING
- | WINED3D_NORMALIZED_DEPTH_BIAS;
+ | WINED3D_NORMALIZED_DEPTH_BIAS | WINED3D_LIMIT_VIEWPORT;
if (!extended)
flags |= WINED3D_VIDMEM_ACCOUNTING;
WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
-static DWORD d3dpresentationinterval_from_wined3dswapinterval(enum wined3d_swap_interval interval)
-{
- switch (interval)
- {
- case WINED3D_SWAP_INTERVAL_IMMEDIATE:
- return D3DPRESENT_INTERVAL_IMMEDIATE;
- case WINED3D_SWAP_INTERVAL_ONE:
- return D3DPRESENT_INTERVAL_ONE;
- case WINED3D_SWAP_INTERVAL_TWO:
- return D3DPRESENT_INTERVAL_TWO;
- case WINED3D_SWAP_INTERVAL_THREE:
- return D3DPRESENT_INTERVAL_THREE;
- case WINED3D_SWAP_INTERVAL_FOUR:
- return D3DPRESENT_INTERVAL_FOUR;
- default:
- ERR("Invalid swap interval %#x.\n", interval);
- case WINED3D_SWAP_INTERVAL_DEFAULT:
- return D3DPRESENT_INTERVAL_DEFAULT;
- }
-}
-
static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9Ex(IDirect3DSwapChain9Ex *iface)
{
return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9Ex_iface);
wined3d_mutex_lock();
hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
- src_rect, dst_rect, dst_window_override, swapchain->swap_interval, flags);
+ src_rect, dst_rect, dst_window_override, 0, flags);
wined3d_mutex_unlock();
return hr;
{
struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
struct wined3d_swapchain_desc desc;
- DWORD presentation_interval;
TRACE("iface %p, parameters %p.\n", iface, parameters);
wined3d_mutex_lock();
wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &desc);
- presentation_interval = d3dpresentationinterval_from_wined3dswapinterval(swapchain->swap_interval);
wined3d_mutex_unlock();
- present_parameters_from_wined3d_swapchain_desc(parameters, &desc, presentation_interval);
+ present_parameters_from_wined3d_swapchain_desc(parameters, &desc);
return D3D_OK;
}
};
static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_device *device,
- struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
+ struct wined3d_swapchain_desc *desc)
{
HRESULT hr;
swapchain->refcount = 1;
swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl;
- swapchain->swap_interval = swap_interval;
wined3d_mutex_lock();
hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
}
HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc,
- unsigned int swap_interval, struct d3d9_swapchain **swapchain)
+ struct d3d9_swapchain **swapchain)
{
struct d3d9_swapchain *object;
HRESULT hr;
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- if (FAILED(hr = swapchain_init(object, device, desc, swap_interval)))
+ if (FAILED(hr = swapchain_init(object, device, desc)))
{
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
heap_free(object);
WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
return D3DERR_INVALIDCALL;
}
- wined3d_mutex_lock();
- hr = wined3d_check_device_format(device->d3d_parent->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM,
- WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_GENMIPMAP, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format));
- wined3d_mutex_unlock();
- if (hr == D3D_OK)
- {
- flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
- levels = 0;
- }
- else
- {
- WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture "
- "with a single level.\n", format);
- levels = 1;
- }
+ flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
texture->autogen_filter_type = D3DTEXF_LINEAR;
+ levels = 0;
}
else
{
-D__WINESRC__
-DDIRECT3D_VERSION=0x0900)
-if(MSVC)
- # error C4133: 'function': incompatible types - from 'D3D_CBUFFER_TYPE *' to 'DWORD *'
- replace_compile_flags("/we4133" " ")
-endif()
-
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
spec2def(d3dcompiler_43.dll d3dcompiler_43.spec ADD_IMPORTLIB)
list(APPEND SOURCE
asmparser.c
+ asmshader.tab.c
+ asmshader.yy.c
blob.c
bytecodewriter.c
compiler.c
+ hlsl.tab.c
+ hlsl.yy.c
main.c
reflection.c
utils.c
add_library(d3dcompiler_43 MODULE
${SOURCE}
- asmshader.tab.c
- asmshader.yy.c
- hlsl.tab.c
- hlsl.yy.c
version.rc
${CMAKE_CURRENT_BINARY_DIR}/d3dcompiler_43.def)
target_link_libraries(d3dcompiler_43 dx10guid uuid wine wpp)
add_importlibs(d3dcompiler_43 msvcrt kernel32 ntdll)
add_dependencies(d3dcompiler_43 d3d_idl_headers)
-add_pch(d3dcompiler_43 precomp.h SOURCE)
+#add_pch(d3dcompiler_43 precomp.h SOURCE)
add_cd_file(TARGET d3dcompiler_43 DESTINATION reactos/system32 FOR all)
set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/FIwine/typeof.h")
endif()
-add_library(ddraw MODULE
+add_library(ddraw SHARED
${SOURCE}
ddraw.rc
${CMAKE_CURRENT_BINARY_DIR}/ddraw.def)
swapchain_desc.backbuffer_width = mode.width;
swapchain_desc.backbuffer_height = mode.height;
swapchain_desc.backbuffer_format = mode.format_id;
- swapchain_desc.backbuffer_usage = 0;
- swapchain_desc.backbuffer_count = 1;
- swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
+ swapchain_desc.backbuffer_usage = WINED3DUSAGE_RENDERTARGET;
+ swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
swapchain_desc.device_window = window;
swapchain_desc.windowed = windowed;
swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
ddraw->flags |= DDRAW_GDI_FLIP;
if (ddraw->primary)
- ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE, 0);
+ ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE);
return DD_OK;
}
ddraw->device_state = DDRAW_DEVICE_STATE_OK;
}
-static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_device_parent *device_parent,
- enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
void **parent, const struct wined3d_parent_ops **parent_ops)
{
struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
struct ddraw_surface *ddraw_surface;
- TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
- device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
+ TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
/* We have a swapchain or wined3d internal texture. */
- if (type != WINED3D_RTYPE_TEXTURE_2D || !wined3d_texture_get_parent(wined3d_texture)
- || wined3d_texture_get_parent(wined3d_texture) == ddraw)
+ if (!wined3d_texture_get_parent(wined3d_texture) || wined3d_texture_get_parent(wined3d_texture) == ddraw)
{
*parent = NULL;
*parent_ops = &ddraw_null_wined3d_parent_ops;
return DD_OK;
}
+static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+ void **parent, const struct wined3d_parent_ops **parent_ops)
+{
+ TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
+
+ *parent = NULL;
+ *parent_ops = &ddraw_null_wined3d_parent_ops;
+
+ return DD_OK;
+}
+
static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent)
{
struct ddraw *ddraw = parent;
struct wined3d_texture **texture)
{
struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
- const struct wined3d_parent_ops *parent_ops;
HRESULT hr;
TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n",
device_parent, container_parent, desc, texture_flags, texture);
- if (!ddraw->wined3d_frontbuffer)
- parent_ops = &ddraw_frontbuffer_parent_ops;
- else
- parent_ops = &ddraw_null_wined3d_parent_ops;
+ if (ddraw->wined3d_frontbuffer)
+ {
+ ERR("Frontbuffer already created.\n");
+ return E_FAIL;
+ }
if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1,
- texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, parent_ops, texture)))
+ texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- if (!ddraw->wined3d_frontbuffer)
- ddraw->wined3d_frontbuffer = *texture;
+ ddraw->wined3d_frontbuffer = *texture;
return hr;
}
device_parent_wined3d_device_created,
device_parent_mode_changed,
device_parent_activate,
- device_parent_texture_sub_resource_created,
+ device_parent_surface_created,
+ device_parent_volume_created,
device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
#define DDRAW_NO3D 0x00000008
#define DDRAW_SCL_DDRAW1 0x00000010
#define DDRAW_SCL_RECURSIVE 0x00000020
-#define DDRAW_SWAPPED 0x00000040
-#define DDRAW_GDI_FLIP 0x00000080
+#define DDRAW_GDI_FLIP 0x00000040
#define DDRAW_STRIDE_ALIGNMENT 8
#define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
| WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
| WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \
- | WINED3D_LEGACY_CUBEMAP_FILTERING)
+ | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT)
enum ddraw_device_state
{
struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
- const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN;
+ const RECT *rect, BOOL read) DECLSPEC_HIDDEN;
static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface)
{
return hr;
}
+/*****************************************************************************
+ * IDirect3DDevice7::SetViewport
+ *
+ * Sets the current viewport.
+ *
+ * Version 7 only, but IDirect3DViewport uses this call for older
+ * versions
+ *
+ * Params:
+ * Data: The new viewport to set
+ *
+ * Returns:
+ * D3D_OK on success
+ * DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport)
{
struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
- struct wined3d_sub_resource_desc rt_desc;
- struct wined3d_rendertarget_view *rtv;
- struct ddraw_surface *surface;
struct wined3d_viewport vp;
TRACE("iface %p, viewport %p.\n", iface, viewport);
if (!viewport)
return DDERR_INVALIDPARAMS;
- wined3d_mutex_lock();
- if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
- {
- wined3d_mutex_unlock();
- return DDERR_INVALIDCAPS;
- }
- surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
- wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
-
- if (viewport->dwX > rt_desc.width || viewport->dwWidth > rt_desc.width - viewport->dwX
- || viewport->dwY > rt_desc.height || viewport->dwHeight > rt_desc.height - viewport->dwY)
- {
- WARN("Invalid viewport, returning E_INVALIDARG.\n");
- wined3d_mutex_unlock();
- return E_INVALIDARG;
- }
-
vp.x = viewport->dwX;
vp.y = viewport->dwY;
vp.width = viewport->dwWidth;
vp.min_z = viewport->dvMinZ;
vp.max_z = viewport->dvMaxZ;
- wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
+ wined3d_mutex_lock();
+ wined3d_device_set_viewport(device->wined3d_device, &vp);
wined3d_mutex_unlock();
return D3D_OK;
return hr;
}
+/*****************************************************************************
+ * IDirect3DDevice::GetViewport
+ *
+ * Returns the current viewport
+ *
+ * Version 7
+ *
+ * Params:
+ * Data: D3D7Viewport structure to write the viewport information to
+ *
+ * Returns:
+ * D3D_OK on success
+ * DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport)
{
struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
return DDERR_INVALIDPARAMS;
wined3d_mutex_lock();
- wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_viewport);
+ wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
wined3d_mutex_unlock();
viewport->dwX = wined3d_viewport.x;
wined3d_device_copy_sub_resource_region(device->wined3d_device,
wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0,
ci->wDest * sizeof(D3DTLVERTEX), 0, 0,
- wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box, 0);
+ wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, &box);
break;
default:
struct wined3d_map_desc map_desc;
struct wined3d_box box = {0};
HRESULT hr;
- DWORD buf_size = buffer->desc.dwBufferSize, copy_size;
TRACE("iface %p, data %p.\n", iface, data);
- if (data->dwSize != sizeof(*data))
- {
- WARN("data->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", data->dwSize);
- return DDERR_INVALIDPARAMS;
- }
-
/* Skip past previous vertex data. */
buffer->src_vertex_pos += buffer->data.dwVertexCount;
buffer->src_vertex_pos = 0;
}
- if (data->dwVertexCount && (!buf_size || data->dwVertexOffset < buf_size))
+ if (data->dwVertexCount)
{
box.left = buffer->src_vertex_pos * sizeof(D3DVERTEX);
box.right = box.left + data->dwVertexCount * sizeof(D3DVERTEX);
0, &map_desc, &box, WINED3D_MAP_WRITE)))
return hr;
- copy_size = data->dwVertexCount * sizeof(D3DVERTEX);
- if (buf_size)
- copy_size = min(copy_size, buf_size - data->dwVertexOffset);
-
- memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset, copy_size);
+ memcpy(map_desc.data, ((BYTE *)buffer->desc.lpData) + data->dwVertexOffset,
+ data->dwVertexCount * sizeof(D3DVERTEX));
wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0);
}
static HRESULT WINAPI d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data)
{
struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface);
+ DWORD dwSize;
TRACE("iface %p, data %p.\n", iface, data);
- /* Tests show that dwSize is ignored. */
- memcpy(data, &buffer->data, sizeof(*data));
+ dwSize = data->dwSize;
+ memcpy(data, &buffer->data, dwSize);
if (TRACE_ON(ddraw))
{
hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count, entries);
if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE)
- ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE, 0);
+ ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE);
wined3d_mutex_unlock();
* applications from drawing to the screen while we've locked the frontbuffer.
* We'd like to do this in wined3d instead, but for that to work wined3d needs
* to support windowless rendering first. */
-HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
- const RECT *rect, BOOL read, unsigned int swap_interval)
+HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read)
{
- struct wined3d_texture *dst_texture;
+ struct ddraw *ddraw = surface->ddraw;
HDC surface_dc, screen_dc;
int x, y, w, h;
HRESULT hr;
BOOL ret;
RECT r;
- if (surface->ddraw->flags & DDRAW_SWAPPED && !read)
- {
- surface->ddraw->flags &= ~DDRAW_SWAPPED;
- rect = NULL;
- }
-
if (!rect)
{
SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
if (w <= 0 || h <= 0)
return DD_OK;
- if (surface->ddraw->swapchain_window && !(surface->ddraw->flags & DDRAW_GDI_FLIP))
+ if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP))
{
/* Nothing to do, we control the frontbuffer, or at least the parts we
* care about. */
if (read)
return DD_OK;
- if (swap_interval)
- dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0);
- else
- dst_texture = surface->ddraw->wined3d_frontbuffer;
-
- if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture,
- surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval)
- {
- hr = wined3d_swapchain_present(surface->ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0);
- surface->ddraw->flags |= DDRAW_SWAPPED;
- }
- return hr;
+ return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
+ surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT);
}
if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
palette_impl ? palette_impl->wined3d_palette : NULL);
- ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
+ ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
}
if (palette_impl)
IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
}
if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0);
+ hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE);
if (SUCCEEDED(hr))
hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
wined3d_mutex_lock();
hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0);
+ hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE);
wined3d_mutex_unlock();
return hr;
return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL);
}
-static unsigned int ddraw_swap_interval_from_flags(DWORD flags)
-{
- if (flags & DDFLIP_NOVSYNC)
- return 0;
-
- switch (flags & (DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
- {
- case DDFLIP_INTERVAL2:
- return 2;
- case DDFLIP_INTERVAL3:
- return 3;
- case DDFLIP_INTERVAL4:
- return 4;
- default:
- return 1;
- }
-}
-
static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 *iface,
IDirectDrawSurface7 *src, DWORD flags)
{
wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture);
src_impl->wined3d_texture = texture;
- if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
+ if (flags)
{
static UINT once;
if (!once++)
}
if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE, ddraw_swap_interval_from_flags(flags));
+ hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE);
else
hr = DD_OK;
if (!dst_surface->clipper)
{
if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
+ hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE);
if (SUCCEEDED(hr))
hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter);
if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
- hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
+ hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE);
return hr;
}
if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
- if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE)))
break;
}
}
if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
- if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE)))
break;
}
}
if (surface->dc)
hr = DDERR_DCALREADYCREATED;
else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE);
if (SUCCEEDED(hr))
hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
{
surface->dc = NULL;
if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
}
wined3d_mutex_unlock();
}
if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0);
+ hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE);
if (SUCCEEDED(hr))
hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect,
src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT);
if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
- hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE);
wined3d_mutex_unlock();
switch(hr)
unsigned int wined3d_flags;
wined3d_flags = flags & handled;
- if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS | DDLOCK_WRITEONLY)))
+ if (!(flags & (DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS)))
wined3d_flags |= WINED3D_MAP_READ;
if (!(flags & DDLOCK_READONLY))
wined3d_flags |= WINED3D_MAP_WRITE;
wined3d_flags |= WINED3D_MAP_READ | WINED3D_MAP_WRITE;
if (flags & DDLOCK_NODIRTYUPDATE)
wined3d_flags |= WINED3D_MAP_NO_DIRTY_UPDATE;
- flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_WRITEONLY | DDLOCK_NODIRTYUPDATE);
+ flags &= ~(handled | DDLOCK_WAIT | DDLOCK_READONLY | DDLOCK_NODIRTYUPDATE);
if (flags)
FIXME("Unhandled flags %#x.\n", flags);
return DDERR_ALREADYINITIALIZED;
}
-static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::GetViewport
+ *
+ * Returns the viewport data assigned to this viewport interface
+ *
+ * Params:
+ * Data: Address to store the data
+ *
+ * Returns:
+ * D3D_OK on success
+ * DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData)
{
- struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
- DWORD size;
-
- TRACE("iface %p, vp %p.\n", iface, vp);
+ struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
+ DWORD dwSize;
- if (!vp)
- return DDERR_INVALIDPARAMS;
+ TRACE("iface %p, data %p.\n", iface, lpData);
wined3d_mutex_lock();
- size = vp->dwSize;
- if (!viewport->use_vp2)
- {
- memcpy(vp, &viewport->viewports.vp1, size);
- }
- else
- {
+ dwSize = lpData->dwSize;
+ if (!This->use_vp2)
+ memcpy(lpData, &(This->viewports.vp1), dwSize);
+ else {
D3DVIEWPORT vp1;
-
vp1.dwSize = sizeof(vp1);
- vp1.dwX = viewport->viewports.vp2.dwX;
- vp1.dwY = viewport->viewports.vp2.dwY;
- vp1.dwWidth = viewport->viewports.vp2.dwWidth;
- vp1.dwHeight = viewport->viewports.vp2.dwHeight;
+ vp1.dwX = This->viewports.vp2.dwX;
+ vp1.dwY = This->viewports.vp2.dwY;
+ vp1.dwWidth = This->viewports.vp2.dwWidth;
+ vp1.dwHeight = This->viewports.vp2.dwHeight;
vp1.dvMaxX = 0.0;
vp1.dvMaxY = 0.0;
vp1.dvScaleX = 0.0;
vp1.dvScaleY = 0.0;
- vp1.dvMinZ = viewport->viewports.vp2.dvMinZ;
- vp1.dvMaxZ = viewport->viewports.vp2.dvMaxZ;
- memcpy(vp, &vp1, size);
+ vp1.dvMinZ = This->viewports.vp2.dvMinZ;
+ vp1.dvMaxZ = This->viewports.vp2.dvMaxZ;
+ memcpy(lpData, &vp1, dwSize);
}
if (TRACE_ON(ddraw))
{
TRACE(" returning D3DVIEWPORT :\n");
- _dump_D3DVIEWPORT(vp);
+ _dump_D3DVIEWPORT(lpData);
}
wined3d_mutex_unlock();
- return D3D_OK;
+ return DD_OK;
}
-static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::SetViewport
+ *
+ * Sets the viewport information for this interface
+ *
+ * Params:
+ * lpData: Viewport to set
+ *
+ * Returns:
+ * D3D_OK on success
+ * DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData)
{
- struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
- struct d3d_device *device = viewport->active_device;
- struct wined3d_sub_resource_desc rt_desc;
- struct wined3d_rendertarget_view *rtv;
+ struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
IDirect3DViewport3 *current_viewport;
- struct ddraw_surface *surface;
- TRACE("iface %p, vp %p.\n", iface, vp);
-
- if (!vp)
- return DDERR_INVALIDPARAMS;
+ TRACE("iface %p, data %p.\n", iface, lpData);
if (TRACE_ON(ddraw))
{
TRACE(" getting D3DVIEWPORT :\n");
- _dump_D3DVIEWPORT(vp);
- }
-
- if (!device)
- {
- WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
- return D3DERR_VIEWPORTHASNODEVICE;
+ _dump_D3DVIEWPORT(lpData);
}
wined3d_mutex_lock();
- if (device->version > 1)
- {
- if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
- {
- wined3d_mutex_unlock();
- return DDERR_INVALIDCAPS;
- }
- surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
- wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
-
- if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
- || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
- {
- WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
- wined3d_mutex_unlock();
- return DDERR_INVALIDPARAMS;
- }
- }
-
- viewport->use_vp2 = 0;
- memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1));
- memcpy(&viewport->viewports.vp1, vp, vp->dwSize);
+ This->use_vp2 = 0;
+ memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
+ memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
- /* Empirical testing on a couple of d3d1 games showed that these values
- * should be ignored. */
- viewport->viewports.vp1.dvMinZ = 0.0;
- viewport->viewports.vp1.dvMaxZ = 1.0;
+ /* Tests on two games show that these values are never used properly so override
+ them with proper ones :-)
+ */
+ This->viewports.vp1.dvMinZ = 0.0;
+ This->viewports.vp1.dvMaxZ = 1.0;
- if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport)))
+ if (This->active_device)
{
- if (current_viewport == iface)
- viewport_activate(viewport, FALSE);
- IDirect3DViewport3_Release(current_viewport);
+ IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
+ if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, ¤t_viewport)))
+ {
+ if (current_viewport == iface) viewport_activate(This, FALSE);
+ IDirect3DViewport3_Release(current_viewport);
+ }
}
wined3d_mutex_unlock();
- return D3D_OK;
+ return DD_OK;
}
/*****************************************************************************
* IDirect3DViewport2 Methods.
*****************************************************************************/
-static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::GetViewport2
+ *
+ * Returns the currently set viewport in a D3DVIEWPORT2 structure.
+ * Similar to IDirect3DViewport3::GetViewport
+ *
+ * Params:
+ * lpData: Pointer to the structure to fill
+ *
+ * Returns:
+ * D3D_OK on success
+ * DDERR_INVALIDPARAMS if the viewport was set with
+ * IDirect3DViewport3::SetViewport
+ * DDERR_INVALIDPARAMS if Data is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_GetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData)
{
- struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
- DWORD size;
-
- TRACE("iface %p, vp %p.\n", iface, vp);
+ struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
+ DWORD dwSize;
- if (!vp)
- return DDERR_INVALIDPARAMS;
+ TRACE("iface %p, data %p.\n", iface, lpData);
wined3d_mutex_lock();
- size = vp->dwSize;
- if (viewport->use_vp2)
- {
- memcpy(vp, &viewport->viewports.vp2, size);
- }
- else
- {
+ dwSize = lpData->dwSize;
+ if (This->use_vp2)
+ memcpy(lpData, &(This->viewports.vp2), dwSize);
+ else {
D3DVIEWPORT2 vp2;
-
vp2.dwSize = sizeof(vp2);
- vp2.dwX = viewport->viewports.vp1.dwX;
- vp2.dwY = viewport->viewports.vp1.dwY;
- vp2.dwWidth = viewport->viewports.vp1.dwWidth;
- vp2.dwHeight = viewport->viewports.vp1.dwHeight;
+ vp2.dwX = This->viewports.vp1.dwX;
+ vp2.dwY = This->viewports.vp1.dwY;
+ vp2.dwWidth = This->viewports.vp1.dwWidth;
+ vp2.dwHeight = This->viewports.vp1.dwHeight;
vp2.dvClipX = 0.0;
vp2.dvClipY = 0.0;
vp2.dvClipWidth = 0.0;
vp2.dvClipHeight = 0.0;
- vp2.dvMinZ = viewport->viewports.vp1.dvMinZ;
- vp2.dvMaxZ = viewport->viewports.vp1.dvMaxZ;
- memcpy(vp, &vp2, size);
+ vp2.dvMinZ = This->viewports.vp1.dvMinZ;
+ vp2.dvMaxZ = This->viewports.vp1.dvMaxZ;
+ memcpy(lpData, &vp2, dwSize);
}
if (TRACE_ON(ddraw))
{
TRACE(" returning D3DVIEWPORT2 :\n");
- _dump_D3DVIEWPORT2(vp);
+ _dump_D3DVIEWPORT2(lpData);
}
wined3d_mutex_unlock();
return D3D_OK;
}
-static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *vp)
+/*****************************************************************************
+ * IDirect3DViewport3::SetViewport2
+ *
+ * Sets the viewport from a D3DVIEWPORT2 structure
+ *
+ * Params:
+ * lpData: Viewport to set
+ *
+ * Returns:
+ * D3D_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData)
{
- struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
- struct d3d_device *device = viewport->active_device;
- struct wined3d_sub_resource_desc rt_desc;
- struct wined3d_rendertarget_view *rtv;
+ struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface);
IDirect3DViewport3 *current_viewport;
- struct ddraw_surface *surface;
-
- TRACE("iface %p, vp %p.\n", iface, vp);
- if (!vp)
- return DDERR_INVALIDPARAMS;
+ TRACE("iface %p, data %p.\n", iface, lpData);
if (TRACE_ON(ddraw))
{
TRACE(" getting D3DVIEWPORT2 :\n");
- _dump_D3DVIEWPORT2(vp);
- }
-
- if (!device)
- {
- WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
- return D3DERR_VIEWPORTHASNODEVICE;
+ _dump_D3DVIEWPORT2(lpData);
}
wined3d_mutex_lock();
- if (device->version > 1)
- {
- if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
- {
- wined3d_mutex_unlock();
- return DDERR_INVALIDCAPS;
- }
- surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
- wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
+ This->use_vp2 = 1;
+ memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
+ memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
- if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
- || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
+ if (This->active_device)
+ {
+ IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
+ if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, ¤t_viewport)))
{
- WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
- wined3d_mutex_unlock();
- return DDERR_INVALIDPARAMS;
+ if (current_viewport == iface) viewport_activate(This, FALSE);
+ IDirect3DViewport3_Release(current_viewport);
}
}
- viewport->use_vp2 = 1;
- memset(&viewport->viewports.vp2, 0, sizeof(viewport->viewports.vp2));
- memcpy(&viewport->viewports.vp2, vp, vp->dwSize);
-
- if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport)))
- {
- if (current_viewport == iface)
- viewport_activate(viewport, FALSE);
- IDirect3DViewport3_Release(current_viewport);
- }
-
wined3d_mutex_unlock();
return D3D_OK;
include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
-if(MSVC)
- # error C4312: 'type cast': conversion from 'LONG' to 'void *' of greater size
- replace_compile_flags("/we4312" " ")
-endif()
-
# We name this d3dwine.dll, because the Virtualbox additions ship with a custom wined3d.dll
# and it breaks everything if it is installed.
spec2def(d3dwine.dll wined3d.spec ADD_IMPORTLIB)
wined3d_main.c
precomp.h)
-add_library(d3dwine MODULE
+add_library(d3dwine SHARED
${SOURCE}
version.rc
${CMAKE_CURRENT_BINARY_DIR}/d3dwine.def)
unsigned char i;
/* Upload the position fixup */
- shader_get_position_fixup(context, state, 1, position_fixup);
+ shader_get_position_fixup(context, state, position_fixup);
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, position_fixup));
if (!gl_shader->num_int_consts) return;
/* This is better than nothing for now */
sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
}
- else if(ctx->cur_ps_args->super.vp_mode != WINED3D_VP_MODE_SHADER)
+ else if(ctx->cur_ps_args->super.vp_mode != vertexshader)
{
/* This is problematic because we'd have to consult the ctx->ps_input strings
* for where to find the varying. Some may be "0.0", others can be texcoords or
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
const char *mod;
BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+ const struct wined3d_shader *shader;
+ const struct wined3d_device *device;
+ const struct wined3d_gl_info *gl_info;
const char *tex_dst = dst_str;
struct color_fixup_masks masks;
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
+ shader = ins->ctx->shader;
+ device = shader->device;
+ gl_info = &device->adapter->gl_info;
+
if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx)
- && ins->ctx->gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ && gl_info->supported[ARB_TEXTURE_RECTANGLE])
tex_type = "RECT";
else
tex_type = "2D";
const char *semantic_name;
DWORD semantic_idx;
- if (args->super.vp_mode == WINED3D_VP_MODE_SHADER)
- {
- /* That one is easy. The vertex shaders provide v0-v7 in
- * fragment.texcoord and v8 and v9 in fragment.color. */
- for (i = 0; i < 8; ++i)
- {
- priv->ps_input[i] = texcoords[i];
- }
- priv->ps_input[8] = "fragment.color.primary";
- priv->ps_input[9] = "fragment.color.secondary";
- return;
- }
+ switch(args->super.vp_mode)
+ {
+ case pretransformed:
+ case fixedfunction:
+ /* The pixelshader has to collect the varyings on its own. In any case properly load
+ * color0 and color1. In the case of pretransformed vertices also load texcoords. Set
+ * other attribs to 0.0.
+ *
+ * For fixedfunction this behavior is correct, according to the tests. For pretransformed
+ * we'd either need a replacement shader that can load other attribs like BINORMAL, or
+ * load the texcoord attrib pointers to match the pixel shader signature
+ */
+ for (i = 0; i < shader->input_signature.element_count; ++i)
+ {
+ input = &shader->input_signature.elements[i];
+ if (!(semantic_name = input->semantic_name))
+ continue;
+ semantic_idx = input->semantic_idx;
- /* The fragment shader has to collect the varyings on its own. In any case
- * properly load color0 and color1. In the case of pre-transformed
- * vertices also load texture coordinates. Set other attributes to 0.0.
- *
- * For fixed-function this behavior is correct, according to the tests.
- * For pre-transformed we'd either need a replacement shader that can load
- * other attributes like BINORMAL, or load the texture coordinate
- * attribute pointers to match the fragment shader signature. */
- for (i = 0; i < shader->input_signature.element_count; ++i)
- {
- input = &shader->input_signature.elements[i];
- if (!(semantic_name = input->semantic_name))
- continue;
- semantic_idx = input->semantic_idx;
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ {
+ if (!semantic_idx)
+ priv->ps_input[input->register_idx] = "fragment.color.primary";
+ else if (semantic_idx == 1)
+ priv->ps_input[input->register_idx] = "fragment.color.secondary";
+ else
+ priv->ps_input[input->register_idx] = "0.0";
+ }
+ else if (args->super.vp_mode == fixedfunction)
+ {
+ priv->ps_input[input->register_idx] = "0.0";
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ {
+ if (semantic_idx < 8)
+ priv->ps_input[input->register_idx] = texcoords[semantic_idx];
+ else
+ priv->ps_input[input->register_idx] = "0.0";
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ {
+ if (!semantic_idx)
+ priv->ps_input[input->register_idx] = "fragment.fogcoord";
+ else
+ priv->ps_input[input->register_idx] = "0.0";
+ }
+ else
+ {
+ priv->ps_input[input->register_idx] = "0.0";
+ }
- if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
- {
- if (!semantic_idx)
- priv->ps_input[input->register_idx] = "fragment.color.primary";
- else if (semantic_idx == 1)
- priv->ps_input[input->register_idx] = "fragment.color.secondary";
- else
- priv->ps_input[input->register_idx] = "0.0";
- }
- else if (args->super.vp_mode == WINED3D_VP_MODE_FF)
- {
- priv->ps_input[input->register_idx] = "0.0";
- }
- else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
- {
- if (semantic_idx < 8)
- priv->ps_input[input->register_idx] = texcoords[semantic_idx];
- else
- priv->ps_input[input->register_idx] = "0.0";
- }
- else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
- {
- if (!semantic_idx)
- priv->ps_input[input->register_idx] = "fragment.fogcoord";
- else
- priv->ps_input[input->register_idx] = "0.0";
- }
- else
- {
- priv->ps_input[input->register_idx] = "0.0";
- }
+ TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
+ semantic_name, semantic_idx, priv->ps_input[input->register_idx]);
+ }
+ break;
- TRACE("v%u, semantic %s%u is %s\n", input->register_idx,
- semantic_name, semantic_idx, priv->ps_input[input->register_idx]);
+ case vertexshader:
+ /* That one is easy. The vertex shaders provide v0-v7 in fragment.texcoord and v8 and v9 in
+ * fragment.color
+ */
+ for(i = 0; i < 8; i++)
+ {
+ priv->ps_input[i] = texcoords[i];
+ }
+ priv->ps_input[8] = "fragment.color.primary";
+ priv->ps_input[9] = "fragment.color.secondary";
+ break;
}
}
}
static void gen_ffp_instr(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color,
- BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+ BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
{
const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
unsigned int mul = 1;
- if (color && alpha)
- dstmask = "";
- else if (color)
- dstmask = ".xyz";
- else
- dstmask = ".w";
+ if(color && alpha) dstmask = "";
+ else if(color) dstmask = ".xyz";
+ else dstmask = ".w";
- dstreg = tmp_dst ? "tempreg" : "ret";
+ if(dst == tempreg) dstreg = "tempreg";
+ else dstreg = "ret";
arg0 = get_argreg(buffer, 0, stage, dw_arg0);
arg1 = get_argreg(buffer, 1, stage, dw_arg1);
if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE)
tex_read |= 1u << stage;
- if (settings->op[stage].tmp_dst)
+ if (settings->op[stage].dst == tempreg)
tempreg_used = TRUE;
if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
tempreg_used = TRUE;
textype = arbfp_texture_target(settings->op[stage].tex_type);
- if (settings->op[stage].projected == WINED3D_PROJECTION_NONE)
- {
+ if(settings->op[stage].projected == proj_none) {
instr = "TEX";
- }
- else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4
- || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
- {
+ } else if(settings->op[stage].projected == proj_count4 ||
+ settings->op[stage].projected == proj_count3) {
instr = "TXP";
- }
- else
- {
+ } else {
FIXME("Unexpected projection mode %d\n", settings->op[stage].projected);
instr = "TXP";
}
shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1);
shader_addline(&buffer, "DP3 ret.y, arg1, tex%u;\n", stage - 1);
- /* With projective textures, texbem only divides the static
- * texture coordinate, not the displacement, so multiply the
- * displacement with the dividing parameter before passing it to
- * TXP. */
- if (settings->op[stage].projected != WINED3D_PROJECTION_NONE)
- {
- if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4)
- {
+ /* with projective textures, texbem only divides the static texture coord, not the displacement,
+ * so multiply the displacement with the dividing parameter before passing it to TXP
+ */
+ if (settings->op[stage].projected != proj_none) {
+ if(settings->op[stage].projected == proj_count4) {
shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].w;\n", stage);
- shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n",
- stage, stage);
- }
- else
- {
+ shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", stage, stage);
+ } else {
shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].z;\n", stage);
- shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n",
- stage, stage);
+ shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", stage, stage);
}
- }
- else
- {
+ } else {
shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage);
}
stage - 1, stage - 1, stage - 1);
shader_addline(&buffer, "MUL tex%u, tex%u, ret.x;\n", stage, stage);
}
- }
- else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
- {
+ } else if(settings->op[stage].projected == proj_count3) {
shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage);
shader_addline(&buffer, "MOV ret.w, ret.z;\n");
shader_addline(&buffer, "%s tex%u, ret, texture[%u], %s;\n",
instr, stage, stage, textype);
- }
- else
- {
+ } else {
shader_addline(&buffer, "%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n",
instr, stage, stage, stage, textype);
}
if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
{
- gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+ gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
}
else if (op_equal)
{
- gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst,
+ gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
}
else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP
&& settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
{
- gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+ gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
- gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst,
+ gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].dst,
settings->op[stage].aop, settings->op[stage].aarg0,
settings->op[stage].aarg1, settings->op[stage].aarg2);
}
heap_free(arbfp_blitter);
}
-static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
- const struct arbfp_blit_type *type, char *luminance)
+static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
+ char *luminance)
{
char chroma;
const char *tex, *texinstr = "TXP";
shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n");
shader_addline(buffer, "ADD texcrd.x, texcrd.x, coef.y;\n");
- /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25
- * and 0.75 for the even and odd pixels respectively. */
+ /* Divide the x coordinate by 0.5 and get the fraction. This gives 0.25 and 0.75 for the
+ * even and odd pixels respectively
+ */
shader_addline(buffer, "MUL texcrd2, texcrd, coef.y;\n");
shader_addline(buffer, "FRC texcrd2, texcrd2;\n");
- /* Sample Pixel 1. */
+ /* Sample Pixel 1 */
shader_addline(buffer, "%s luminance, texcrd, texture[0], %s;\n", texinstr, tex);
/* Put the value into either of the chroma values */
/* This gives the correctly filtered luminance value */
shader_addline(buffer, "TEX luminance, fragment.texcoord[0], texture[0], %s;\n", tex);
+
+ return TRUE;
}
-static void gen_yv12_read(struct wined3d_string_buffer *buffer,
- const struct arbfp_blit_type *type, char *luminance)
+static BOOL gen_yv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
+ char *luminance)
{
const char *tex;
static const float yv12_coef[]
*/
if (type->res_type == WINED3D_GL_RES_TYPE_TEX_2D)
{
+
shader_addline(buffer, "RCP chroma.w, size.y;\n");
shader_addline(buffer, "MUL texcrd2.y, texcrd.y, size.y;\n");
shader_addline(buffer, "FLR texcrd2.y, texcrd2.y;\n");
shader_addline(buffer, "MAD texcrd.y, texcrd.y, yv12_coef.y, yv12_coef.x;\n");
- /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */
+ /* Read odd lines from the right side(add size * 0.5 to the x coordinate */
shader_addline(buffer, "ADD texcrd2.x, texcrd2.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */
shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n");
shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n");
}
else
{
- /* The y coordinate for V is in the range [size, size + size / 4). */
+ /* Read from [size - size+size/4] */
shader_addline(buffer, "FLR texcrd.y, texcrd.y;\n");
shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.w, size.y;\n");
- /* Read odd lines from the right side (add size * 0.5 to the x coordinate). */
+ /* Read odd lines from the right side(add size * 0.5 to the x coordinate */
shader_addline(buffer, "ADD texcrd2.x, texcrd.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */
shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n");
shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n");
shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
}
*luminance = 'a';
+
+ return TRUE;
}
-static void gen_nv12_read(struct wined3d_string_buffer *buffer,
- const struct arbfp_blit_type *type, char *luminance)
+static BOOL gen_nv12_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
+ char *luminance)
{
const char *tex;
static const float nv12_coef[]
}
else
{
- /* The y coordinate for chroma is in the range [size, size + size / 2). */
+ /* Read from [size - size+size/2] */
shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.y, size.y;\n");
shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n");
shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
}
*luminance = 'a';
+
+ return TRUE;
}
/* Context activation is done by the caller. */
{
case COMPLEX_FIXUP_UYVY:
case COMPLEX_FIXUP_YUY2:
- gen_packed_yuv_read(&buffer, type, &luminance_component);
+ if (!gen_planar_yuv_read(&buffer, type, &luminance_component))
+ {
+ string_buffer_free(&buffer);
+ return 0;
+ }
break;
case COMPLEX_FIXUP_YV12:
- gen_yv12_read(&buffer, type, &luminance_component);
+ if (!gen_yv12_read(&buffer, type, &luminance_component))
+ {
+ string_buffer_free(&buffer);
+ return 0;
+ }
break;
case COMPLEX_FIXUP_NV12:
- gen_nv12_read(&buffer, type, &luminance_component);
+ if (!gen_nv12_read(&buffer, type, &luminance_component))
+ {
+ string_buffer_free(&buffer);
+ return 0;
+ }
break;
default:
enum complex_fixup src_fixup;
BOOL decompress;
- if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
+ if (!context->gl_info->supported[ARB_FRAGMENT_PROGRAM])
return FALSE;
if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id)
}
static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
- struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
- DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture,
- unsigned int dst_sub_resource_idx, DWORD dst_location, const RECT *dst_rect,
+ struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location,
+ const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
{
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ struct wined3d_texture *src_texture = src_surface->container;
+ struct wined3d_texture *dst_texture = dst_surface->container;
struct wined3d_device *device = dst_texture->resource.device;
- struct wined3d_texture *staging_texture = NULL;
struct wined3d_arbfp_blitter *arbfp_blitter;
struct wined3d_color_key alpha_test_key;
struct wined3d_blitter *next;
- unsigned int src_level;
RECT s, d;
- TRACE("blitter %p, op %#x, context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_rect %s, "
- "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_rect %s, colour_key %p, filter %s.\n",
- blitter, op, context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location),
- wine_dbgstr_rect(src_rect), dst_texture, dst_sub_resource_idx, wined3d_debug_location(dst_location),
- wine_dbgstr_rect(dst_rect), color_key, debug_d3dtexturefiltertype(filter));
-
if (!arbfp_blit_supported(op, context, &src_texture->resource, src_location,
&dst_texture->resource, dst_location))
{
- if (!(next = blitter->next))
- {
- ERR("No blitter to handle blit op %#x.\n", op);
- return dst_location;
- }
-
- TRACE("Forwarding to blitter %p.\n", next);
- return next->ops->blitter_blit(next, op, context, src_texture, src_sub_resource_idx, src_location,
- src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect, color_key, filter);
+ if ((next = blitter->next))
+ return next->ops->blitter_blit(next, op, context, src_surface, src_location,
+ src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
}
arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
- if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
- {
- struct wined3d_resource_desc desc;
- struct wined3d_box upload_box;
- HRESULT hr;
-
- TRACE("Source texture is not GPU accessible, creating a staging texture.\n");
-
- src_level = src_sub_resource_idx % src_texture->level_count;
- desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
- desc.format = src_texture->resource.format->id;
- desc.multisample_type = src_texture->resource.multisample_type;
- desc.multisample_quality = src_texture->resource.multisample_quality;
- desc.usage = WINED3DUSAGE_PRIVATE;
- desc.access = WINED3D_RESOURCE_ACCESS_GPU;
- desc.width = wined3d_texture_get_level_width(src_texture, src_level);
- desc.height = wined3d_texture_get_level_height(src_texture, src_level);
- desc.depth = 1;
- desc.size = 0;
-
- if (FAILED(hr = wined3d_texture_create(device, &desc, 1, 1, 0,
- NULL, NULL, &wined3d_null_parent_ops, &staging_texture)))
- {
- ERR("Failed to create staging texture, hr %#x.\n", hr);
- return dst_location;
- }
-
- wined3d_box_set(&upload_box, 0, 0, desc.width, desc.height, 0, desc.depth);
- wined3d_texture_upload_from_texture(staging_texture, 0, 0, 0, 0,
- src_texture, src_sub_resource_idx, &upload_box);
-
- src_texture = staging_texture;
- src_sub_resource_idx = 0;
- }
- else if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
- && (src_texture->sub_resources[src_sub_resource_idx].locations
- & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) == WINED3D_LOCATION_DRAWABLE
+ /* Now load the surface */
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && (surface_get_sub_resource(src_surface)->locations
+ & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE))
+ == WINED3D_LOCATION_DRAWABLE
&& !wined3d_resource_is_offscreen(&src_texture->resource))
{
+ unsigned int src_level = src_sub_resource_idx % src_texture->level_count;
/* Without FBO blits transferring from the drawable to the texture is
* expensive, because we have to flip the data in sysmem. Since we can
* flip in the blitter, we don't actually need that flip anyway. So we
* use the surface's texture as scratch texture, and flip the source
* rectangle instead. */
- texture2d_load_fb_texture(src_texture, src_sub_resource_idx, FALSE, context);
+ surface_load_fb_texture(src_surface, FALSE, context);
s = *src_rect;
- src_level = src_sub_resource_idx % src_texture->level_count;
s.top = wined3d_texture_get_level_height(src_texture, src_level) - s.top;
s.bottom = wined3d_texture_get_level_height(src_texture, src_level) - s.bottom;
src_rect = &s;
}
else
- {
wined3d_texture_load(src_texture, context, FALSE);
- }
- context_apply_ffp_blit_state(context, device);
+ context_apply_blit_state(context, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE)
{
d = *dst_rect;
- wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d);
+ surface_translate_drawable_coords(dst_surface, context->win_handle, &d);
dst_rect = &d;
}
if (dst_location == WINED3D_LOCATION_DRAWABLE)
{
- TRACE("Destination texture %p is onscreen.\n", dst_texture);
+ TRACE("Destination surface %p is onscreen.\n", dst_surface);
buffer = wined3d_texture_get_gl_buffer(dst_texture);
}
else
{
- TRACE("Destination texture %p is offscreen.\n", dst_texture);
+ TRACE("Destination surface %p is offscreen.\n", dst_surface);
buffer = GL_COLOR_ATTACHMENT0;
}
- context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER,
- &dst_texture->resource, dst_sub_resource_idx, NULL, 0, dst_location);
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location);
context_set_draw_buffer(context, buffer);
context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
context_invalidate_state(context, STATE_FRAMEBUFFER);
arbfp_blit_set(arbfp_blitter, context, src_texture, src_sub_resource_idx, color_key);
/* Draw a textured quad */
- context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter);
+ draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter);
/* Leave the opengl state valid for blitting */
arbfp_blit_unset(context->gl_info);
- if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))
- context->gl_info->gl_ops.gl.p_glFlush();
-
- if (staging_texture)
- wined3d_texture_decref(staging_texture);
+ if (wined3d_settings.strict_draw_ordering
+ || (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture)))
+ context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
return dst_location;
}
lowest_read = i;
}
- if (lowest_write == -1 && op[i].tmp_dst)
+ if(lowest_write == -1 && op[i].dst == tempreg) {
lowest_write = i;
+ }
if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, GL_SWIZZLE_STR_ATI)\n",
stage, stage);
- GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage, GL_TEXTURE0_ARB + stage, GL_SWIZZLE_STR_ATI));
- if (op[stage + 1].projected == WINED3D_PROJECTION_NONE)
+ GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage,
+ GL_TEXTURE0_ARB + stage,
+ GL_SWIZZLE_STR_ATI));
+ if(op[stage + 1].projected == proj_none) {
swizzle = GL_SWIZZLE_STR_ATI;
- else if (op[stage + 1].projected == WINED3D_PROJECTION_COUNT4)
+ } else if(op[stage + 1].projected == proj_count4) {
swizzle = GL_SWIZZLE_STQ_DQ_ATI;
- else
+ } else {
swizzle = GL_SWIZZLE_STR_DR_ATI;
+ }
TRACE("glPassTexCoordATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, %s)\n",
stage + 1, stage + 1, debug_swizzle(swizzle));
GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1,
if (op[stage].cop == WINED3D_TOP_DISABLE)
break;
- if (op[stage].projected == WINED3D_PROJECTION_NONE)
+ if(op[stage].projected == proj_none) {
swizzle = GL_SWIZZLE_STR_ATI;
- else if (op[stage].projected == WINED3D_PROJECTION_COUNT3)
+ } else if(op[stage].projected == proj_count3) {
swizzle = GL_SWIZZLE_STR_DR_ATI;
- else
+ } else {
swizzle = GL_SWIZZLE_STQ_DQ_ATI;
+ }
if (op_reads_texture(&op[stage]))
{
break;
}
- if (op[stage].tmp_dst)
- {
- /* If we're writing to D3DTA_TEMP, but never reading from it we
- * don't have to write there in the first place. Skip the entire
- * stage, this saves some GPU time. */
- if (tmparg == GL_NONE)
- continue;
+ if(op[stage].dst == tempreg) {
+ /* If we're writing to D3DTA_TEMP, but never reading from it we don't have to write there in the first place.
+ * skip the entire stage, this saves some GPU time
+ */
+ if(tmparg == GL_NONE) continue;
dstreg = tmparg;
- }
- else
- {
+ } else {
dstreg = GL_REG_0_ATI;
}
return TRUE;
if (!wined3d_resource_allocate_sysmem(&buffer->resource))
+ {
+ ERR("Failed to allocate system memory.\n");
return FALSE;
+ }
return TRUE;
case WINED3D_LOCATION_BUFFER:
}
GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint));
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
buffer_clear_dirty_areas(buffer);
buffer->bind_flags = bind_flags;
buffer->locations = WINED3D_LOCATION_SYSMEM;
- if (!wined3d_resource_allocate_sysmem(&buffer->resource))
- return E_OUTOFMEMORY;
-
TRACE("buffer %p, size %#x, usage %#x, format %s, memory @ %p.\n",
buffer, buffer->resource.size, buffer->resource.usage,
debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory);
if (data)
wined3d_device_update_sub_resource(device, &buffer->resource,
- 0, NULL, data->data, data->row_pitch, data->slice_pitch, 0);
+ 0, NULL, data->data, data->row_pitch, data->slice_pitch);
return WINED3D_OK;
}
gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
resource->object, resource->level);
}
- else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY
- || resource->target == GL_TEXTURE_3D)
+ else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY ||
+ resource->target == GL_TEXTURE_3D)
{
if (!gl_info->fbo_ops.glFramebufferTextureLayer)
{
{
gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment,
resource->target, resource->object, resource->level);
+ checkGLcall("glFramebufferTexture1D()");
}
else
{
}
texture_type[] =
{
- {GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, "1d", WINED3D_GL_EXT_NONE},
- {GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BINDING_1D_ARRAY, "1d-array", EXT_TEXTURE_ARRAY},
{GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2d", WINED3D_GL_EXT_NONE},
{GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BINDING_RECTANGLE_ARB, "rectangle", ARB_TEXTURE_RECTANGLE},
{GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2d-array" , EXT_TEXTURE_ARRAY},
}
texture = wined3d_texture_from_resource(resource);
- if (texture->current_renderbuffer)
+ if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
{
- key->objects[idx].object = texture->current_renderbuffer->id;
- key->objects[idx].target = 0;
- key->objects[idx].level = key->objects[idx].layer = 0;
- key->rb_namespace |= 1 << idx;
- return;
- }
+ struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
+ if (surface->current_renderbuffer)
+ {
+ key->objects[idx].object = surface->current_renderbuffer->id;
+ key->objects[idx].target = 0;
+ key->objects[idx].level = key->objects[idx].layer = 0;
+ key->rb_namespace |= 1 << idx;
+ return;
+ }
+ }
key->objects[idx].target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
key->objects[idx].level = sub_resource_idx % texture->level_count;
key->objects[idx].layer = sub_resource_idx / texture->level_count;
}
else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D)
{
- wined3d_texture_set_compatible_renderbuffer(ds_texture, ds_level, &render_targets[0]);
+ struct wined3d_surface *surface;
+
+ surface = ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface;
+ surface_set_compatible_renderbuffer(surface, &render_targets[0]);
}
}
/* Context activation is done by the caller. */
static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
- const struct wined3d_rendertarget_info *render_targets,
- const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location, DWORD ds_location)
+ struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+ DWORD color_location, DWORD ds_location)
{
struct fbo_entry *entry, *entry2;
}
else
{
+ struct wined3d_rendertarget_info ds = {{0}};
+
+ if (depth_stencil)
+ {
+ ds.resource = &depth_stencil->container->resource;
+ ds.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil);
+ ds.layer_count = 1;
+ }
context->current_fbo = context_find_fbo_entry(context, target,
- render_targets, depth_stencil, color_location, ds_location);
+ render_targets, &ds, color_location, ds_location);
context_apply_fbo_entry(context, target, context->current_fbo);
}
}
/* Context activation is done by the caller. */
void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
- struct wined3d_resource *rt, unsigned int rt_sub_resource_idx,
- struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location)
+ struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
{
- struct wined3d_rendertarget_info ds_info = {{0}};
-
memset(context->blit_targets, 0, sizeof(context->blit_targets));
- if (rt)
+ if (render_target)
{
- context->blit_targets[0].resource = rt;
- context->blit_targets[0].sub_resource_idx = rt_sub_resource_idx;
+ context->blit_targets[0].resource = &render_target->container->resource;
+ context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target);
context->blit_targets[0].layer_count = 1;
}
-
- if (ds)
- {
- ds_info.resource = ds;
- ds_info.sub_resource_idx = ds_sub_resource_idx;
- ds_info.layer_count = 1;
- }
-
- context_apply_fbo_state(context, target, context->blit_targets, &ds_info, location, location);
+ context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location);
}
/* Context activation is done by the caller. */
list_add_head(&context->fbo_destroy_list, &entry->entry);
}
-void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource)
+void context_resource_released(const struct wined3d_device *device,
+ struct wined3d_resource *resource, enum wined3d_resource_type type)
{
- unsigned int i;
+ struct wined3d_texture *texture;
+ UINT i;
if (!device->d3d_initialized)
return;
- for (i = 0; i < device->context_count; ++i)
+ switch (type)
{
- struct wined3d_context *context = device->contexts[i];
+ case WINED3D_RTYPE_TEXTURE_2D:
+ case WINED3D_RTYPE_TEXTURE_3D:
+ texture = texture_from_resource(resource);
- if (&context->current_rt.texture->resource == resource)
- {
- context->current_rt.texture = NULL;
- context->current_rt.sub_resource_idx = 0;
- }
+ for (i = 0; i < device->context_count; ++i)
+ {
+ struct wined3d_context *context = device->contexts[i];
+ if (context->current_rt.texture == texture)
+ {
+ context->current_rt.texture = NULL;
+ context->current_rt.sub_resource_idx = 0;
+ }
+ }
+ break;
+
+ default:
+ break;
}
}
context_enum_fbo_entries(device, name, rb_namespace, context_queue_fbo_entry_destruction);
}
-void context_texture_update(struct wined3d_context *context, const struct wined3d_texture *texture)
+void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry = context->current_fbo;
for (i = 0; i < gl_info->limits.buffers + 1; ++i)
{
- if (texture->texture_rgb.name == entry->key.objects[i].object
- || texture->texture_srgb.name == entry->key.objects[i].object)
+ if (surface->container->texture_rgb.name == entry->key.objects[i].object
+ || surface->container->texture_srgb.name == entry->key.objects[i].object)
{
- TRACE("Updated texture %p is bound as attachment %u to the current FBO.\n", texture, i);
+ TRACE("Updated surface %p is bound as attachment %u to the current FBO.\n", surface, i);
context->rebind_fbo = TRUE;
return;
}
}
}
- if (context->blit_vbo)
- GL_EXTCALL(glDeleteBuffers(1, &context->blit_vbo));
-
checkGLcall("context cleanup");
}
/* This is used when a context for render target A is active, but a separate context is
* needed to access the WGL framebuffer for render target B. Re-acquire a context for rt
* A to avoid breaking caller code. */
-void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, unsigned int sub_resource_idx)
+void context_restore(struct wined3d_context *context, struct wined3d_surface *restore)
{
- if (context->current_rt.texture != texture || context->current_rt.sub_resource_idx != sub_resource_idx)
+ if (context->current_rt.texture != restore->container
+ || context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore))
{
context_release(context);
- context = context_acquire(texture->resource.device, texture, sub_resource_idx);
+ context = context_acquire(restore->container->resource.device,
+ restore->container, surface_get_sub_resource_idx(restore));
}
context_release(context);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
}
-
if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version >> 16;
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_MINOR_VERSION_ARB;
ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version & 0xffff;
+ if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2))
+ ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctx_flags)
{
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
{
- if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2))
+ if (ctx_flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
{
- if (ctx_flags)
- {
- ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
- ctx_attribs[ctx_attrib_idx - 1] = ctx_flags;
- }
- else
- {
- ctx_flags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
- ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
- ctx_attribs[ctx_attrib_idx++] = ctx_flags;
- ctx_attribs[ctx_attrib_idx] = 0;
- }
+ ctx_attribs[ctx_attrib_idx - 1] &= ~WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
WARN("Failed to create a WGL context with wglCreateContextAttribsARB, last error %#x.\n",
GetLastError());
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, 1);");
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ /* Direct3D always uses n-1 weights for n world matrices and uses
+ * 1 - sum for the last one this is equal to GL_WEIGHT_SUM_UNITY_ARB.
+ * Enabling it doesn't do anything unless GL_VERTEX_BLEND_ARB isn't
+ * enabled as well. */
+ gl_info->gl_ops.gl.p_glEnable(GL_WEIGHT_SUM_UNITY_ARB);
+ checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
+ }
if (gl_info->supported[NV_TEXTURE_SHADER2])
{
/* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
if (device->dummy_textures.tex_2d)
context_bind_dummy_textures(device, ret);
- /* Initialise all rectangles to avoid resetting unused ones later. */
- gl_info->gl_ops.gl.p_glScissor(0, 0, 0, 0);
- checkGLcall("glScissor");
-
TRACE("Created context %p.\n", ret);
return ret;
return context->tex_unit_map;
}
+/* Context activation is done by the caller. */
+static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height)
+{
+ const GLdouble projection[] =
+ {
+ 2.0 / width, 0.0, 0.0, 0.0,
+ 0.0, 2.0 / height, 0.0, 0.0,
+ 0.0, 0.0, 2.0, 0.0,
+ -1.0, -1.0, -1.0, 1.0,
+ };
+
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ {
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode(GL_PROJECTION)");
+ gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
+ checkGLcall("glLoadMatrixd");
+ }
+ gl_info->gl_ops.gl.p_glViewport(0, 0, width, height);
+ checkGLcall("glViewport");
+}
+
static void context_get_rt_size(const struct wined3d_context *context, SIZE *size)
{
const struct wined3d_texture *rt = context->current_rt.texture;
checkGLcall("toggle clip distances");
}
+/*****************************************************************************
+ * SetupForBlit
+ *
+ * Sets up a context for DirectDraw blitting.
+ * All texture units are disabled, texture unit 0 is set as current unit
+ * fog, lighting, blending, alpha test, z test, scissor test, culling disabled
+ * color writing enabled for all channels
+ * register combiners disabled, shaders disabled
+ * world matrix is set to identity, texture matrix 0 too
+ * projection matrix is setup for drawing screen coordinates
+ *
+ * Params:
+ * This: Device to activate the context for
+ * context: Context to setup
+ *
+ *****************************************************************************/
+/* Context activation is done by the caller. */
+static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD sampler;
+ SIZE rt_size;
+ int i;
+
+ TRACE("Setting up context %p for blitting\n", context);
+
+ context_get_rt_size(context, &rt_size);
+
+ if (context->last_was_blit)
+ {
+ if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
+ {
+ set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
+ context->blit_w = rt_size.cx;
+ context->blit_h = rt_size.cy;
+ /* No need to dirtify here, the states are still dirtified because
+ * they weren't applied since the last SetupForBlit() call. */
+ }
+ TRACE("Context is already set up for blitting, nothing to do\n");
+ return;
+ }
+ context->last_was_blit = TRUE;
+
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ {
+ /* Disable all textures. The caller can then bind a texture it wants to blit
+ * from
+ *
+ * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
+ * function texture unit. No need to care for higher samplers
+ */
+ for (i = gl_info->limits.textures - 1; i > 0 ; --i)
+ {
+ sampler = context->rev_tex_unit_map[i];
+ context_active_texture(context, gl_info, i);
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable GL_TEXTURE_3D");
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable GL_TEXTURE_2D");
+
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
+
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ {
+ if (sampler < MAX_TEXTURES)
+ context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+ context_invalidate_state(context, STATE_SAMPLER(sampler));
+ }
+ }
+
+ context_active_texture(context, gl_info, 0);
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable GL_TEXTURE_3D");
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable GL_TEXTURE_2D");
+
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
+ checkGLcall("glMatrixMode(GL_TEXTURE)");
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+
+ if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+ GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
+ checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ...");
+ }
+
+ /* Setup transforms */
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode(GL_MODELVIEW)");
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+
+ /* Other misc states */
+ gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ checkGLcall("glDisable GL_LIGHTING");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
+ glDisableWINE(GL_FOG);
+ checkGLcall("glDisable GL_FOG");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
+ }
+
+ if (gl_info->supported[ARB_SAMPLER_OBJECTS])
+ GL_EXTCALL(glBindSampler(0, 0));
+ context_active_texture(context, gl_info, 0);
+
+ sampler = context->rev_tex_unit_map[0];
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ {
+ if (sampler < MAX_TEXTURES)
+ {
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
+ context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+ }
+ context_invalidate_state(context, STATE_SAMPLER(sampler));
+ }
+
+ /* Other misc states */
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+ checkGLcall("glDisable GL_DEPTH_TEST");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ checkGLcall("glDisable GL_BLEND");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+ checkGLcall("glDisable GL_CULL_FACE");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+ checkGLcall("glDisable GL_STENCIL_TEST");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ checkGLcall("glDisable GL_SCISSOR_TEST");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+ if (gl_info->supported[ARB_POINT_SPRITE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
+ checkGLcall("glDisable GL_POINT_SPRITE_ARB");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
+ }
+ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
+ checkGLcall("glColorMask");
+ for (i = 0; i < MAX_RENDER_TARGETS; ++i)
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
+ checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
+ }
+
+ context->last_was_rhw = TRUE;
+ context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
+
+ context_enable_clip_distances(context, 0);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
+
+ /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
+ if (gl_info->supported[ARB_CLIP_CONTROL])
+ GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE));
+
+ set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
+
+ /* Disable shaders */
+ device->shader_backend->shader_disable(device->shader_priv, context);
+
+ context->blit_w = rt_size.cx;
+ context->blit_h = rt_size.cy;
+ context_invalidate_state(context, STATE_VIEWPORT);
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+}
+
static inline BOOL is_rt_mask_onscreen(DWORD rt_mask)
{
return rt_mask & (1u << 31);
break;
case GL_TEXTURE_1D:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+ checkGLcall("glBindTexture");
break;
case GL_TEXTURE_1D_ARRAY:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+ checkGLcall("glBindTexture");
break;
case GL_TEXTURE_2D:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
context_invalidate_state(context, STATE_SCISSORRECT);
if (!context->gl_info->supported[ARB_CLIP_CONTROL])
{
- context_invalidate_state(context, STATE_RASTERIZER);
+ context_invalidate_state(context, STATE_FRONTFACE);
context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN);
context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
}
}
}
-static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_resource *rt)
+static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, struct wined3d_texture *rt)
{
- if (!rt || rt->format->id == WINED3DFMT_NULL)
+ if (!rt || rt->resource.format->id == WINED3DFMT_NULL)
return 0;
- else if (rt->type != WINED3D_RTYPE_BUFFER && texture_from_resource(rt)->swapchain)
- return context_generate_rt_mask_from_resource(rt);
+ else if (rt->swapchain)
+ return context_generate_rt_mask_from_resource(&rt->resource);
else
return context_generate_rt_mask(context_get_offscreen_gl_buffer(context));
}
/* Context activation is done by the caller. */
void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
{
- const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_texture *rt = context->current_rt.texture;
+ struct wined3d_surface *surface;
DWORD rt_mask, *cur_mask;
- unsigned int i, sampler;
- SIZE rt_size;
-
- TRACE("Setting up context %p for blitting.\n", context);
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
{
wined3d_texture_load(rt, context, FALSE);
- context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, &rt->resource,
- context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding);
+ surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface;
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding);
if (rt->resource.format->id != WINED3DFMT_NULL)
rt_mask = 1;
else
}
else
{
- rt_mask = context_generate_rt_mask_no_fbo(context, &rt->resource);
+ rt_mask = context_generate_rt_mask_no_fbo(context, rt);
}
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
{
context_check_fbo_status(context, GL_FRAMEBUFFER);
}
+
+ SetupForBlit(device, context);
context_invalidate_state(context, STATE_FRAMEBUFFER);
+}
- context_get_rt_size(context, &rt_size);
+static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts,
+ const struct wined3d_rendertarget_view *ds)
+{
+ unsigned int i;
- if (context->last_was_blit)
+ if (ds)
+ return TRUE;
+
+ for (i = 0; i < rt_count; ++i)
{
- if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
- {
- gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy);
- context->viewport_count = WINED3D_MAX_VIEWPORTS;
- context->blit_w = rt_size.cx;
- context->blit_h = rt_size.cy;
- /* No need to dirtify here, the states are still dirtified because
- * they weren't applied since the last context_apply_blit_state()
- * call. */
- }
- checkGLcall("blit state application");
- TRACE("Context is already set up for blitting, nothing to do.\n");
- return;
+ if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
+ return TRUE;
}
- context->last_was_blit = TRUE;
- if (gl_info->supported[ARB_SAMPLER_OBJECTS])
- GL_EXTCALL(glBindSampler(0, 0));
- context_active_texture(context, gl_info, 0);
+ return FALSE;
+}
- sampler = context->rev_tex_unit_map[0];
- if (sampler != WINED3D_UNMAPPED_STAGE)
+/* Context activation is done by the caller. */
+BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
+ UINT rt_count, const struct wined3d_fb_state *fb)
+{
+ struct wined3d_rendertarget_view * const *rts = fb->render_targets;
+ struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD rt_mask = 0, *cur_mask;
+ unsigned int i;
+
+ if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
+ || rt_count != gl_info->limits.buffers)
{
- if (sampler < MAX_TEXTURES)
+ if (!have_framebuffer_attachment(rt_count, rts, dsv))
{
- context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
- context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
- }
- context_invalidate_state(context, STATE_SAMPLER(sampler));
- }
-
- if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
- {
- gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
- }
- gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
- gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
- gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
- gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
- gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
- if (gl_info->supported[ARB_POINT_SPRITE])
- {
- gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
- }
- if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
- {
- gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
- }
- gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- for (i = 0; i < MAX_RENDER_TARGETS; ++i)
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
-
- context->last_was_rhw = TRUE;
- context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
-
- context_enable_clip_distances(context, 0);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
-
- /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
- if (gl_info->supported[ARB_CLIP_CONTROL])
- GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE));
- gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy);
- context->viewport_count = WINED3D_MAX_VIEWPORTS;
- context_invalidate_state(context, STATE_VIEWPORT);
-
- device->shader_backend->shader_disable(device->shader_priv, context);
-
- context->blit_w = rt_size.cx;
- context->blit_h = rt_size.cy;
-
- checkGLcall("blit state application");
-}
-
-static void context_apply_blit_projection(const struct wined3d_context *context, unsigned int w, unsigned int h)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- const GLdouble projection[] =
- {
- 2.0 / w, 0.0, 0.0, 0.0,
- 0.0, 2.0 / h, 0.0, 0.0,
- 0.0, 0.0, 2.0, 0.0,
- -1.0, -1.0, -1.0, 1.0,
- };
-
- gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
- gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
-}
-
-/* Setup OpenGL states for fixed-function blitting. */
-/* Context activation is done by the caller. */
-void context_apply_ffp_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- unsigned int i, sampler;
-
- if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
- ERR("Applying fixed-function state without legacy context support.\n");
-
- if (context->last_was_ffp_blit)
- {
- SIZE rt_size;
-
- context_get_rt_size(context, &rt_size);
- if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
- context_apply_blit_projection(context, rt_size.cx, rt_size.cy);
- context_apply_blit_state(context, device);
-
- checkGLcall("ffp blit state application");
- return;
- }
- context->last_was_ffp_blit = TRUE;
-
- context_apply_blit_state(context, device);
-
- /* Disable all textures. The caller can then bind a texture it wants to blit
- * from. */
- for (i = gl_info->limits.textures - 1; i > 0 ; --i)
- {
- context_active_texture(context, gl_info, i);
-
- if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
- if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-
- gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- sampler = context->rev_tex_unit_map[i];
- if (sampler != WINED3D_UNMAPPED_STAGE)
- {
- if (sampler < MAX_TEXTURES)
- context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
- context_invalidate_state(context, STATE_SAMPLER(sampler));
- }
- }
-
- context_active_texture(context, gl_info, 0);
-
- if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
- if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
- gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-
- gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
- gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
-
- gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
- gl_info->gl_ops.gl.p_glLoadIdentity();
-
- /* Setup transforms. */
- gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
- gl_info->gl_ops.gl.p_glLoadIdentity();
- context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
- context_apply_blit_projection(context, context->blit_w, context->blit_h);
- context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
-
- /* Other misc states. */
- gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
- glDisableWINE(GL_FOG);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
-
- if (gl_info->supported[EXT_SECONDARY_COLOR])
- {
- gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
- context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
- }
- checkGLcall("ffp blit state application");
-}
-
-static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts,
- const struct wined3d_rendertarget_view *ds)
-{
- unsigned int i;
-
- if (ds)
- return TRUE;
-
- for (i = 0; i < rt_count; ++i)
- {
- if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Context activation is done by the caller. */
-BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
- UINT rt_count, const struct wined3d_fb_state *fb)
-{
- struct wined3d_rendertarget_view * const *rts = fb->render_targets;
- struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
- const struct wined3d_gl_info *gl_info = context->gl_info;
- DWORD rt_mask = 0, *cur_mask;
- unsigned int i;
-
- if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
- || rt_count != gl_info->limits.buffers)
- {
- if (!have_framebuffer_attachment(rt_count, rts, dsv))
- {
- WARN("Invalid render target config, need at least one attachment.\n");
- return FALSE;
+ WARN("Invalid render target config, need at least one attachment.\n");
+ return FALSE;
}
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
- struct wined3d_rendertarget_info ds_info = {{0}};
-
context_validate_onscreen_formats(context, dsv);
if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
rt_mask |= (1u << i);
}
-
- if (dsv)
- {
- ds_info.gl_view = dsv->gl_view;
- ds_info.resource = dsv->resource;
- ds_info.sub_resource_idx = dsv->sub_resource_idx;
- ds_info.layer_count = dsv->layer_count;
- }
-
- context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, &ds_info,
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
+ wined3d_rendertarget_view_get_surface(dsv),
rt_count ? rts[0]->resource->draw_binding : 0,
dsv ? dsv->resource->draw_binding : 0);
}
else
{
- context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info,
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL,
WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
rt_mask = context_generate_rt_mask_from_resource(rts[0]->resource);
}
}
else
{
- rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource : NULL);
+ rt_mask = context_generate_rt_mask_no_fbo(context,
+ rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL);
}
}
else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
}
else
{
- rt_mask = context_generate_rt_mask_no_fbo(context, rt_count ? rts[0]->resource : NULL);
+ rt_mask = context_generate_rt_mask_no_fbo(context,
+ rt_count ? wined3d_rendertarget_view_get_surface(rts[0])->container : NULL);
}
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
}
context->last_was_blit = FALSE;
- context->last_was_ffp_blit = FALSE;
/* Blending and clearing should be orthogonal, but tests on the nvidia
* driver show that disabling blending when clearing improves the clearing
unsigned int i;
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
- return context_generate_rt_mask_no_fbo(context, rts[0]->resource);
+ return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])->container);
else if (!context->render_offscreen)
return context_generate_rt_mask_from_resource(rts[0]->resource);
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
- struct wined3d_rendertarget_info ds_info = {{0}};
-
if (!context->render_offscreen)
{
- context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, &ds_info,
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL,
WINED3D_LOCATION_DRAWABLE, WINED3D_LOCATION_DRAWABLE);
}
else
if (!color_location)
color_location = fb->render_targets[i]->resource->draw_binding;
}
-
- if (fb->depth_stencil)
- {
- ds_info.gl_view = fb->depth_stencil->gl_view;
- ds_info.resource = fb->depth_stencil->resource;
- ds_info.sub_resource_idx = fb->depth_stencil->sub_resource_idx;
- ds_info.layer_count = fb->depth_stencil->layer_count;
- }
-
- context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, &ds_info,
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
+ wined3d_rendertarget_view_get_surface(fb->depth_stencil),
color_location, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0);
}
}
context->numDirtyEntries = 0; /* This makes the whole list clean */
context->last_was_blit = FALSE;
- context->last_was_ffp_blit = FALSE;
return TRUE;
}
context_invalidate_state(context, STATE_FRAMEBUFFER);
context->last_was_blit = FALSE;
- context->last_was_ffp_blit = FALSE;
}
static BOOL use_transform_feedback(const struct wined3d_state *state)
GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
checkGLcall("glMemoryBarrier");
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
context_release(context);
}
case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3];
case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2];
case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1];
- case WINED3D_FFP_EMIT_FLOAT1: vector[0] = data[0]; break;
default:
FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx));
return (BYTE *)data;
WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
emulation = TRUE;
}
- else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device))
+ else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device))
{
WARN_(d3d_perf)("Using software emulation because application requested SVP.\n");
emulation = TRUE;
}
+
if (emulation)
{
si_emulated = context->stream_info;
}
else if (!context->transform_feedback_active)
{
- enum wined3d_primitive_type primitive_type = shader->u.gs.output_type
- ? shader->u.gs.output_type : d3d_primitive_type_from_gl(state->gl_primitive_type);
- GLenum mode = gl_tfb_primitive_type_from_d3d(primitive_type);
+ GLenum mode = gl_tfb_primitive_type_from_d3d(shader->u.gs.output_type);
GL_EXTCALL(glBeginTransformFeedback(mode));
checkGLcall("glBeginTransformFeedback");
context->transform_feedback_active = 1;
for (i = 0; i < context->buffer_fence_count; ++i)
wined3d_fence_issue(context->buffer_fences[i], device);
- context_release(context);
-}
-
-void context_unload_tex_coords(const struct wined3d_context *context)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- unsigned int texture_idx;
-
- for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
- {
- gl_info->gl_ops.ext.p_glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx);
- gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
-}
-
-void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
- GLuint *current_bo, const struct wined3d_state *state)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- unsigned int mapped_stage = 0;
- unsigned int texture_idx;
-
- for (texture_idx = 0; texture_idx < context->d3d_info->limits.ffp_blend_stages; ++texture_idx)
- {
- unsigned int coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
-
- if ((mapped_stage = context->tex_unit_map[texture_idx]) == WINED3D_UNMAPPED_STAGE)
- continue;
-
- if (mapped_stage >= gl_info->limits.texture_coords)
- {
- FIXME("Attempted to load unsupported texture coordinate %u.\n", mapped_stage);
- continue;
- }
-
- if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
- {
- const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx];
-
- TRACE("Setting up texture %u, idx %d, coord_idx %u, data {%#x:%p}.\n",
- texture_idx, mapped_stage, coord_idx, e->data.buffer_object, e->data.addr);
-
- if (*current_bo != e->data.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
- checkGLcall("glBindBuffer");
- *current_bo = e->data.buffer_object;
- }
-
- GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
- checkGLcall("glClientActiveTextureARB");
-
- /* The coords to supply depend completely on the fvf/vertex shader. */
- gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- else
- {
- GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
- }
- }
- if (gl_info->supported[NV_REGISTER_COMBINERS])
- {
- /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
- for (texture_idx = mapped_stage + 1; texture_idx < gl_info->limits.textures; ++texture_idx)
- {
- GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
- }
- }
-
- checkGLcall("loadTexCoords");
-}
-
-/* This should match any arrays loaded in context_load_vertex_data(). */
-static void context_unload_vertex_data(struct wined3d_context *context)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
-
- if (!context->namedArraysLoaded)
- return;
- gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
- gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
- gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
- if (gl_info->supported[EXT_SECONDARY_COLOR])
- gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
- context_unload_tex_coords(context);
- context->namedArraysLoaded = FALSE;
-}
-
-static void context_load_vertex_data(struct wined3d_context *context,
- const struct wined3d_stream_info *si, const struct wined3d_state *state)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- const struct wined3d_stream_info_element *e;
- GLuint current_bo;
-
- TRACE("context %p, si %p, state %p.\n", context, si, state);
-
- /* This is used for the fixed-function pipeline only, and the
- * fixed-function pipeline doesn't do instancing. */
- context->instance_count = 0;
- current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0;
-
- /* Blend data */
- if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT))
- || si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
- {
- /* TODO: Support vertex blending in immediate mode draws. No need to
- * write a FIXME here, this is done after the general vertex
- * declaration decoding. */
- WARN("Vertex blending not supported.\n");
- }
-
- /* Point Size */
- if (si->use_map & (1u << WINED3D_FFP_PSIZE))
- {
- /* No such functionality in the fixed-function GL pipeline. */
- WARN("Per-vertex point size not supported.\n");
- }
-
- /* Position */
- if (si->use_map & (1u << WINED3D_FFP_POSITION))
- {
- e = &si->elements[WINED3D_FFP_POSITION];
-
- if (current_bo != e->data.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
- checkGLcall("glBindBuffer");
- current_bo = e->data.buffer_object;
- }
-
- TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
- e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- checkGLcall("glVertexPointer(...)");
- gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
- checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
- }
-
- /* Normals */
- if (si->use_map & (1u << WINED3D_FFP_NORMAL))
- {
- e = &si->elements[WINED3D_FFP_NORMAL];
-
- if (current_bo != e->data.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
- checkGLcall("glBindBuffer");
- current_bo = e->data.buffer_object;
- }
-
- TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- checkGLcall("glNormalPointer(...)");
- gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
- checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
-
- }
- else
- {
- gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
- checkGLcall("glNormal3f(0, 0, 0)");
- }
-
- /* Diffuse colour */
- if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
- {
- e = &si->elements[WINED3D_FFP_DIFFUSE];
-
- if (current_bo != e->data.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
- checkGLcall("glBindBuffer");
- current_bo = e->data.buffer_object;
- }
-
- TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
- e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
- gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
- checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
-
- }
- else
- {
- gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- checkGLcall("glColor4f(1, 1, 1, 1)");
- }
-
- /* Specular colour */
- if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
- {
- TRACE("Setting specular colour.\n");
-
- e = &si->elements[WINED3D_FFP_SPECULAR];
-
- if (gl_info->supported[EXT_SECONDARY_COLOR])
- {
- GLenum type = e->format->gl_vtx_type;
- GLint format = e->format->gl_vtx_format;
-
- if (current_bo != e->data.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
- checkGLcall("glBindBuffer");
- current_bo = e->data.buffer_object;
- }
-
- if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
- {
- /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
- * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
- * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
- * 4 component secondary colors use it
- */
- TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride));
- checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
- }
- else
- {
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride));
- checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
- break;
-
- default:
- FIXME("Add 4 component specular colour pointers for type %#x.\n", type);
- /* Make sure that the right colour component is dropped. */
- TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride);
- GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
- e->data.addr + state->load_base_vertex_index * e->stride));
- checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
- }
- }
- gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
- checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
- }
- else
- {
- WARN("Specular colour is not supported in this GL implementation.\n");
- }
- }
- else
- {
- if (gl_info->supported[EXT_SECONDARY_COLOR])
- {
- GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
- checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
- }
- else
- {
- WARN("Specular colour is not supported in this GL implementation.\n");
- }
- }
-
- /* Texture coordinates */
- context_load_tex_coords(context, si, ¤t_bo, state);
-}
-
-static void context_unload_numbered_array(struct wined3d_context *context, unsigned int i)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
-
- GL_EXTCALL(glDisableVertexAttribArray(i));
- checkGLcall("glDisableVertexAttribArray");
- if (gl_info->supported[ARB_INSTANCED_ARRAYS])
- GL_EXTCALL(glVertexAttribDivisor(i, 0));
-
- context->numbered_array_mask &= ~(1u << i);
-}
-
-static void context_unload_numbered_arrays(struct wined3d_context *context)
-{
- unsigned int i;
-
- while (context->numbered_array_mask)
- {
- i = wined3d_bit_scan(&context->numbered_array_mask);
- context_unload_numbered_array(context, i);
- }
-}
-
-static void context_load_numbered_arrays(struct wined3d_context *context,
- const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
-{
- const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
- const struct wined3d_gl_info *gl_info = context->gl_info;
- GLuint current_bo;
- unsigned int i;
-
- /* Default to no instancing. */
- context->instance_count = 0;
- current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0;
-
- for (i = 0; i < MAX_ATTRIBS; ++i)
- {
- const struct wined3d_stream_info_element *element = &stream_info->elements[i];
- const struct wined3d_stream_state *stream;
-
- if (!(stream_info->use_map & (1u << i)))
- {
- if (context->numbered_array_mask & (1u << i))
- context_unload_numbered_array(context, i);
- if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE)
- GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f));
- else
- GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f));
- continue;
- }
-
- stream = &state->streams[element->stream_idx];
-
- if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
- context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
-
- if (gl_info->supported[ARB_INSTANCED_ARRAYS])
- {
- GL_EXTCALL(glVertexAttribDivisor(i, element->divisor));
- }
- else if (element->divisor)
- {
- /* Unload instanced arrays, they will be loaded using immediate
- * mode instead. */
- if (context->numbered_array_mask & (1u << i))
- context_unload_numbered_array(context, i);
- continue;
- }
-
- TRACE("Loading array %u [VBO=%u].\n", i, element->data.buffer_object);
-
- if (element->stride)
- {
- if (current_bo != element->data.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object));
- checkGLcall("glBindBuffer");
- current_bo = element->data.buffer_object;
- }
- /* Use the VBO to find out if a vertex buffer exists, not the vb
- * pointer. vb can point to a user pointer data blob. In that case
- * current_bo will be 0. If there is a vertex buffer but no vbo we
- * won't be load converted attributes anyway. */
- if (vs && vs->reg_maps.shader_version.major >= 4
- && (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER))
- {
- GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
- element->stride, element->data.addr + state->load_base_vertex_index * element->stride));
- }
- else
- {
- GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
- element->format->gl_normalized, element->stride,
- element->data.addr + state->load_base_vertex_index * element->stride));
- }
-
- if (!(context->numbered_array_mask & (1u << i)))
- {
- GL_EXTCALL(glEnableVertexAttribArray(i));
- context->numbered_array_mask |= (1u << i);
- }
- }
- else
- {
- /* Stride = 0 means always the same values.
- * glVertexAttribPointer() doesn't do that. Instead disable the
- * pointer and set up the attribute statically. But we have to
- * figure out the system memory address. */
- const BYTE *ptr = element->data.addr;
- if (element->data.buffer_object)
- ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context);
-
- if (context->numbered_array_mask & (1u << i))
- context_unload_numbered_array(context, i);
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
- switch (element->format->id)
- {
- case WINED3DFMT_R32_FLOAT:
- GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr));
- break;
- case WINED3DFMT_R32G32_FLOAT:
- GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr));
- break;
- case WINED3DFMT_R32G32B32_FLOAT:
- GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr));
- break;
- case WINED3DFMT_R32G32B32A32_FLOAT:
- GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr));
- break;
- case WINED3DFMT_R8G8B8A8_UINT:
- GL_EXTCALL(glVertexAttrib4ubv(i, ptr));
- break;
- case WINED3DFMT_B8G8R8A8_UNORM:
- if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
- {
- const DWORD *src = (const DWORD *)ptr;
- DWORD c = *src & 0xff00ff00u;
- c |= (*src & 0xff0000u) >> 16;
- c |= (*src & 0xffu) << 16;
- GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
- break;
- }
- /* else fallthrough */
- case WINED3DFMT_R8G8B8A8_UNORM:
- GL_EXTCALL(glVertexAttrib4Nubv(i, ptr));
- break;
- case WINED3DFMT_R16G16_SINT:
- GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr));
- break;
- case WINED3DFMT_R16G16B16A16_SINT:
- GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr));
- break;
- case WINED3DFMT_R16G16_SNORM:
- {
- const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
- GL_EXTCALL(glVertexAttrib4Nsv(i, s));
- break;
- }
- case WINED3DFMT_R16G16_UNORM:
- {
- const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
- GL_EXTCALL(glVertexAttrib4Nusv(i, s));
- break;
- }
- case WINED3DFMT_R16G16B16A16_SNORM:
- GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr));
- break;
- case WINED3DFMT_R16G16B16A16_UNORM:
- GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr));
- break;
- case WINED3DFMT_R10G10B10X2_UINT:
- FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n");
- /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
- break;
- case WINED3DFMT_R10G10B10X2_SNORM:
- FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n");
- /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
- break;
- case WINED3DFMT_R16G16_FLOAT:
- if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
- {
- /* Not supported by GL_ARB_half_float_vertex. */
- GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr));
- }
- else
- {
- float x = float_16_to_32(((const unsigned short *)ptr) + 0);
- float y = float_16_to_32(((const unsigned short *)ptr) + 1);
- GL_EXTCALL(glVertexAttrib2f(i, x, y));
- }
- break;
- case WINED3DFMT_R16G16B16A16_FLOAT:
- if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
- {
- /* Not supported by GL_ARB_half_float_vertex. */
- GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr));
- }
- else
- {
- float x = float_16_to_32(((const unsigned short *)ptr) + 0);
- float y = float_16_to_32(((const unsigned short *)ptr) + 1);
- float z = float_16_to_32(((const unsigned short *)ptr) + 2);
- float w = float_16_to_32(((const unsigned short *)ptr) + 3);
- GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w));
- }
- break;
- default:
- ERR("Unexpected declaration in stride 0 attributes.\n");
- break;
-
- }
- }
- }
- checkGLcall("Loading numbered arrays");
-}
-
-void context_update_stream_sources(struct wined3d_context *context, const struct wined3d_state *state)
-{
-
- if (context->use_immediate_mode_draw)
- return;
-
- context_unload_vertex_data(context);
- if (context->d3d_info->ffp_generic_attributes || use_vs(state))
- {
- TRACE("Loading numbered arrays.\n");
- context_load_numbered_arrays(context, &context->stream_info, state);
- return;
- }
-
- TRACE("Loading named arrays.\n");
- context_unload_numbered_arrays(context);
- context_load_vertex_data(context, &context->stream_info, state);
- context->namedArraysLoaded = TRUE;
-}
-
-static void apply_texture_blit_state(const struct wined3d_gl_info *gl_info, struct gl_texture *texture,
- GLenum target, unsigned int level, enum wined3d_texture_filter_type filter)
-{
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
- wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, level);
-
- /* We changed the filtering settings on the texture. Make sure they get
- * reset on subsequent draws. */
- texture->sampler_desc.mag_filter = WINED3D_TEXF_POINT;
- texture->sampler_desc.min_filter = WINED3D_TEXF_POINT;
- texture->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
- texture->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
- texture->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
- texture->sampler_desc.srgb_decode = FALSE;
- texture->base_level = level;
-}
-
-/* Context activation is done by the caller. */
-void context_draw_shaded_quad(struct wined3d_context *context, struct wined3d_texture *texture,
- unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect,
- enum wined3d_texture_filter_type filter)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_blt_info info;
- unsigned int level, w, h, i;
- SIZE dst_size;
- struct blit_vertex
- {
- float x, y;
- struct wined3d_vec3 texcoord;
- }
- quad[4];
-
- texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
-
- level = sub_resource_idx % texture->level_count;
- context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
- apply_texture_blit_state(gl_info, &texture->texture_rgb, info.bind_target, level, filter);
- gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level);
-
- context_get_rt_size(context, &dst_size);
- w = dst_size.cx;
- h = dst_size.cy;
-
- quad[0].x = dst_rect->left * 2.0f / w - 1.0f;
- quad[0].y = dst_rect->top * 2.0f / h - 1.0f;
- quad[0].texcoord = info.texcoords[0];
-
- quad[1].x = dst_rect->right * 2.0f / w - 1.0f;
- quad[1].y = dst_rect->top * 2.0f / h - 1.0f;
- quad[1].texcoord = info.texcoords[1];
-
- quad[2].x = dst_rect->left * 2.0f / w - 1.0f;
- quad[2].y = dst_rect->bottom * 2.0f / h - 1.0f;
- quad[2].texcoord = info.texcoords[2];
-
- quad[3].x = dst_rect->right * 2.0f / w - 1.0f;
- quad[3].y = dst_rect->bottom * 2.0f / h - 1.0f;
- quad[3].texcoord = info.texcoords[3];
-
- /* Draw a quad. */
- if (gl_info->supported[ARB_VERTEX_BUFFER_OBJECT])
- {
- if (!context->blit_vbo)
- GL_EXTCALL(glGenBuffers(1, &context->blit_vbo));
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, context->blit_vbo));
-
- context_unload_vertex_data(context);
- context_unload_numbered_arrays(context);
-
- GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW));
- GL_EXTCALL(glVertexAttribPointer(0, 2, GL_FLOAT, FALSE, sizeof(*quad), NULL));
- GL_EXTCALL(glVertexAttribPointer(1, 3, GL_FLOAT, FALSE, sizeof(*quad),
- (void *)FIELD_OFFSET(struct blit_vertex, texcoord)));
-
- GL_EXTCALL(glEnableVertexAttribArray(0));
- GL_EXTCALL(glEnableVertexAttribArray(1));
-
- gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
- GL_EXTCALL(glDisableVertexAttribArray(1));
- GL_EXTCALL(glDisableVertexAttribArray(0));
- }
- else
- {
- gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
-
- for (i = 0; i < ARRAY_SIZE(quad); ++i)
- {
- GL_EXTCALL(glVertexAttrib3fv(1, &quad[i].texcoord.x));
- GL_EXTCALL(glVertexAttrib2fv(0, &quad[i].x));
- }
-
- gl_info->gl_ops.gl.p_glEnd();
- }
- checkGLcall("draw");
-
- gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
- context_bind_texture(context, info.bind_target, 0);
-}
-
-/* Context activation is done by the caller. */
-void context_draw_textured_quad(struct wined3d_context *context, struct wined3d_texture *texture,
- unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect,
- enum wined3d_texture_filter_type filter)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_blt_info info;
- unsigned int level;
-
- texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
-
- gl_info->gl_ops.gl.p_glEnable(info.bind_target);
- checkGLcall("glEnable(bind_target)");
-
- level = sub_resource_idx % texture->level_count;
- context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
- apply_texture_blit_state(gl_info, &texture->texture_rgb, info.bind_target, level, filter);
- gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level);
- gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- checkGLcall("glTexEnvi");
-
- /* Draw a quad. */
- gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
- gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x);
- gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top);
-
- gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x);
- gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top);
-
- gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x);
- gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom);
-
- gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x);
- gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom);
- gl_info->gl_ops.gl.p_glEnd();
-
- gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
- context_bind_texture(context, info.bind_target, 0);
+ context_release(context);
}
WINED3D_CS_OP_DRAW,
WINED3D_CS_OP_FLUSH,
WINED3D_CS_OP_SET_PREDICATION,
- WINED3D_CS_OP_SET_VIEWPORTS,
- WINED3D_CS_OP_SET_SCISSOR_RECTS,
+ WINED3D_CS_OP_SET_VIEWPORT,
+ WINED3D_CS_OP_SET_SCISSOR_RECT,
WINED3D_CS_OP_SET_RENDERTARGET_VIEW,
WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW,
WINED3D_CS_OP_SET_VERTEX_DECLARATION,
struct wined3d_swapchain *swapchain;
RECT src_rect;
RECT dst_rect;
- unsigned int swap_interval;
+ DWORD swap_interval;
DWORD flags;
};
BOOL value;
};
-struct wined3d_cs_set_viewports
+struct wined3d_cs_set_viewport
{
enum wined3d_cs_op opcode;
- unsigned int viewport_count;
- struct wined3d_viewport viewports[1];
+ struct wined3d_viewport viewport;
};
-struct wined3d_cs_set_scissor_rects
+struct wined3d_cs_set_scissor_rect
{
enum wined3d_cs_op opcode;
- unsigned int rect_count;
- RECT rects[1];
+ RECT rect;
};
struct wined3d_cs_set_rendertarget_view
unsigned int sub_resource_idx;
struct wined3d_box box;
struct wined3d_sub_resource_data data;
+#if defined(STAGING_CSMT)
BYTE copy_data[1];
+#endif /* STAGING_CSMT */
};
struct wined3d_cs_add_dirty_texture_region
swapchain = op->swapchain;
wined3d_swapchain_set_window(swapchain, op->dst_window_override);
- wined3d_swapchain_set_swap_interval(swapchain, op->swap_interval);
+
+ if (op->swap_interval && swapchain->desc.swap_interval != op->swap_interval)
+ {
+ swapchain->desc.swap_interval = op->swap_interval;
+ swapchain_update_swap_interval(swapchain);
+ }
swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags);
void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
- unsigned int swap_interval, DWORD flags)
+ DWORD swap_interval, DWORD flags)
{
struct wined3d_cs_present *op;
unsigned int i;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
/* Limit input latency by limiting the number of presents that we can get
- * ahead of the worker thread. */
- while (pending >= swapchain->max_frame_latency)
+ * ahead of the worker thread. We have a constant limit here, but
+ * IDXGIDevice1 allows tuning this. */
+ while (pending > 1)
{
wined3d_pause();
pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0);
{
unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers;
const struct wined3d_state *state = &cs->device->state;
- const struct wined3d_viewport *vp = &state->viewports[0];
- struct wined3d_rendertarget_view *view;
+ const struct wined3d_viewport *vp = &state->viewport;
struct wined3d_cs_clear *op;
- RECT view_rect;
unsigned int i;
op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]),
WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_CLEAR;
op->flags = flags;
- if (flags & WINED3DCLEAR_TARGET)
- op->rt_count = rt_count;
- else
- op->rt_count = 0;
+ op->rt_count = rt_count;
op->fb = &cs->fb;
SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
- IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rects[0]);
+ IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rect);
op->color = *color;
op->depth = depth;
op->stencil = stencil;
{
for (i = 0; i < rt_count; ++i)
{
- if ((view = state->fb->render_targets[i]))
- {
- SetRect(&view_rect, 0, 0, view->width, view->height);
- IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect);
- wined3d_resource_acquire(view->resource);
- }
+ if (state->fb->render_targets[i])
+ wined3d_resource_acquire(state->fb->render_targets[i]->resource);
}
}
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
- {
- view = state->fb->depth_stencil;
- SetRect(&view_rect, 0, 0, view->width, view->height);
- IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect);
- wined3d_resource_acquire(view->resource);
- }
+ wined3d_resource_acquire(state->fb->depth_stencil->resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
- const struct wined3d_shader *geometry_shader;
struct wined3d_state *state = &cs->state;
const struct wined3d_cs_draw *op = data;
int load_base_vertex_idx;
if (state->gl_primitive_type != op->primitive_type)
{
- if ((geometry_shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]) && !geometry_shader->function)
- device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY));
if (state->gl_primitive_type == GL_POINTS || op->primitive_type == GL_POINTS)
device_invalidate_state(cs->device, STATE_POINT_ENABLE);
state->gl_primitive_type = op->primitive_type;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
-static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
{
- const struct wined3d_cs_set_viewports *op = data;
+ const struct wined3d_cs_set_viewport *op = data;
- if (op->viewport_count)
- memcpy(cs->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports));
- else
- memset(cs->state.viewports, 0, sizeof(*cs->state.viewports));
- cs->state.viewport_count = op->viewport_count;
+ cs->state.viewport = op->viewport;
device_invalidate_state(cs->device, STATE_VIEWPORT);
}
-void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count,
- const struct wined3d_viewport *viewports)
+void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
{
- struct wined3d_cs_set_viewports *op;
+ struct wined3d_cs_set_viewport *op;
- op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_viewports, viewports[viewport_count]),
- WINED3D_CS_QUEUE_DEFAULT);
- op->opcode = WINED3D_CS_OP_SET_VIEWPORTS;
- memcpy(op->viewports, viewports, viewport_count * sizeof(*viewports));
- op->viewport_count = viewport_count;
+ op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+ op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
+ op->viewport = *viewport;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
-static void wined3d_cs_exec_set_scissor_rects(struct wined3d_cs *cs, const void *data)
+static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
{
- const struct wined3d_cs_set_scissor_rects *op = data;
+ const struct wined3d_cs_set_scissor_rect *op = data;
- if (op->rect_count)
- memcpy(cs->state.scissor_rects, op->rects, op->rect_count * sizeof(*op->rects));
- else
- SetRectEmpty(cs->state.scissor_rects);
- cs->state.scissor_rect_count = op->rect_count;
+ cs->state.scissor_rect = op->rect;
device_invalidate_state(cs->device, STATE_SCISSORRECT);
}
-void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects)
+void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
{
- struct wined3d_cs_set_scissor_rects *op;
+ struct wined3d_cs_set_scissor_rect *op;
- op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_scissor_rects, rects[rect_count]),
- WINED3D_CS_QUEUE_DEFAULT);
- op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECTS;
- memcpy(op->rects, rects, rect_count * sizeof(*rects));
- op->rect_count = rect_count;
+ op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+ op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
+ op->rect = *rect;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
struct wined3d_device *device = cs->device;
struct wined3d_rendertarget_view *prev;
- if ((prev = cs->state.fb->depth_stencil) && prev->resource->type != WINED3D_RTYPE_BUFFER)
+ if ((prev = cs->state.fb->depth_stencil))
{
- struct wined3d_texture *prev_texture = texture_from_resource(prev->resource);
+ struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
- if (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
- || prev_texture->flags & WINED3D_TEXTURE_DISCARD)
- wined3d_texture_validate_location(prev_texture,
+ if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
+ || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD))
+ {
+ wined3d_texture_validate_location(prev_surface->container,
prev->sub_resource_idx, WINED3D_LOCATION_DISCARDED);
+ }
}
cs->fb.depth_stencil = op->view;
const struct wined3d_cs_set_rasterizer_state *op = data;
cs->state.rasterizer_state = op->state;
- device_invalidate_state(cs->device, STATE_RASTERIZER);
+ device_invalidate_state(cs->device, STATE_FRONTFACE);
}
void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs,
buffer_from_resource(op->src_resource), op->src_box.left,
op->src_box.right - op->src_box.left);
}
+ else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
+ {
+ struct wined3d_surface *dst_surface, *src_surface;
+ struct wined3d_texture *dst_texture, *src_texture;
+ RECT dst_rect, src_rect;
+
+ dst_texture = texture_from_resource(op->dst_resource);
+ src_texture = texture_from_resource(op->src_resource);
+ dst_surface = dst_texture->sub_resources[op->dst_sub_resource_idx].u.surface;
+ src_surface = src_texture->sub_resources[op->src_sub_resource_idx].u.surface;
+ SetRect(&dst_rect, op->dst_box.left, op->dst_box.top, op->dst_box.right, op->dst_box.bottom);
+ SetRect(&src_rect, op->src_box.left, op->src_box.top, op->src_box.right, op->src_box.bottom);
+
+ if (FAILED(wined3d_surface_blt(dst_surface, &dst_rect, src_surface,
+ &src_rect, op->flags, &op->fx, op->filter)))
+ FIXME("Blit failed.\n");
+ }
else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D)
{
struct wined3d_texture *src_texture, *dst_texture;
goto error;
}
+ if (op->src_box.left || op->src_box.top || op->src_box.front)
+ {
+ FIXME("Source box %s not supported for %s resources.\n",
+ debug_box(&op->src_box), debug_d3dresourcetype(op->dst_resource->type));
+ goto error;
+ }
+
dst_texture = texture_from_resource(op->dst_resource);
src_texture = texture_from_resource(op->src_resource);
&row_pitch, &slice_pitch);
wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
- wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context,
- dst_texture->resource.format, &op->src_box, wined3d_const_bo_address(&addr),
- row_pitch, slice_pitch, op->dst_box.left, op->dst_box.top, op->dst_box.front, FALSE);
+ wined3d_texture_upload_data(dst_texture, op->dst_sub_resource_idx, context, &op->dst_box,
+ wined3d_const_bo_address(&addr), row_pitch, slice_pitch);
wined3d_texture_validate_location(dst_texture, op->dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_invalidate_location(dst_texture, op->dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
}
else
{
- if (FAILED(texture2d_blt(texture_from_resource(op->dst_resource), op->dst_sub_resource_idx,
- &op->dst_box, texture_from_resource(op->src_resource), op->src_sub_resource_idx,
- &op->src_box, op->flags, &op->fx, op->filter)))
- FIXME("Blit failed.\n");
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type));
}
error:
struct wined3d_const_bo_address addr;
struct wined3d_context *context;
struct wined3d_texture *texture;
- struct wined3d_box src_box;
context = context_acquire(cs->device, NULL, 0);
wined3d_texture_load_location(texture, op->sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
- wined3d_box_set(&src_box, 0, 0, box->right - box->left, box->bottom - box->top, 0, box->back - box->front);
- wined3d_texture_upload_data(texture, op->sub_resource_idx, context, texture->resource.format, &src_box,
- &addr, op->data.row_pitch, op->data.slice_pitch, box->left, box->top, box->front, FALSE);
+ wined3d_texture_upload_data(texture, op->sub_resource_idx, context,
+ box, &addr, op->data.row_pitch, op->data.slice_pitch);
wined3d_texture_validate_location(texture, op->sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_invalidate_location(texture, op->sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
unsigned int slice_pitch)
{
struct wined3d_cs_update_sub_resource *op;
+#if defined(STAGING_CSMT)
size_t data_size, size;
if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
no_async:
wined3d_resource_wait_idle(resource);
+#endif /* STAGING_CSMT */
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP);
op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
wined3d_resource_acquire(resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP);
+#if !defined(STAGING_CSMT)
+ /* The data pointer may go away, so we need to wait until it is read.
+ * Copying the data may be faster if it's small. */
+#endif /* STAGING_CSMT */
cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP);
}
/* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
/* WINED3D_CS_OP_FLUSH */ wined3d_cs_exec_flush,
/* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication,
- /* WINED3D_CS_OP_SET_VIEWPORTS */ wined3d_cs_exec_set_viewports,
- /* WINED3D_CS_OP_SET_SCISSOR_RECTS */ wined3d_cs_exec_set_scissor_rects,
+ /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
+ /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
/* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
/* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view,
/* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
/* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps,
};
+#if defined(STAGING_CSMT)
static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
{
return TRUE;
}
+#endif /* STAGING_CSMT */
static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
{
if (size > (cs->data_size - cs->end))
static const struct wined3d_cs_ops wined3d_cs_st_ops =
{
+#if defined(STAGING_CSMT)
wined3d_cs_st_check_space,
+#endif /* STAGING_CSMT */
wined3d_cs_st_require_space,
wined3d_cs_st_submit,
wined3d_cs_st_finish,
wined3d_cs_queue_submit(&cs->queue[queue_id], cs);
}
+#if defined(STAGING_CSMT)
static BOOL wined3d_cs_queue_check_space(struct wined3d_cs_queue *queue, size_t size)
{
size_t queue_size = ARRAY_SIZE(queue->data);
return (remaining >= packet_size);
}
+#endif /* STAGING_CSMT */
static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs)
{
size_t queue_size = ARRAY_SIZE(queue->data);
return packet->data;
}
+#if defined(STAGING_CSMT)
static BOOL wined3d_cs_mt_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
{
if (cs->thread_id == GetCurrentThreadId())
return wined3d_cs_queue_check_space(&cs->queue[queue_id], size);
}
+#endif /* STAGING_CSMT */
static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
{
if (cs->thread_id == GetCurrentThreadId())
static const struct wined3d_cs_ops wined3d_cs_mt_ops =
{
+#if defined(STAGING_CSMT)
wined3d_cs_mt_check_space,
+#endif /* STAGING_CSMT */
wined3d_cs_mt_require_space,
wined3d_cs_mt_submit,
wined3d_cs_mt_finish,
}
}
-enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type)
+static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type)
{
switch (primitive_type)
{
float depth, DWORD stencil)
{
struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL;
+ struct wined3d_surface *target = rtv ? wined3d_rendertarget_view_get_surface(rtv) : NULL;
struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
+ struct wined3d_surface *depth_stencil = dsv ? wined3d_rendertarget_view_get_surface(dsv) : NULL;
const struct wined3d_state *state = &device->cs->state;
- struct wined3d_texture *depth_stencil = NULL;
const struct wined3d_gl_info *gl_info;
- struct wined3d_texture *target = NULL;
UINT drawable_width, drawable_height;
struct wined3d_color corrected_color;
struct wined3d_context *context;
BOOL render_offscreen;
unsigned int i;
- if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER)
- {
- target = texture_from_resource(rtv->resource);
- context = context_acquire(device, target, rtv->sub_resource_idx);
- }
+ if (target)
+ context = context_acquire(device, target->container, rtv->sub_resource_idx);
else
- {
context = context_acquire(device, NULL, 0);
- }
-
- if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER)
- depth_stencil = texture_from_resource(dsv->resource);
-
if (!context->valid)
{
context_release(context);
}
else
{
- unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->level_count;
+ unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->container->level_count;
render_offscreen = TRUE;
- drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level);
- drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil, ds_level);
+ drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil->container, ds_level);
+ drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil->container, ds_level);
}
if (depth_stencil)
gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom,
draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
}
+ checkGLcall("glScissor");
gl_info->gl_ops.gl.p_glClear(clear_mask);
+ checkGLcall("glClear");
}
else
{
gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom,
current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
}
+ checkGLcall("glScissor");
+
gl_info->gl_ops.gl.p_glClear(clear_mask);
+ checkGLcall("glClear");
}
}
- context->scissor_rect_count = WINED3D_MAX_VIEWPORTS;
- checkGLcall("clear");
- if (flags & WINED3DCLEAR_TARGET && target->swapchain && target->swapchain->front_buffer == target)
- gl_info->gl_ops.gl.p_glFlush();
+ if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
+ && target->container->swapchain && target->container->swapchain->front_buffer == target->container))
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
}
if (gl_info->supported[EXT_TEXTURE_ARRAY])
{
+
gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d_array);
TRACE("Dummy 1D array texture given name %u.\n", textures->tex_1d_array);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0,
- GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_array);
TRACE("Dummy 2D array texture given name %u.\n", textures->tex_2d_array);
if (gl_info->supported[EXT_TEXTURE_ARRAY])
{
- gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d_array);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
}
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
return;
}
wined3d_ffp_blitter_create(&device->blitter, &device->adapter->gl_info);
- if (!wined3d_glsl_blitter_create(&device->blitter, device))
- wined3d_arbfp_blitter_create(&device->blitter, device);
+ wined3d_arbfp_blitter_create(&device->blitter, device);
wined3d_fbo_blitter_create(&device->blitter, &device->adapter->gl_info);
wined3d_raw_blitter_create(&device->blitter, &device->adapter->gl_info);
goto err_out;
}
- if (swapchain_desc->backbuffer_count && swapchain_desc->backbuffer_usage & WINED3DUSAGE_RENDERTARGET)
+ if (swapchain_desc->backbuffer_count)
{
struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource;
struct wined3d_view_desc view_desc;
TRACE("All defaults now set up.\n");
/* Clear the screen */
- if (device->back_buffer_view)
+ if (swapchain->back_buffers && swapchain->back_buffers[0])
clear_flags |= WINED3DCLEAR_TARGET;
if (swapchain_desc->enable_auto_depth_stencil)
clear_flags |= WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL;
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
+#if defined(STAGING_CSMT)
context_set_current(NULL);
+#endif /* STAGING_CSMT */
wined3d_device_delete_opengl_contexts(device);
if (device->fb.depth_stencil)
return device->state.base_vertex_index;
}
-void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count,
- const struct wined3d_viewport *viewports)
+void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport)
{
- unsigned int i;
+ TRACE("device %p, viewport %p.\n", device, viewport);
+ TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n",
+ viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z);
- TRACE("device %p, viewport_count %u, viewports %p.\n", device, viewport_count, viewports);
-
- for (i = 0; i < viewport_count; ++i)
- {
- TRACE("%u: x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", i, viewports[i].x, viewports[i].y,
- viewports[i].width, viewports[i].height, viewports[i].min_z, viewports[i].max_z);
- }
-
- if (viewport_count)
- memcpy(device->update_state->viewports, viewports, viewport_count * sizeof(*viewports));
- else
- memset(device->update_state->viewports, 0, sizeof(device->update_state->viewports));
- device->update_state->viewport_count = viewport_count;
+ device->update_state->viewport = *viewport;
/* Handle recording of state blocks */
if (device->recording)
return;
}
- wined3d_cs_emit_set_viewports(device->cs, viewport_count, viewports);
+ wined3d_cs_emit_set_viewport(device->cs, viewport);
}
-void CDECL wined3d_device_get_viewports(const struct wined3d_device *device, unsigned int *viewport_count,
- struct wined3d_viewport *viewports)
+void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport)
{
- unsigned int count;
-
- TRACE("device %p, viewport_count %p, viewports %p.\n", device, viewport_count, viewports);
+ TRACE("device %p, viewport %p.\n", device, viewport);
- count = viewport_count ? min(*viewport_count, device->state.viewport_count) : 1;
- if (count && viewports)
- memcpy(viewports, device->state.viewports, count * sizeof(*viewports));
- if (viewport_count)
- *viewport_count = device->state.viewport_count;
+ *viewport = device->state.viewport;
}
static void resolve_depth_buffer(struct wined3d_device *device)
return device->state.sampler_states[sampler_idx][state];
}
-void CDECL wined3d_device_set_scissor_rects(struct wined3d_device *device, unsigned int rect_count,
- const RECT *rects)
+void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect)
{
- unsigned int i;
-
- TRACE("device %p, rect_count %u, rects %p.\n", device, rect_count, rects);
-
- for (i = 0; i < rect_count; ++i)
- {
- TRACE("%u: %s\n", i, wine_dbgstr_rect(&rects[i]));
- }
+ TRACE("device %p, rect %s.\n", device, wine_dbgstr_rect(rect));
if (device->recording)
device->recording->changed.scissorRect = TRUE;
- if (device->update_state->scissor_rect_count == rect_count
- && !memcmp(device->update_state->scissor_rects, rects, rect_count * sizeof(*rects)))
+ if (EqualRect(&device->update_state->scissor_rect, rect))
{
- TRACE("App is setting the old scissor rectangles over, nothing to do.\n");
+ TRACE("App is setting the old scissor rectangle over, nothing to do.\n");
return;
}
-
- if (rect_count)
- memcpy(device->update_state->scissor_rects, rects, rect_count * sizeof(*rects));
- else
- memset(device->update_state->scissor_rects, 0, sizeof(device->update_state->scissor_rects));
- device->update_state->scissor_rect_count = rect_count;
+ CopyRect(&device->update_state->scissor_rect, rect);
if (device->recording)
{
return;
}
- wined3d_cs_emit_set_scissor_rects(device->cs, rect_count, rects);
+ wined3d_cs_emit_set_scissor_rect(device->cs, rect);
}
-void CDECL wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count, RECT *rects)
+void CDECL wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect)
{
- unsigned int count;
-
- TRACE("device %p, rect_count %p, rects %p.\n", device, rect_count, rects);
+ TRACE("device %p, rect %p.\n", device, rect);
- count = rect_count ? min(*rect_count, device->state.scissor_rect_count) : 1;
- if (count && rects)
- memcpy(rects, device->state.scissor_rects, count * sizeof(*rects));
- if (rect_count)
- *rect_count = device->state.scissor_rect_count;
+ *rect = device->state.scissor_rect;
+ TRACE("Returning rect %s.\n", wine_dbgstr_rect(rect));
}
void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device,
return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx);
}
-void CDECL wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int latency)
-{
- unsigned int i;
-
- if (!latency)
- latency = 3;
-
- device->max_frame_latency = latency;
- for (i = 0; i < device->swapchain_count; ++i)
- swapchain_set_max_frame_latency(device->swapchains[i], device);
-}
-
-unsigned int CDECL wined3d_device_get_max_frame_latency(const struct wined3d_device *device)
-{
- return device->max_frame_latency;
-}
-
/* Context activation is done by the caller. */
#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount,
TRACE("%.8e %.8e %.8e %.8e\n", world_mat._41, world_mat._42, world_mat._43, world_mat._44);
/* Get the viewport */
- wined3d_device_get_viewports(device, NULL, &vp);
- TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n",
+ wined3d_device_get_viewport(device, &vp);
+ TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n",
vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
multiply_matrix(&mat,&view_mat,&world_mat);
level_count = min(src_level_count, dst_level_count);
src_size = max(src_texture->resource.width, src_texture->resource.height);
- src_size = max(src_size, src_texture->resource.depth);
dst_size = max(dst_texture->resource.width, dst_texture->resource.height);
- dst_size = max(dst_size, dst_texture->resource.depth);
+ if (type == WINED3D_RTYPE_TEXTURE_3D)
+ {
+ src_size = max(src_size, src_texture->resource.depth);
+ dst_size = max(dst_size, dst_texture->resource.depth);
+ }
while (src_size > dst_size)
{
src_size >>= 1;
HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *device,
struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x,
unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource,
- unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags)
+ unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
{
struct wined3d_box dst_box, b;
TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, "
- "src_resource %p, src_sub_resource_idx %u, src_box %s, flags %#x.\n",
+ "src_resource %p, src_sub_resource_idx %u, src_box %s.\n",
device, dst_resource, dst_sub_resource_idx, dst_x, dst_y, dst_z,
- src_resource, src_sub_resource_idx, debug_box(src_box), flags);
-
- if (flags)
- FIXME("Ignoring flags %#x.\n", flags);
+ src_resource, src_sub_resource_idx, debug_box(src_box));
if (src_resource == dst_resource && src_sub_resource_idx == dst_sub_resource_idx)
{
wined3d_box_set(&dst_box, dst_x, 0, dst_x + (src_box->right - src_box->left), 1, 0, 1);
}
- else
+ else if (dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
{
struct wined3d_texture *dst_texture = texture_from_resource(dst_resource);
struct wined3d_texture *src_texture = texture_from_resource(src_resource);
return WINED3DERR_INVALIDCALL;
}
+#if !defined(STAGING_CSMT)
if (dst_texture->sub_resources[dst_sub_resource_idx].map_count)
{
WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx);
{
WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx);
return WINED3DERR_INVALIDCALL;
+#else /* STAGING_CSMT */
+ if (dst_texture->sub_resources[dst_sub_resource_idx].map_count ||
+ src_texture->sub_resources[src_sub_resource_idx].map_count)
+ {
+ struct wined3d_device *device = dst_texture->resource.device;
+ device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
+ if (dst_texture->sub_resources[dst_sub_resource_idx].map_count ||
+ src_texture->sub_resources[src_sub_resource_idx].map_count)
+ {
+ WARN("Destination or source sub-resource is mapped.\n");
+ return WINEDDERR_SURFACEBUSY;
+ }
+#endif /* STAGING_CSMT */
}
if (!src_box)
{
- unsigned int src_w, src_h, src_d, dst_w, dst_h, dst_d, dst_level;
+ unsigned int src_w, src_h, dst_w, dst_h, dst_level;
src_w = wined3d_texture_get_level_width(src_texture, src_level);
src_h = wined3d_texture_get_level_height(src_texture, src_level);
- src_d = wined3d_texture_get_level_depth(src_texture, src_level);
dst_level = dst_sub_resource_idx % dst_texture->level_count;
dst_w = wined3d_texture_get_level_width(dst_texture, dst_level) - dst_x;
dst_h = wined3d_texture_get_level_height(dst_texture, dst_level) - dst_y;
- dst_d = wined3d_texture_get_level_depth(dst_texture, dst_level) - dst_z;
- wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, min(src_d, dst_d));
+ wined3d_box_set(&b, 0, 0, min(src_w, dst_w), min(src_h, dst_h), 0, 1);
src_box = &b;
}
else if (FAILED(wined3d_texture_check_box_dimensions(src_texture, src_level, src_box)))
}
wined3d_box_set(&dst_box, dst_x, dst_y, dst_x + (src_box->right - src_box->left),
- dst_y + (src_box->bottom - src_box->top), dst_z, dst_z + (src_box->back - src_box->front));
+ dst_y + (src_box->bottom - src_box->top), 0, 1);
if (FAILED(wined3d_texture_check_box_dimensions(dst_texture,
dst_sub_resource_idx % dst_texture->level_count, &dst_box)))
{
return WINED3DERR_INVALIDCALL;
}
}
+ else
+ {
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type));
+ return WINED3DERR_INVALIDCALL;
+ }
wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box,
src_resource, src_sub_resource_idx, src_box, WINED3D_BLT_RAW, NULL, WINED3D_TEXF_POINT);
void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource,
unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch,
- unsigned int depth_pitch, unsigned int flags)
+ unsigned int depth_pitch)
{
unsigned int width, height, depth;
struct wined3d_box b;
- TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u, "
- "flags %#x.\n",
- device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch, flags);
-
- if (flags)
- FIXME("Ignoring flags %#x.\n", flags);
+ TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n",
+ device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch);
if (resource->type == WINED3D_RTYPE_BUFFER)
{
height = 1;
depth = 1;
}
- else
+ else if (resource->type == WINED3D_RTYPE_TEXTURE_1D ||
+ resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D)
{
struct wined3d_texture *texture = texture_from_resource(resource);
unsigned int level;
height = wined3d_texture_get_level_height(texture, level);
depth = wined3d_texture_get_level_depth(texture, level);
}
+ else
+ {
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
+ return;
+ }
if (!box)
{
return;
}
+#if !defined(STAGING_CSMT)
+ wined3d_resource_wait_idle(resource);
+
+#endif /* STAGING_CSMT */
wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
}
return WINED3D_OK;
resource = view->resource;
- if (resource->type != WINED3D_RTYPE_TEXTURE_1D && resource->type != WINED3D_RTYPE_TEXTURE_2D)
+ if (resource->type != WINED3D_RTYPE_TEXTURE_2D)
{
FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
return WINED3DERR_INVALIDCALL;
{
struct wined3d_state *state = &device->state;
- state->viewports[0].x = 0;
- state->viewports[0].y = 0;
- state->viewports[0].width = view->width;
- state->viewports[0].height = view->height;
- state->viewports[0].min_z = 0.0f;
- state->viewports[0].max_z = 1.0f;
- state->viewport_count = 1;
- wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports);
+ state->viewport.x = 0;
+ state->viewport.y = 0;
+ state->viewport.width = view->width;
+ state->viewport.height = view->height;
+ state->viewport.min_z = 0.0f;
+ state->viewport.max_z = 1.0f;
+ wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
- SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height);
- state->scissor_rect_count = 1;
- wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects);
+ SetRect(&state->scissor_rect, 0, 0, view->width, view->height);
+ wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
}
+
prev = device->fb.render_targets[view_idx];
if (view == prev)
return WINED3D_OK;
TRACE("auto_depth_stencil_format %s\n", debug_d3dformat(swapchain_desc->auto_depth_stencil_format));
TRACE("flags %#x\n", swapchain_desc->flags);
TRACE("refresh_rate %u\n", swapchain_desc->refresh_rate);
+ TRACE("swap_interval %u\n", swapchain_desc->swap_interval);
TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode);
- if (swapchain_desc->backbuffer_usage && swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET)
+ if (swapchain_desc->backbuffer_usage != WINED3DUSAGE_RENDERTARGET)
FIXME("Got unexpected backbuffer usage %#x.\n", swapchain_desc->backbuffer_usage);
if (swapchain_desc->swap_effect != WINED3D_SWAP_EFFECT_DISCARD
swapchain->desc.auto_depth_stencil_format = swapchain_desc->auto_depth_stencil_format;
swapchain->desc.flags = swapchain_desc->flags;
swapchain->desc.refresh_rate = swapchain_desc->refresh_rate;
+ swapchain->desc.swap_interval = swapchain_desc->swap_interval;
swapchain->desc.auto_restore_display_mode = swapchain_desc->auto_restore_display_mode;
if (swapchain_desc->device_window
wined3d_rendertarget_view_decref(device->back_buffer_view);
device->back_buffer_view = NULL;
}
- if (swapchain->desc.backbuffer_count && swapchain->desc.backbuffer_usage & WINED3DUSAGE_RENDERTARGET)
+ if (swapchain->desc.backbuffer_count)
{
struct wined3d_resource *back_buffer = &swapchain->back_buffers[0]->resource;
wined3d_device_set_rendertarget_view(device, 0, view, FALSE);
/* Note the min_z / max_z is not reset. */
- state->viewports[0].x = 0;
- state->viewports[0].y = 0;
- state->viewports[0].width = view->width;
- state->viewports[0].height = view->height;
- state->viewport_count = 1;
- wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports);
+ state->viewport.x = 0;
+ state->viewport.y = 0;
+ state->viewport.width = view->width;
+ state->viewport.height = view->height;
+ wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
- SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height);
- state->scissor_rect_count = 1;
- wined3d_cs_emit_set_scissor_rects(device->cs, 1, state->scissor_rects);
+ SetRect(&state->scissor_rect, 0, 0, view->width, view->height);
+ wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
}
if (device->d3d_initialized)
{
if (reset_state)
hr = wined3d_device_create_primary_opengl_context(device);
+ swapchain_update_swap_interval(swapchain);
}
/* All done. There is no need to reload resources or shaders, this will happen automatically on the
case WINED3D_RTYPE_TEXTURE_3D:
for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
{
- if (&device->state.textures[i]->resource == resource)
+ struct wined3d_texture *texture = texture_from_resource(resource);
+
+ if (device->state.textures[i] == texture)
{
- ERR("Texture resource %p is still in use, stage %u.\n", resource, i);
+ ERR("Texture %p is still in use, stage %u.\n", texture, i);
device->state.textures[i] = NULL;
}
- if (device->recording && &device->update_state->textures[i]->resource == resource)
+ if (device->recording && device->update_state->textures[i] == texture)
{
- ERR("Texture resource %p is still in use by recording stateblock %p, stage %u.\n",
- resource, device->recording, i);
+ ERR("Texture %p is still in use by recording stateblock %p, stage %u.\n",
+ texture, device->recording, i);
device->update_state->textures[i] = NULL;
}
}
break;
case WINED3D_RTYPE_BUFFER:
- for (i = 0; i < MAX_STREAMS; ++i)
{
- if (&device->state.streams[i].buffer->resource == resource)
+ struct wined3d_buffer *buffer = buffer_from_resource(resource);
+
+ for (i = 0; i < MAX_STREAMS; ++i)
{
- ERR("Buffer resource %p is still in use, stream %u.\n", resource, i);
- device->state.streams[i].buffer = NULL;
+ if (device->state.streams[i].buffer == buffer)
+ {
+ ERR("Buffer %p is still in use, stream %u.\n", buffer, i);
+ device->state.streams[i].buffer = NULL;
+ }
+
+ if (device->recording && device->update_state->streams[i].buffer == buffer)
+ {
+ ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
+ buffer, device->recording, i);
+ device->update_state->streams[i].buffer = NULL;
+ }
}
- if (device->recording && &device->update_state->streams[i].buffer->resource == resource)
+ if (device->state.index_buffer == buffer)
{
- ERR("Buffer resource %p is still in use by stateblock %p, stream %u.\n",
- resource, device->recording, i);
- device->update_state->streams[i].buffer = NULL;
+ ERR("Buffer %p is still in use as index buffer.\n", buffer);
+ device->state.index_buffer = NULL;
}
- }
- if (&device->state.index_buffer->resource == resource)
- {
- ERR("Buffer resource %p is still in use as index buffer.\n", resource);
- device->state.index_buffer = NULL;
- }
-
- if (device->recording && &device->update_state->index_buffer->resource == resource)
- {
- ERR("Buffer resource %p is still in use by stateblock %p as index buffer.\n",
- resource, device->recording);
- device->update_state->index_buffer = NULL;
+ if (device->recording && device->update_state->index_buffer == buffer)
+ {
+ ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
+ buffer, device->recording);
+ device->update_state->index_buffer = NULL;
+ }
}
break;
&adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
device->update_state = &device->state;
- device->max_frame_latency = 3;
-
if (!(device->cs = wined3d_cs_create(device)))
{
WARN("Failed to create command stream.\n");
else
return CallWindowProcA(proc, window, message, wparam, lparam);
}
+#if defined(STAGING_CSMT)
+
+/* Context activation is done by the caller */
+struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage,
+ GLenum type_hint, struct wined3d_context *context)
+{
+ struct wined3d_gl_bo *ret;
+ const struct wined3d_gl_info *gl_info;
+
+ TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size, gl_usage,
+ type_hint);
+
+ ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
+ if(!ret)
+ return NULL;
+ ret->type_hint = type_hint;
+ ret->size = size;
+ ret->usage = gl_usage;
+
+ gl_info = context->gl_info;
+
+ GL_EXTCALL(glGenBuffers(1, &ret->name));
+ if (type_hint == GL_ELEMENT_ARRAY_BUFFER)
+ context_invalidate_state(context, STATE_INDEXBUFFER);
+ GL_EXTCALL(glBindBuffer(type_hint, ret->name));
+ GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage));
+ GL_EXTCALL(glBindBuffer(type_hint, 0));
+ checkGLcall("Create buffer object");
+
+ TRACE("Successfully created and set up buffer %u\n", ret->name);
+ return ret;
+}
+
+/* Context activation is done by the caller */
+static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct wined3d_context *context,
+ struct wined3d_gl_bo *bo)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name);
+
+ GL_EXTCALL(glDeleteBuffers(1, &bo->name));
+ checkGLcall("glDeleteBuffers");
+
+ HeapFree(GetProcessHeap(), 0, bo);
+}
+
+/* Context activation is done by the caller */
+void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo,
+ const struct wined3d_context *context)
+{
+ TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name);
+
+ wined3d_device_destroy_bo(device, context, bo);
+}
+#endif /* STAGING_CSMT */
{"GL_ARB_point_parameters", ARB_POINT_PARAMETERS },
{"GL_ARB_point_sprite", ARB_POINT_SPRITE },
{"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX },
- {"GL_ARB_sample_shading", ARB_SAMPLE_SHADING },
{"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS },
{"GL_ARB_seamless_cube_map", ARB_SEAMLESS_CUBE_MAP },
{"GL_ARB_shader_atomic_counters", ARB_SHADER_ATOMIC_COUNTERS },
{"GL_ARB_shader_image_load_store", ARB_SHADER_IMAGE_LOAD_STORE },
{"GL_ARB_shader_image_size", ARB_SHADER_IMAGE_SIZE },
{"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT},
- {"GL_ARB_shader_texture_image_samples", ARB_SHADER_TEXTURE_IMAGE_SAMPLES},
{"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD },
{"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 },
{"GL_ARB_shading_language_420pack", ARB_SHADING_LANGUAGE_420PACK },
{"GL_ARB_transform_feedback3", ARB_TRANSFORM_FEEDBACK3 },
{"GL_ARB_uniform_buffer_object", ARB_UNIFORM_BUFFER_OBJECT },
{"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA },
+ {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND },
{"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT },
{"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM },
{"GL_ARB_vertex_shader", ARB_VERTEX_SHADER },
GLenum error;
DWORD data[16];
- if (!gl_info->supported[EXT_SECONDARY_COLOR] || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ if (!gl_info->supported[EXT_SECONDARY_COLOR])
return FALSE;
while (gl_info->gl_ops.gl.p_glGetError());
return FALSE;
if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
return FALSE;
- if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
- return FALSE;
gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980, "NVIDIA GeForce GTX 980", DRIVER_NVIDIA_GEFORCE8, 4096},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX980TI, "NVIDIA GeForce GTX 980 Ti", DRIVER_NVIDIA_GEFORCE8, 6144},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050, "NVIDIA GeForce GTX 1050", DRIVER_NVIDIA_GEFORCE8, 2048},
- {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1050TI, "NVIDIA GeForce GTX 1050 Ti", DRIVER_NVIDIA_GEFORCE8, 4096},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1060, "NVIDIA GeForce GTX 1060", DRIVER_NVIDIA_GEFORCE8, 6144},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1070, "NVIDIA GeForce GTX 1070", DRIVER_NVIDIA_GEFORCE8, 8192},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080, "NVIDIA GeForce GTX 1080", DRIVER_NVIDIA_GEFORCE8, 8192},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX1080TI, "NVIDIA GeForce GTX 1080 Ti", DRIVER_NVIDIA_GEFORCE8, 11264},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANX_PASCAL, "NVIDIA TITAN X (Pascal)", DRIVER_NVIDIA_GEFORCE8, 12288},
- {HW_VENDOR_NVIDIA, CARD_NVIDIA_TITANV, "NVIDIA TITAN V", DRIVER_NVIDIA_GEFORCE8, 12288},
/* AMD cards */
{HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 },
* In order to avoid this application bug we limit the amount of video memory
* to LONG_MAX for older Windows versions.
*/
+#ifdef __i386__
if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX)
{
TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX);
driver_info->vram_bytes = LONG_MAX;
}
+#endif
/* Try to obtain driver version information for the current Windows version. This fails in
* some cases:
cards_nvidia_binary[] =
{
/* Direct 3D 11 */
- {"TITAN V", CARD_NVIDIA_TITANV}, /* GeForce 1000 - highend */
{"TITAN X (Pascal)", CARD_NVIDIA_TITANX_PASCAL}, /* GeForce 1000 - highend */
{"GTX 1080 Ti", CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */
{"GTX 1080", CARD_NVIDIA_GEFORCE_GTX1080}, /* GeForce 1000 - highend */
{"GTX 1070", CARD_NVIDIA_GEFORCE_GTX1070}, /* GeForce 1000 - highend */
{"GTX 1060", CARD_NVIDIA_GEFORCE_GTX1060}, /* GeForce 1000 - midend high */
- {"GTX 1050 Ti", CARD_NVIDIA_GEFORCE_GTX1050TI}, /* GeForce 1000 - midend */
{"GTX 1050", CARD_NVIDIA_GEFORCE_GTX1050}, /* GeForce 1000 - midend */
{"GTX 980 Ti", CARD_NVIDIA_GEFORCE_GTX980TI}, /* GeForce 900 - highend */
{"GTX 980", CARD_NVIDIA_GEFORCE_GTX980}, /* GeForce 900 - highend */
{"830M", CARD_INTEL_830M},
},
/* 20101109 - These are never returned by current Gallium radeon
- * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. */
+ * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351.
+ *
+ * These are returned but not handled: RC410, RV380. */
cards_amd_mesa[] =
{
/* Polaris 10/11 */
{"RS482", CARD_AMD_RADEON_XPRESS_200M},
{"RS480", CARD_AMD_RADEON_XPRESS_200M},
{"RS400", CARD_AMD_RADEON_XPRESS_200M},
- {"RC410", CARD_AMD_RADEON_XPRESS_200M},
/* R300 */
{"R360", CARD_AMD_RADEON_9500},
{"R350", CARD_AMD_RADEON_9500},
{"R300", CARD_AMD_RADEON_9500},
- {"RV380", CARD_AMD_RADEON_9500},
{"RV370", CARD_AMD_RADEON_9500},
{"RV360", CARD_AMD_RADEON_9500},
{"RV351", CARD_AMD_RADEON_9500},
USE_GL_FUNC(glPointParameterfvARB)
/* GL_ARB_provoking_vertex */
USE_GL_FUNC(glProvokingVertex)
- /* GL_ARB_sample_shading */
- USE_GL_FUNC(glMinSampleShadingARB)
/* GL_ARB_sampler_objects */
USE_GL_FUNC(glGenSamplers)
USE_GL_FUNC(glDeleteSamplers)
USE_GL_FUNC(glGetUniformBlockIndex)
USE_GL_FUNC(glGetUniformIndices)
USE_GL_FUNC(glUniformBlockBinding)
+ /* GL_ARB_vertex_blend */
+ USE_GL_FUNC(glVertexBlendARB)
+ USE_GL_FUNC(glWeightPointerARB)
+ USE_GL_FUNC(glWeightbvARB)
+ USE_GL_FUNC(glWeightdvARB)
+ USE_GL_FUNC(glWeightfvARB)
+ USE_GL_FUNC(glWeightivARB)
+ USE_GL_FUNC(glWeightsvARB)
+ USE_GL_FUNC(glWeightubvARB)
+ USE_GL_FUNC(glWeightuivARB)
+ USE_GL_FUNC(glWeightusvARB)
/* GL_ARB_vertex_buffer_object */
USE_GL_FUNC(glBindBufferARB)
USE_GL_FUNC(glBufferDataARB)
MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT);
MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB);
MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB);
- MAP_GL_FUNCTION(glMinSampleShading, glMinSampleShadingARB);
MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB);
MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB);
MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT);
GLfloat gl_floatv[2];
GLint gl_max;
+ gl_info->limits.blends = 1;
gl_info->limits.buffers = 1;
gl_info->limits.textures = 0;
gl_info->limits.texture_coords = 0;
gl_info->limits.texture_coords = 1;
}
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
+ gl_info->limits.blends = gl_max;
+ TRACE("Max blends: %u.\n", gl_info->limits.blends);
+ }
if (gl_info->supported[EXT_TEXTURE3D])
{
gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
{EXT_TEXTURE_SNORM, MAKEDWORD_VERSION(3, 1)},
/* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */
- {ARB_DEPTH_CLAMP, MAKEDWORD_VERSION(3, 2)},
{ARB_DRAW_ELEMENTS_BASE_VERTEX, MAKEDWORD_VERSION(3, 2)},
/* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2
* core geometry shaders so it's not really correct to expose the
{ARB_DRAW_INDIRECT, MAKEDWORD_VERSION(4, 0)},
{ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)},
- {ARB_SAMPLE_SHADING, MAKEDWORD_VERSION(4, 0)},
{ARB_TESSELLATION_SHADER, MAKEDWORD_VERSION(4, 0)},
{ARB_TEXTURE_CUBE_MAP_ARRAY, MAKEDWORD_VERSION(4, 0)},
{ARB_TEXTURE_GATHER, MAKEDWORD_VERSION(4, 0)},
{ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)},
{ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)},
{ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)},
- {ARB_SHADER_TEXTURE_IMAGE_SAMPLES, MAKEDWORD_VERSION(4, 5)},
{ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)},
{ARB_TEXTURE_FILTER_ANISOTROPIC, MAKEDWORD_VERSION(4, 6)},
gl_info->supported[WINED3D_GL_BLEND_EQUATION] = TRUE;
if (gl_version >= MAKEDWORD_VERSION(2, 0))
- {
gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
- /* We want to use the core APIs for two-sided stencil in GL 2.0. */
- gl_info->supported[EXT_STENCIL_TWO_SIDE] = FALSE;
- }
if (gl_version >= MAKEDWORD_VERSION(3, 2))
gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE;
case WINED3D_RTYPE_NONE:
allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
| WINED3DUSAGE_RENDERTARGET;
- gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
+ gl_type = WINED3D_GL_RES_TYPE_TEX_1D;
gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
break;
| WINED3DUSAGE_SOFTWAREPROCESSING
| WINED3DUSAGE_TEXTURE
| WINED3DUSAGE_QUERY_FILTER
- | WINED3DUSAGE_QUERY_GENMIPMAP
| WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
| WINED3DUSAGE_QUERY_SRGBREAD
| WINED3DUSAGE_QUERY_SRGBWRITE
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
break;
+ case WINED3D_RTYPE_BUFFER:
+ allowed_usage = WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE;
+ gl_type = gl_type_end = WINED3D_GL_RES_TYPE_BUFFER;
+ break;
+
default:
FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
return WINED3DERR_NOTAVAILABLE;
WINED3DCAPS3_COPY_TO_VIDMEM |
WINED3DCAPS3_COPY_TO_SYSTEMMEM;
+ caps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
+ WINED3DPRESENT_INTERVAL_ONE;
+
caps->CursorCaps = WINED3DCURSORCAPS_COLOR |
WINED3DCURSORCAPS_LOWRES;
{
const char *gl_vendor, *gl_renderer;
- if (wined3d_settings.explicit_gl_version)
+ if (wined3d_settings.explicit_gl_version || (flags & WINED3D_PIXEL_CENTER_INTEGER))
return wined3d_settings.max_gl_version;
gl_vendor = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR);
gl_renderer = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER);
if (!gl_vendor || !gl_renderer
|| wined3d_guess_card_vendor(gl_vendor, gl_renderer) == HW_VENDOR_NVIDIA)
- return MAKEDWORD_VERSION(1, 0);
+ return wined3d_settings.max_gl_version;
- return wined3d_settings.max_gl_version;
+ return MAKEDWORD_VERSION(4, 4);
+}
+
+static BOOL has_extension(const char *list, const char *ext)
+{
+ size_t len = strlen(ext);
+ while (list)
+ {
+ while (*list == ' ') list++;
+ if (!strncmp(list, ext, len) && (!list[len] || list[len] == ' ')) return TRUE;
+ list = strchr(list, ' ');
+ }
+ return FALSE;
}
static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
}
max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags);
+
+ if (wined3d_creation_flags & WINED3D_REQUEST_D3D10)
+ {
+ const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
+ if (!has_extension(gl_extensions, "GL_ARB_compatibility"))
+ {
+ ERR_(winediag)("GL_ARB_compatibility not supported, requesting context with GL version 3.2.\n");
+ max_gl_version = MAKEDWORD_VERSION(3, 2);
+ }
+ }
+
for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
{
if (supported_gl_versions[i] <= max_gl_version)
enum wined3d_data_type data_type;
BOOL output_single_component;
unsigned int offset_size;
+ enum wined3d_shader_resource_type emulate_lod;
};
enum heap_node_op
}
}
-static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
+static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count,
char *strings, unsigned int *strings_length, GLenum buffer_mode)
{
unsigned int i, buffer_idx, count, length, highest_output_slot, stride;
- BOOL have_varyings_to_record = FALSE;
count = length = 0;
highest_output_slot = 0;
string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx);
append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
}
-
- have_varyings_to_record = TRUE;
}
if (buffer_idx < so_desc->buffer_stride_count
*varying_count = count;
if (strings_length)
*strings_length = length;
-
- return have_varyings_to_record;
}
static void shader_glsl_init_transform_feedback(const struct wined3d_context *context,
- struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader)
+ struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
{
const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
const struct wined3d_gl_info *gl_info = context->gl_info;
buffer = string_buffer_get(&priv->string_buffers);
- if (!shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode))
- {
- FIXME("No varyings to record, disabling transform feedback.\n");
- shader->u.gs.so_desc.element_count = 0;
- string_buffer_release(&priv->string_buffers, buffer);
- return;
- }
+ shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode);
if (!(varyings = heap_calloc(count, sizeof(*varyings))))
{
const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
const struct wined3d_gl_info *gl_info = context->gl_info;
struct shader_glsl_priv *priv = shader_priv;
- float position_fixup[4 * WINED3D_MAX_VIEWPORTS];
+ float position_fixup[4];
float normal[3 * 3];
DWORD update_mask;
if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP)
{
- unsigned int fixup_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ?
- max(state->viewport_count, 1) : 1;
- shader_get_position_fixup(context, state, fixup_count, position_fixup);
+ shader_get_position_fixup(context, state, position_fixup);
if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY])
- GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, fixup_count, position_fixup));
+ GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup));
else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup));
else
}
}
-static const char *get_fragment_output(const struct wined3d_gl_info *gl_info)
-{
- return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out";
-}
-
static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
{
switch (primitive_type)
sprintf(register_name, "vpc[%u]", reg->idx[0].offset);
break;
- case WINED3DSPR_SAMPLEMASK:
- sprintf(register_name, "sample_mask");
- break;
-
default:
FIXME("Unhandled register type %#x.\n", reg->type);
sprintf(register_name, "unrecognized_register");
enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
struct shader_glsl_ctx_priv *priv = ctx->backend_data;
const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx);
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
unsigned int coord_size, deriv_size;
sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
+ sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE;
if (resource_type >= ARRAY_SIZE(resource_type_info))
{
if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
projected = FALSE;
- if (needs_legacy_glsl_syntax(gl_info))
+ if (shadow && lod)
+ {
+ switch (resource_type)
+ {
+ /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */
+ case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+ sample_function->emulate_lod = resource_type;
+ grad = offset = TRUE;
+ lod = FALSE;
+ break;
+
+ /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */
+ case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+ sample_function->emulate_lod = resource_type;
+ grad = legacy_syntax = TRUE;
+ lod = FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (legacy_syntax)
{
if (shadow)
base = "shadow";
sample_function->offset_size = offset ? deriv_size : 0;
sample_function->coord_mask = (1u << coord_size) - 1;
sample_function->deriv_mask = (1u << deriv_size) - 1;
- sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info);
+ sample_function->output_single_component = shadow && !legacy_syntax;
}
static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset,
const char *coord_reg_fmt, ...)
{
+ static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0};
const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
char dst_swizzle[6];
struct color_fixup_desc fixup;
break;
}
}
+ if (sample_function->emulate_lod)
+ {
+ if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias);
+ switch (sample_function->emulate_lod)
+ {
+ case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+ if (!dx) dx = "vec2(0.0, 0.0)";
+ if (!dy) dy = "vec2(0.0, 0.0)";
+ break;
+
+ case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
+ if (!dx) dx = "vec3(0.0, 0.0, 0.0)";
+ if (!dy) dy = "vec3(0.0, 0.0, 0.0)";
+ break;
+
+ default:
+ break;
+ }
+ if (!offset) offset = &dummy_offset;
+ }
if (dx && dy)
shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
else if (bias)
shader_glsl_color_correction(ins, fixup);
}
-static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOOL use_viewport_index)
+static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer)
{
/* Write the final position.
*
* pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering
* upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow
* a MAD. */
- if (use_viewport_index)
- {
- shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup[gl_ViewportIndex].y;\n");
- shader_addline(buffer, "gl_Position.xy += pos_fixup[gl_ViewportIndex].zw * gl_Position.ww;\n");
- }
- else
- {
- shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
- shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
- }
+ shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
+ shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
/* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix()
* in utils.c
static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
{
unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset;
- const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n");
if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL])
- shader_glsl_fixup_position(ins->ctx->buffer, reg_maps->viewport_array);
+ shader_glsl_fixup_position(ins->ctx->buffer);
if (!stream)
shader_addline(ins->ctx->buffer, "EmitVertex();\n");
shader_addline(buffer, ")%s);\n", dst_swizzle);
}
-static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins)
-{
- const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
- const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
- struct wined3d_string_buffer *buffer = ins->ctx->buffer;
- const struct wined3d_shader_dst_param *dst = ins->dst;
- const struct wined3d_shader_src_param *src = ins->src;
- enum wined3d_shader_resource_type resource_type;
- enum wined3d_data_type dst_data_type;
- unsigned int resource_idx, bind_idx;
- char dst_swizzle[6];
- DWORD write_mask;
-
- dst_data_type = dst->reg.data_type;
- if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT)
- dst_data_type = WINED3D_DATA_UINT;
- else if (ins->flags)
- FIXME("Unhandled flags %#x.\n", ins->flags);
-
- write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type);
- shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle);
-
- if (dst_data_type == WINED3D_DATA_UINT)
- shader_addline(buffer, "uvec4(");
- else
- shader_addline(buffer, "vec4(");
-
- if (src->reg.type == WINED3DSPR_RASTERIZER)
- {
- if (gl_info->supported[ARB_SAMPLE_SHADING])
- {
- shader_addline(buffer, "gl_NumSamples");
- }
- else
- {
- FIXME("OpenGL implementation does not support ARB_sample_shading.\n");
- shader_addline(buffer, "1");
- }
- }
- else
- {
- resource_idx = src->reg.idx[0].offset;
- resource_type = reg_maps->resource_info[resource_idx].type;
- if (resource_type >= ARRAY_SIZE(resource_type_info))
- {
- ERR("Unexpected resource type %#x.\n", resource_type);
- return;
- }
- bind_idx = shader_glsl_find_sampler(®_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT);
-
- if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES])
- {
- shader_addline(buffer, "textureSamples(%s_sampler%u)",
- shader_glsl_get_prefix(reg_maps->shader_version.type), bind_idx);
- }
- else
- {
- FIXME("textureSamples() is not supported.\n");
- shader_addline(buffer, "1");
- }
- }
-
- shader_addline(buffer, ", 0, 0, 0)%s);\n", dst_swizzle);
-}
-
static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
semantic_idx = input->semantic_idx;
shader_glsl_write_mask_to_str(input->mask, reg_mask);
- if (args->vp_mode == WINED3D_VP_MODE_SHADER)
+ if (args->vp_mode == vertexshader)
{
if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx)
{
shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n",
input->register_idx, reg_mask);
}
- else if (input->sysval_semantic == WINED3D_SV_SAMPLE_INDEX)
- {
- if (gl_info->supported[ARB_SAMPLE_SHADING])
- shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_SampleID);\n",
- input->register_idx, reg_mask);
- else
- FIXME("ARB_sample_shading is not supported.\n");
- }
else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx)
{
if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT])
else
FIXME("ARB_fragment_layer_viewport is not supported.\n");
}
- else if (input->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
- {
- if (gl_info->supported[ARB_VIEWPORT_ARRAY])
- shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_ViewportIndex);\n",
- input->register_idx, reg_mask);
- else
- FIXME("ARB_viewport_array is not supported.\n");
- }
else
{
if (input->sysval_semantic)
if (args->pointsprite)
shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n",
shader->u.ps.input_reg_map[input->register_idx]);
- else if (args->vp_mode == WINED3D_VP_MODE_NONE && args->texcoords_initialized & (1u << semantic_idx))
+ else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx))
shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n",
shader->u.ps.input_reg_map[input->register_idx], reg_mask,
needs_legacy_glsl_syntax(gl_info)
shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n",
output->register_idx, reg_mask);
}
- else if (output->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
- {
- shader_addline(buffer, "gl_ViewportIndex = floatBitsToInt(outputs[%u])%s;\n",
- output->register_idx, reg_mask);
- }
else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
{
shader_glsl_generate_clip_or_cull_distances(buffer, output, reg_maps_out->clip_distance_mask);
shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n");
if (gl_info->supported[ARB_SHADER_STORAGE_BUFFER_OBJECT])
shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n");
- if (gl_info->supported[ARB_SHADER_TEXTURE_IMAGE_SAMPLES])
- shader_addline(buffer, "#extension GL_ARB_shader_texture_image_samples : enable\n");
if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK])
shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n");
if (gl_info->supported[ARB_SHADING_LANGUAGE_PACKING])
shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n");
if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n");
- if (gl_info->supported[ARB_VIEWPORT_ARRAY])
- shader_addline(buffer, "#extension GL_ARB_viewport_array : enable\n");
if (gl_info->supported[EXT_GPU_SHADER4])
shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
if (gl_info->supported[EXT_TEXTURE_ARRAY])
shader_glsl_generate_fog_code(buffer, gl_info, args->fog);
shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1);
-
- if (reg_maps->sample_mask)
- shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
}
/* Context activation is done by the caller. */
shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n");
if (gl_info->supported[ARB_FRAGMENT_LAYER_VIEWPORT])
shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n");
- if (gl_info->supported[ARB_SAMPLE_SHADING])
- shader_addline(buffer, "#extension GL_ARB_sample_shading : enable\n");
if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
/* The spec says that it doesn't have to be explicitly enabled, but the
shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
}
- if (version->major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER)
+ if (version->major < 3 || args->vp_mode != vertexshader)
{
shader_addline(buffer, "uniform struct\n{\n");
shader_addline(buffer, " vec4 color;\n");
{
unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
- if (args->vp_mode == WINED3D_VP_MODE_SHADER && reg_maps->input_registers)
+ if (args->vp_mode == vertexshader && reg_maps->input_registers)
shader_glsl_declare_shader_inputs(gl_info, buffer, in_count,
shader->u.ps.interpolation_mode, version->major >= 4);
shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
shader_addline(buffer, "void main()\n{\n");
- if (reg_maps->sample_mask)
- shader_addline(buffer, "float sample_mask = uintBitsToFloat(0xffffffffu);\n");
-
/* Direct3D applications expect integer vPos values, while OpenGL drivers
* add approximately 0.5. This causes off-by-one problems as spotted by
* the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
"vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n");
}
- if (reg_maps->shader_version.major < 3 || args->vp_mode != WINED3D_VP_MODE_SHADER)
+ if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader)
{
unsigned int i;
WORD map = reg_maps->texcoord;
shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
- shader_glsl_fixup_position(buffer, FALSE);
+ shader_glsl_fixup_position(buffer);
}
/* Context activation is done by the caller. */
shader_addline(buffer, "setup_ds_output(ds_out);\n");
if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
- shader_glsl_fixup_position(buffer, FALSE);
+ shader_glsl_fixup_position(buffer);
}
static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context,
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
const struct wined3d_gl_info *gl_info = context->gl_info;
- const struct wined3d_shader_signature_element *output;
- enum wined3d_primitive_type primitive_type;
struct shader_glsl_ctx_priv priv_ctx;
- unsigned int max_vertices;
- unsigned int i, j;
GLuint shader_id;
memset(&priv_ctx, 0, sizeof(priv_ctx));
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
- primitive_type = shader->u.gs.input_type ? shader->u.gs.input_type : args->primitive_type;
- shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(primitive_type));
+ shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type));
if (shader->u.gs.instance_count > 1)
shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count);
shader_addline(buffer, ") in;\n");
-
- primitive_type = shader->u.gs.output_type ? shader->u.gs.output_type : args->primitive_type;
- if (!(max_vertices = shader->u.gs.vertices_out))
- {
- switch (args->primitive_type)
- {
- case WINED3D_PT_POINTLIST:
- max_vertices = 1;
- break;
- case WINED3D_PT_LINELIST:
- max_vertices = 2;
- break;
- case WINED3D_PT_TRIANGLELIST:
- max_vertices = 3;
- break;
- default:
- FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(args->primitive_type));
- break;
- }
- }
shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n",
- glsl_primitive_type_from_d3d(primitive_type), max_vertices);
+ glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out);
shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
if (!gl_info->supported[ARB_CLIP_CONTROL])
- {
- shader_addline(buffer, "uniform vec4 pos_fixup");
- if (reg_maps->viewport_array)
- shader_addline(buffer, "[%u]", WINED3D_MAX_VIEWPORTS);
- shader_addline(buffer, ";\n");
- }
+ shader_addline(buffer, "uniform vec4 pos_fixup;\n");
if (is_rasterization_disabled(shader))
{
shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count,
gl_info, TRUE, args->interpolation_mode);
}
-
shader_addline(buffer, "void main()\n{\n");
- if (shader->function)
- {
- if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
- return 0;
- }
- else
- {
- for (i = 0; i < max_vertices; ++i)
- {
- for (j = 0; j < shader->output_signature.element_count; ++j)
- {
- output = &shader->output_signature.elements[j];
- shader_addline(buffer, "gs_out[%u] = shader_in[%u].reg[%u];\n",
- output->register_idx, i, output->register_idx);
- }
- shader_addline(buffer, "setup_gs_output(gs_out);\n");
- if (!gl_info->supported[ARB_CLIP_CONTROL])
- shader_glsl_fixup_position(buffer, FALSE);
- shader_addline(buffer, "EmitVertex();\n");
- }
- }
+ if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
+ return 0;
shader_addline(buffer, "}\n");
shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
}
static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color,
- BOOL alpha, BOOL tmp_dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+ BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
{
const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
else
dstmask = ".w";
- dstreg = tmp_dst ? "temp_reg" : "ret";
+ if (dst == tempreg)
+ dstreg = "temp_reg";
+ else
+ dstreg = "ret";
arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0);
arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1);
tfactor_used = TRUE;
if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
tempreg_used = TRUE;
- if (settings->op[stage].tmp_dst)
+ if (settings->op[stage].dst == tempreg)
tempreg_used = TRUE;
if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
tss_const_map |= 1u << stage;
if (!(tex_map & (1u << stage)))
continue;
- if (settings->op[stage].projected == WINED3D_PROJECTION_NONE)
+ if (settings->op[stage].projected == proj_none)
{
proj = FALSE;
}
- else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4
- || settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+ else if (settings->op[stage].projected == proj_count4
+ || settings->op[stage].projected == proj_count3)
{
proj = TRUE;
}
shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1);
/* With projective textures, texbem only divides the static
- * texture coordinate, not the displacement, so multiply the
+ * texture coord, not the displacement, so multiply the
* displacement with the dividing parameter before passing it to
* TXP. */
- if (settings->op[stage].projected != WINED3D_PROJECTION_NONE)
+ if (settings->op[stage].projected != proj_none)
{
- if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT4)
+ if (settings->op[stage].projected == proj_count4)
{
shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n",
stage, stage);
shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n",
stage, stage - 1, stage - 1, stage - 1);
}
- else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
+ else if (settings->op[stage].projected == proj_count3)
{
shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n",
stage, texture_function, stage, stage);
if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
{
- shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+ shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
}
else if (op_equal)
{
- shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].tmp_dst,
+ shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
}
else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP
&& settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
{
- shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].tmp_dst,
+ shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
- shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].tmp_dst,
+ shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst,
settings->op[stage].aop, settings->op[stage].aarg0,
settings->op[stage].aarg1, settings->op[stage].aarg2);
}
&& gl_info->supported[ARB_SHADER_IMAGE_SIZE]
&& gl_info->supported[ARB_SHADING_LANGUAGE_PACKING]
&& gl_info->supported[ARB_TESSELLATION_SHADER]
- && gl_info->supported[ARB_TEXTURE_COMPRESSION_BPTC]
&& gl_info->supported[ARB_TEXTURE_GATHER]
&& gl_info->supported[ARB_TRANSFORM_FEEDBACK3])
return 5;
/* WINED3DSIH_SAMPLE_C */ shader_glsl_sample_c,
/* WINED3DSIH_SAMPLE_C_LZ */ shader_glsl_sample_c,
/* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample,
- /* WINED3DSIH_SAMPLE_INFO */ shader_glsl_sample_info,
+ /* WINED3DSIH_SAMPLE_INFO */ NULL,
/* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample,
/* WINED3DSIH_SAMPLE_POS */ NULL,
/* WINED3DSIH_SETP */ NULL,
shader_glsl_color_fixup_supported,
glsl_fragment_pipe_state_template,
};
-
-struct glsl_blitter_args
-{
- GLenum texture_type;
- struct color_fixup_desc fixup;
- unsigned short padding;
-};
-
-struct glsl_blitter_program
-{
- struct wine_rb_entry entry;
- struct glsl_blitter_args args;
- GLuint id;
-};
-
-struct wined3d_glsl_blitter
-{
- struct wined3d_blitter blitter;
- struct wined3d_string_buffer_list string_buffers;
- struct wine_rb_tree programs;
- GLuint palette_texture;
-};
-
-static int glsl_blitter_args_compare(const void *key, const struct wine_rb_entry *entry)
-{
- const struct glsl_blitter_args *a = key;
- const struct glsl_blitter_args *b = &WINE_RB_ENTRY_VALUE(entry, const struct glsl_blitter_program, entry)->args;
-
- return memcmp(a, b, sizeof(*a));
-}
-
-/* Context activation is done by the caller. */
-static void glsl_free_blitter_program(struct wine_rb_entry *entry, void *ctx)
-{
- struct glsl_blitter_program *program = WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry);
- struct wined3d_context *context = ctx;
- const struct wined3d_gl_info *gl_info = context->gl_info;
-
- GL_EXTCALL(glDeleteProgram(program->id));
- checkGLcall("glDeleteProgram()");
- heap_free(program);
-}
-
-/* Context activation is done by the caller. */
-static void glsl_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_glsl_blitter *glsl_blitter;
- struct wined3d_blitter *next;
-
- if ((next = blitter->next))
- next->ops->blitter_destroy(next, context);
-
- glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_blitter, blitter);
-
- if (glsl_blitter->palette_texture)
- gl_info->gl_ops.gl.p_glDeleteTextures(1, &glsl_blitter->palette_texture);
-
- wine_rb_destroy(&glsl_blitter->programs, glsl_free_blitter_program, context);
- string_buffer_list_cleanup(&glsl_blitter->string_buffers);
-
- heap_free(glsl_blitter);
-}
-
-static void glsl_blitter_generate_p8_shader(struct wined3d_string_buffer *buffer,
- const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
- const char *output, const char *tex_type, const char *swizzle)
-{
- shader_addline(buffer, "uniform sampler1D sampler_palette;\n");
- shader_addline(buffer, "\nvoid main()\n{\n");
- /* The alpha-component contains the palette index. */
- shader_addline(buffer, " float index = texture%s(sampler, out_texcoord.%s).%c;\n",
- needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle,
- gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x');
- /* Scale the index by 255/256 and add a bias of 0.5 in order to sample in
- * the middle. */
- shader_addline(buffer, " index = (index * 255.0 + 0.5) / 256.0;\n");
- shader_addline(buffer, " %s = texture%s(sampler_palette, index);\n",
- output, needs_legacy_glsl_syntax(gl_info) ? "1D" : "");
- shader_addline(buffer, "}\n");
-}
-
-static void gen_packed_yuv_read(struct wined3d_string_buffer *buffer,
- const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
- const char *tex_type)
-{
- enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
- char chroma, luminance;
- const char *tex;
-
- /* The YUY2 and UYVY formats contain two pixels packed into a 32 bit
- * macropixel, giving effectively 16 bits per pixel. The color consists of
- * a luminance(Y) and two chroma(U and V) values. Each macropixel has two
- * luminance values, one for each single pixel it contains, and one U and
- * one V value shared between both pixels.
- *
- * The data is loaded into an A8L8 texture. With YUY2, the luminance
- * component contains the luminance and alpha the chroma. With UYVY it is
- * vice versa. Thus take the format into account when generating the read
- * swizzles
- *
- * Reading the Y value is straightforward - just sample the texture. The
- * hardware takes care of filtering in the horizontal and vertical
- * direction.
- *
- * Reading the U and V values is harder. We have to avoid filtering
- * horizontally, because that would mix the U and V values of one pixel or
- * two adjacent pixels. Thus floor the texture coordinate and add 0.5 to
- * get an unfiltered read, regardless of the filtering setting. Vertical
- * filtering works automatically though - the U and V values of two rows
- * are mixed nicely.
- *
- * Apart of avoiding filtering issues, the code has to know which value it
- * just read, and where it can find the other one. To determine this, it
- * checks if it sampled an even or odd pixel, and shifts the 2nd read
- * accordingly.
- *
- * Handling horizontal filtering of U and V values requires reading a 2nd
- * pair of pixels, extracting U and V and mixing them. This is not
- * implemented yet.
- *
- * An alternative implementation idea is to load the texture as A8R8G8B8
- * texture, with width / 2. This way one read gives all 3 values, finding
- * U and V is easy in an unfiltered situation. Finding the luminance on
- * the other hand requires finding out if it is an odd or even pixel. The
- * real drawback of this approach is filtering. This would have to be
- * emulated completely in the shader, reading up two 2 packed pixels in up
- * to 2 rows and interpolating both horizontally and vertically. Beyond
- * that it would require adjustments to the texture handling code to deal
- * with the width scaling. */
-
- if (complex_fixup == COMPLEX_FIXUP_UYVY)
- {
- chroma = 'x';
- luminance = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y';
- }
- else
- {
- chroma = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'y';
- luminance = 'x';
- }
-
- tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
- /* First we have to read the chroma values. This means we need at least
- * two pixels (no filtering), or 4 pixels (with filtering). To get the
- * unmodified chroma, we have to rid ourselves of the filtering when we
- * sample the texture. */
- shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n");
- /* We must not allow filtering between pixel x and x+1, this would mix U
- * and V. Vertical filtering is ok. However, bear in mind that the pixel
- * center is at 0.5, so add 0.5. */
- shader_addline(buffer, " texcoord.x = (floor(texcoord.x * size.x) + 0.5) / size.x;\n");
- shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma);
-
- /* Multiply the x coordinate by 0.5 and get the fraction. This gives 0.25
- * and 0.75 for the even and odd pixels respectively. */
- /* Put the value into either of the chroma values. */
- shader_addline(buffer, " bool even = fract(texcoord.x * size.x * 0.5) < 0.5;\n");
- shader_addline(buffer, " if (even)\n");
- shader_addline(buffer, " chroma.y = luminance;\n");
- shader_addline(buffer, " else\n");
- shader_addline(buffer, " chroma.x = luminance;\n");
-
- /* Sample pixel 2. If we read an even pixel, sample the pixel right to the
- * current one. Otherwise, sample the left pixel. */
- shader_addline(buffer, " texcoord.x += even ? 1.0 / size.x : -1.0 / size.x;\n");
- shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, chroma);
-
- /* Put the value into the other chroma. */
- shader_addline(buffer, " if (even)\n");
- shader_addline(buffer, " chroma.x = luminance;\n");
- shader_addline(buffer, " else\n");
- shader_addline(buffer, " chroma.y = luminance;\n");
-
- /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of
- * the current one and lerp the two U and V values. */
-
- /* This gives the correctly filtered luminance value. */
- shader_addline(buffer, " luminance = texture%s(sampler, out_texcoord.xy).%c;\n", tex, luminance);
-}
-
-static void gen_yv12_read(struct wined3d_string_buffer *buffer,
- const struct wined3d_gl_info *gl_info, const char *tex_type)
-{
- char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x';
- const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
- /* YV12 surfaces contain a WxH sized luminance plane, followed by a
- * (W/2)x(H/2) V and a (W/2)x(H/2) U plane, each with 8 bit per pixel. So
- * the effective bitdepth is 12 bits per pixel. Since the U and V planes
- * have only half the pitch of the luminance plane, the packing into the
- * gl texture is a bit unfortunate. If the whole texture is interpreted as
- * luminance data it looks approximately like this:
- *
- * +----------------------------------+----
- * | |
- * | |
- * | |
- * | |
- * | | 2
- * | LUMINANCE | -
- * | | 3
- * | |
- * | |
- * | |
- * | |
- * +----------------+-----------------+----
- * | | |
- * | V even rows | V odd rows |
- * | | | 1
- * +----------------+------------------ -
- * | | | 3
- * | U even rows | U odd rows |
- * | | |
- * +----------------+-----------------+----
- * | | |
- * | 0.5 | 0.5 |
- *
- * So it appears as if there are 4 chroma images, but in fact the odd rows
- * in the chroma images are in the same row as the even ones. So it is
- * kinda tricky to read. */
-
- /* First sample the chroma values. */
- shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n");
- /* The chroma planes have only half the width. */
- shader_addline(buffer, " texcoord.x *= 0.5;\n");
-
- /* The first value is between 2/3 and 5/6 of the texture's height, so
- * scale+bias the coordinate. Also read the right side of the image when
- * reading odd lines.
- *
- * Don't forget to clamp the y values in into the range, otherwise we'll
- * get filtering bleeding. */
-
- /* Read odd lines from the right side (add 0.5 to the x coordinate). */
- shader_addline(buffer, " if (fract(floor(texcoord.y * size.y) * 0.5 + 1.0 / 6.0) >= 0.5)\n");
- shader_addline(buffer, " texcoord.x += 0.5;\n");
-
- /* Clamp, keep the half pixel origin in mind. */
- shader_addline(buffer, " texcoord.y = clamp(2.0 / 3.0 + texcoord.y / 6.0, "
- "2.0 / 3.0 + 0.5 / size.y, 5.0 / 6.0 - 0.5 / size.y);\n");
-
- shader_addline(buffer, " chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
- /* The other chroma value is 1/6th of the texture lower, from 5/6th to
- * 6/6th No need to clamp because we're just reusing the already clamped
- * value from above. */
- shader_addline(buffer, " texcoord.y += 1.0 / 6.0;\n");
- shader_addline(buffer, " chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
- /* Sample the luminance value. It is in the top 2/3rd of the texture, so
- * scale the y coordinate. Clamp the y coordinate to prevent the chroma
- * values from bleeding into the sampled luminance values due to
- * filtering. */
- shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n");
- /* Multiply the y coordinate by 2/3 and clamp it. */
- shader_addline(buffer, " texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n");
- shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-}
-
-static void gen_nv12_read(struct wined3d_string_buffer *buffer,
- const struct wined3d_gl_info *gl_info, const char *tex_type)
-{
- char component = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? 'w' : 'x';
- const char *tex = needs_legacy_glsl_syntax(gl_info) ? tex_type : "";
-
- /* NV12 surfaces contain a WxH sized luminance plane, followed by a
- * (W/2)x(H/2) sized plane where each component is an UV pair. So the
- * effective bitdepth is 12 bits per pixel. If the whole texture is
- * interpreted as luminance data it looks approximately like this:
- *
- * +----------------------------------+----
- * | |
- * | |
- * | |
- * | |
- * | | 2
- * | LUMINANCE | -
- * | | 3
- * | |
- * | |
- * | |
- * | |
- * +----------------------------------+----
- * |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV|
- * |UVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUVUV|
- * | | 1
- * | | -
- * | | 3
- * | |
- * | |
- * +----------------------------------+---- */
-
- /* First sample the chroma values. */
- shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n");
- /* We only have half the number of chroma pixels. */
- shader_addline(buffer, " texcoord.x *= 0.5;\n");
- shader_addline(buffer, " texcoord.y = (texcoord.y + 2.0) / 3.0;\n");
-
- /* We must not allow filtering horizontally, this would mix U and V.
- * Vertical filtering is ok. However, bear in mind that the pixel center
- * is at 0.5, so add 0.5. */
-
- /* Convert to non-normalised coordinates so we can find the individual
- * pixel. */
- shader_addline(buffer, " texcoord.x = floor(texcoord.x * size.x);\n");
- /* Multiply by 2 since chroma components are stored in UV pixel pairs, add
- * 0.5 to hit the center of the pixel. Then convert back to normalised
- * coordinates. */
- shader_addline(buffer, " texcoord.x = (texcoord.x * 2.0 + 0.5) / size.x;\n");
- /* Clamp, keep the half pixel origin in mind. */
- shader_addline(buffer, " texcoord.y = max(texcoord.y, 2.0 / 3.0 + 0.5 / size.y);\n");
-
- shader_addline(buffer, " chroma.y = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
- /* Add 1.0 / size.x to sample the adjacent texel. */
- shader_addline(buffer, " texcoord.x += 1.0 / size.x;\n");
- shader_addline(buffer, " chroma.x = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-
- /* Sample the luminance value. It is in the top 2/3rd of the texture, so
- * scale the y coordinate. Clamp the y coordinate to prevent the chroma
- * values from bleeding into the sampled luminance values due to
- * filtering. */
- shader_addline(buffer, " texcoord.xy = out_texcoord.xy;\n");
- /* Multiply the y coordinate by 2/3 and clamp it. */
- shader_addline(buffer, " texcoord.y = min(texcoord.y * 2.0 / 3.0, 2.0 / 3.0 - 0.5 / size.y);\n");
- shader_addline(buffer, " luminance = texture%s(sampler, texcoord.xy).%c;\n", tex, component);
-}
-
-static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffer,
- const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args,
- const char *output, const char *tex_type, const char *swizzle)
-{
- enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
-
- shader_addline(buffer, "const vec4 yuv_coef = vec4(1.403, -0.344, -0.714, 1.770);\n");
- shader_addline(buffer, "float luminance;\n");
- shader_addline(buffer, "vec2 texcoord;\n");
- shader_addline(buffer, "vec2 chroma;\n");
- shader_addline(buffer, "uniform vec2 size;\n");
-
- shader_addline(buffer, "\nvoid main()\n{\n");
-
- switch (complex_fixup)
- {
- case COMPLEX_FIXUP_UYVY:
- case COMPLEX_FIXUP_YUY2:
- gen_packed_yuv_read(buffer, gl_info, args, tex_type);
- break;
-
- case COMPLEX_FIXUP_YV12:
- gen_yv12_read(buffer, gl_info, tex_type);
- break;
-
- case COMPLEX_FIXUP_NV12:
- gen_nv12_read(buffer, gl_info, tex_type);
- break;
-
- default:
- FIXME("Unsupported fixup %#x.\n", complex_fixup);
- string_buffer_free(buffer);
- return;
- }
-
- /* Calculate the final result. Formula is taken from
- * http://www.fourcc.org/fccyvrgb.php. Note that the chroma
- * ranges from -0.5 to 0.5. */
- shader_addline(buffer, "\n chroma.xy -= 0.5;\n");
-
- shader_addline(buffer, " %s.x = luminance + chroma.x * yuv_coef.x;\n", output);
- shader_addline(buffer, " %s.y = luminance + chroma.y * yuv_coef.y + chroma.x * yuv_coef.z;\n", output);
- shader_addline(buffer, " %s.z =&nbs