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 = luminance + chroma.y * yuv_coef.w;\n", output);
-
- shader_addline(buffer, "}\n");
-}
-
-static void glsl_blitter_generate_plain_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, "\nvoid main()\n{\n");
- shader_addline(buffer, " %s = texture%s(sampler, out_texcoord.%s);\n",
- output, needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle);
- shader_glsl_color_correction_ext(buffer, output, WINED3DSP_WRITEMASK_ALL, args->fixup);
- shader_addline(buffer, "}\n");
-}
-
-/* Context activation is done by the caller. */
-static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter,
- const struct wined3d_gl_info *gl_info, const struct glsl_blitter_args *args)
-{
- static const struct
- {
- GLenum texture_target;
- const char texture_type[7];
- const char texcoord_swizzle[4];
- }
- texture_data[] =
- {
- {GL_TEXTURE_2D, "2D", "xy"},
- {GL_TEXTURE_CUBE_MAP, "Cube", "xyz"},
- {GL_TEXTURE_RECTANGLE_ARB, "2DRect", "xy"},
- };
- static const char vshader_main[] =
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(pos, 0.0, 1.0);\n"
- " out_texcoord = texcoord;\n"
- "}\n";
- enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
- struct wined3d_string_buffer *buffer, *output;
- GLuint program, vshader_id, fshader_id;
- const char *tex_type, *swizzle, *ptr;
- unsigned int i;
- GLint loc;
-
- for (i = 0; i < ARRAY_SIZE(texture_data); ++i)
- {
- if (args->texture_type == texture_data[i].texture_target)
- {
- tex_type = texture_data[i].texture_type;
- swizzle = texture_data[i].texcoord_swizzle;
- break;
- }
- }
- if (i == ARRAY_SIZE(texture_data))
- {
- FIXME("Unsupported texture type %#x.\n", args->texture_type);
- return 0;
- }
-
- program = GL_EXTCALL(glCreateProgram());
-
- vshader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
-
- buffer = string_buffer_get(&blitter->string_buffers);
- shader_glsl_add_version_declaration(buffer, gl_info);
- shader_addline(buffer, "%s vec2 pos;\n", get_attribute_keyword(gl_info));
- shader_addline(buffer, "%s vec3 texcoord;\n", get_attribute_keyword(gl_info));
- declare_out_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
- shader_addline(buffer, vshader_main);
-
- ptr = buffer->buffer;
- GL_EXTCALL(glShaderSource(vshader_id, 1, &ptr, NULL));
- GL_EXTCALL(glAttachShader(program, vshader_id));
- GL_EXTCALL(glDeleteShader(vshader_id));
-
- fshader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
-
- string_buffer_clear(buffer);
- shader_glsl_add_version_declaration(buffer, gl_info);
- shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type);
- declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
- if (!needs_legacy_glsl_syntax(gl_info))
- shader_addline(buffer, "out vec4 ps_out[1];\n");
-
- output = string_buffer_get(&blitter->string_buffers);
- string_buffer_sprintf(output, "%s[0]", get_fragment_output(gl_info));
-
- switch (complex_fixup)
- {
- case COMPLEX_FIXUP_P8:
- glsl_blitter_generate_p8_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle);
- break;
- case COMPLEX_FIXUP_YUY2:
- case COMPLEX_FIXUP_UYVY:
- case COMPLEX_FIXUP_YV12:
- case COMPLEX_FIXUP_NV12:
- glsl_blitter_generate_yuv_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle);
- break;
- case COMPLEX_FIXUP_NONE:
- glsl_blitter_generate_plain_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle);
- }
-
- string_buffer_release(&blitter->string_buffers, output);
-
- ptr = buffer->buffer;
- GL_EXTCALL(glShaderSource(fshader_id, 1, &ptr, NULL));
- string_buffer_release(&blitter->string_buffers, buffer);
- GL_EXTCALL(glAttachShader(program, fshader_id));
- GL_EXTCALL(glDeleteShader(fshader_id));
-
- GL_EXTCALL(glBindAttribLocation(program, 0, "pos"));
- GL_EXTCALL(glBindAttribLocation(program, 1, "texcoord"));
-
- if (!needs_legacy_glsl_syntax(gl_info))
- GL_EXTCALL(glBindFragDataLocation(program, 0, "ps_out"));
-
- GL_EXTCALL(glCompileShader(vshader_id));
- print_glsl_info_log(gl_info, vshader_id, FALSE);
- GL_EXTCALL(glCompileShader(fshader_id));
- print_glsl_info_log(gl_info, fshader_id, FALSE);
- GL_EXTCALL(glLinkProgram(program));
- shader_glsl_validate_link(gl_info, program);
-
- GL_EXTCALL(glUseProgram(program));
- loc = GL_EXTCALL(glGetUniformLocation(program, "sampler"));
- GL_EXTCALL(glUniform1i(loc, 0));
- if (complex_fixup == COMPLEX_FIXUP_P8)
- {
- loc = GL_EXTCALL(glGetUniformLocation(program, "sampler_palette"));
- GL_EXTCALL(glUniform1i(loc, 1));
- }
-
- return program;
-}
-
-/* Context activation is done by the caller. */
-static void glsl_blitter_upload_palette(struct wined3d_glsl_blitter *blitter,
- struct wined3d_context *context, const struct wined3d_texture *texture)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- const struct wined3d_palette *palette;
-
- palette = texture->swapchain ? texture->swapchain->palette : NULL;
-
- if (!blitter->palette_texture)
- gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture);
-
- context_active_texture(context, gl_info, 1);
- gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, blitter->palette_texture);
- gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-
- if (palette)
- {
- gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_BGRA,
- GL_UNSIGNED_INT_8_8_8_8_REV, palette->colors);
- }
- else
- {
- static const DWORD black;
-
- FIXME("P8 texture loaded without a palette.\n");
- gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 1, 0, GL_BGRA,
- GL_UNSIGNED_INT_8_8_8_8_REV, &black);
- }
-
- context_active_texture(context, gl_info, 0);
-}
-
-/* Context activation is done by the caller. */
-static struct glsl_blitter_program *glsl_blitter_get_program(struct wined3d_glsl_blitter *blitter,
- struct wined3d_context *context, const struct wined3d_texture *texture)
-{
- const struct wined3d_gl_info *gl_info = context->gl_info;
- struct glsl_blitter_program *program;
- struct glsl_blitter_args args;
- struct wine_rb_entry *entry;
-
- memset(&args, 0, sizeof(args));
- args.texture_type = texture->target;
- args.fixup = texture->resource.format->color_fixup;
-
- if ((entry = wine_rb_get(&blitter->programs, &args)))
- return WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry);
-
- if (!(program = heap_alloc(sizeof(*program))))
- {
- ERR("Failed to allocate blitter program memory.\n");
- return NULL;
- }
-
- program->args = args;
- if (!(program->id = glsl_blitter_generate_program(blitter, gl_info, &args)))
- {
- WARN("Failed to generate blitter program.\n");
- heap_free(program);
- return NULL;
- }
-
- if (wine_rb_put(&blitter->programs, &program->args, &program->entry) == -1)
- {
- ERR("Failed to store blitter program.\n");
- GL_EXTCALL(glDeleteProgram(program->id));
- heap_free(program);
- return NULL;
- }
-
- return program;
-}
-
-static BOOL glsl_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_context *context,
- const struct wined3d_texture *src_texture, DWORD src_location,
- const struct wined3d_texture *dst_texture, DWORD dst_location)
-{
- const struct wined3d_resource *src_resource = &src_texture->resource;
- const struct wined3d_resource *dst_resource = &dst_texture->resource;
- const struct wined3d_format *src_format = src_resource->format;
- const struct wined3d_format *dst_format = dst_resource->format;
- BOOL decompress;
-
- if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_format->id == src_format->id)
- {
- if (dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
- blit_op = WINED3D_BLIT_OP_DEPTH_BLIT;
- else
- blit_op = WINED3D_BLIT_OP_COLOR_BLIT;
- }
-
- if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT)
- {
- TRACE("Unsupported blit_op %#x.\n", blit_op);
- return FALSE;
- }
-
- if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
- return FALSE;
-
- if (src_texture->target == GL_TEXTURE_2D_MULTISAMPLE
- || dst_texture->target == GL_TEXTURE_2D_MULTISAMPLE
- || src_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY
- || dst_texture->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
- {
- TRACE("Multi-sample textures not supported.\n");
- return FALSE;
- }
-
- /* We don't necessarily want to blit from resources without
- * WINED3D_RESOURCE_ACCESS_GPU, but that may be the only way to decompress
- * compressed textures. */
- decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
- && !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
- if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
- {
- TRACE("Source or destination resource does not have GPU access.\n");
- return FALSE;
- }
-
- if (!is_identity_fixup(dst_format->color_fixup)
- && (dst_format->id != src_format->id || dst_location != WINED3D_LOCATION_DRAWABLE))
- {
- TRACE("Destination fixups are not supported.\n");
- return FALSE;
- }
-
- TRACE("Returning supported.\n");
- return TRUE;
-}
-
-static DWORD glsl_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,
- const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
-{
- struct wined3d_device *device = dst_texture->resource.device;
- const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_texture *staging_texture = NULL;
- struct wined3d_glsl_blitter *glsl_blitter;
- struct glsl_blitter_program *program;
- struct wined3d_blitter *next;
- unsigned int src_level;
- GLint location;
- 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), colour_key, debug_d3dtexturefiltertype(filter));
-
- if (!glsl_blitter_supported(op, context, src_texture, src_location, dst_texture, 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, colour_key, filter);
- }
-
- glsl_blitter = CONTAINING_RECORD(blitter, struct wined3d_glsl_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
- && !wined3d_resource_is_offscreen(&src_texture->resource))
- {
-
- /* 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);
-
- 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_blit_state(context, device);
-
- if (dst_location == WINED3D_LOCATION_DRAWABLE)
- {
- d = *dst_rect;
- wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d);
- dst_rect = &d;
- }
-
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
- {
- GLenum buffer;
-
- if (dst_location == WINED3D_LOCATION_DRAWABLE)
- {
- TRACE("Destination texture %p is onscreen.\n", dst_texture);
- buffer = wined3d_texture_get_gl_buffer(dst_texture);
- }
- else
- {
- TRACE("Destination texture %p is offscreen.\n", dst_texture);
- 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_set_draw_buffer(context, buffer);
- context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
- context_invalidate_state(context, STATE_FRAMEBUFFER);
- }
-
- if (!(program = glsl_blitter_get_program(glsl_blitter, context, src_texture)))
- {
- ERR("Failed to get blitter program.\n");
- return dst_location;
- }
- GL_EXTCALL(glUseProgram(program->id));
- switch (get_complex_fixup(program->args.fixup))
- {
- case COMPLEX_FIXUP_P8:
- glsl_blitter_upload_palette(glsl_blitter, context, src_texture);
- break;
-
- case COMPLEX_FIXUP_YUY2:
- case COMPLEX_FIXUP_UYVY:
- case COMPLEX_FIXUP_YV12:
- case COMPLEX_FIXUP_NV12:
- src_level = src_sub_resource_idx % src_texture->level_count;
- location = GL_EXTCALL(glGetUniformLocation(program->id, "size"));
- GL_EXTCALL(glUniform2f(location, wined3d_texture_get_level_pow2_width(src_texture, src_level),
- wined3d_texture_get_level_pow2_height(src_texture, src_level)));
- break;
-
- default:
- break;
- }
- context_draw_shaded_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter);
- GL_EXTCALL(glUseProgram(0));
-
- if (dst_texture->swapchain && (dst_texture->swapchain->front_buffer == dst_texture))
- gl_info->gl_ops.gl.p_glFlush();
-
- if (staging_texture)
- wined3d_texture_decref(staging_texture);
-
- return dst_location;
-}
-
-static void glsl_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
- unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects,
- const RECT *draw_rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
-{
- struct wined3d_blitter *next;
-
- if ((next = blitter->next))
- next->ops->blitter_clear(next, device, rt_count, fb, rect_count,
- clear_rects, draw_rect, flags, color, depth, stencil);
-}
-
-static const struct wined3d_blitter_ops glsl_blitter_ops =
-{
- glsl_blitter_destroy,
- glsl_blitter_clear,
- glsl_blitter_blit,
-};
-
-struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next,
- const struct wined3d_device *device)
-{
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- struct wined3d_glsl_blitter *blitter;
-
- if (device->shader_backend != &glsl_shader_backend)
- return NULL;
-
- if (!gl_info->supported[ARB_VERTEX_SHADER] || !gl_info->supported[ARB_FRAGMENT_SHADER])
- return NULL;
-
- if (!(blitter = heap_alloc(sizeof(*blitter))))
- {
- ERR("Failed to allocate blitter.\n");
- return NULL;
- }
-
- TRACE("Created blitter %p.\n", blitter);
-
- blitter->blitter.ops = &glsl_blitter_ops;
- blitter->blitter.next = *next;
- string_buffer_list_init(&blitter->string_buffers);
- wine_rb_init(&blitter->programs, glsl_blitter_args_compare);
- blitter->palette_texture = 0;
- *next = &blitter->blitter;
-
- return *next;
-}
gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
break;
- default:
- FIXME("Unhandled target %#x.\n", state->textures[stage]->target);
- break;
}
}
else
return WINED3DERR_INVALIDCALL;
}
- if (!size)
- ERR("Attempting to create a zero-sized resource.\n");
-
for (i = 0; i < ARRAY_SIZE(resource_types); ++i)
{
if (resource_types[i].type != type
resource->parent_ops = parent_ops;
resource->resource_ops = resource_ops;
resource->map_binding = WINED3D_LOCATION_SYSMEM;
- resource->heap_memory = NULL;
+
+ if (size)
+ {
+ if (!wined3d_resource_allocate_sysmem(resource))
+ {
+ ERR("Failed to allocate system memory.\n");
+ return E_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ resource->heap_memory = NULL;
+ }
if (!(usage & WINED3DUSAGE_PRIVATE))
{
{
if (size > wined3d_device_get_available_texture_mem(device))
{
- ERR("Out of adapter memory.\n");
+ ERR("Out of adapter memory\n");
+ wined3d_resource_free_sysmem(resource);
return WINED3DERR_OUTOFVIDEOMEMORY;
}
adapter_adjust_memory(device->adapter, size);
struct wined3d_resource *resource = object;
wined3d_resource_free_sysmem(resource);
- context_resource_released(resource->device, resource);
+ context_resource_released(resource->device, resource, resource->type);
wined3d_resource_release(resource);
}
void *mem;
if (!(mem = heap_alloc_zero(resource->size + align)))
- {
- ERR("Failed to allocate system memory.\n");
return FALSE;
- }
p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1;
*p = mem;
}
}
-static enum wined3d_shader_type shader_get_shader_type(const struct wined3d_shader_desc *desc)
-{
- if (desc->format == WINED3D_SHADER_BYTE_CODE_FORMAT_SM4)
- return wined3d_get_sm4_shader_type(desc->byte_code, desc->byte_code_size);
-
- FIXME("Could not get shader type for byte code format %#x.\n", desc->format);
- return WINED3D_SHADER_TYPE_INVALID;
-}
-
void string_buffer_clear(struct wined3d_string_buffer *buffer)
{
buffer->buffer[0] = '\0';
reg_maps->vocp = 1;
break;
- case WINED3DSPR_SAMPLEMASK:
- reg_maps->sample_mask = 1;
- break;
-
default:
TRACE("Not recording register of type %#x and [%#x][%#x].\n",
reg->type, reg->idx[0].offset, reg->idx[1].offset);
register_idx * WINED3D_PACKED_INTERPOLATION_BIT_COUNT, WINED3D_PACKED_INTERPOLATION_BIT_COUNT, mode);
}
-static HRESULT shader_scan_output_signature(struct wined3d_shader *shader)
-{
- const struct wined3d_shader_signature *output_signature = &shader->output_signature;
- struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
- unsigned int i;
- HRESULT hr;
-
- for (i = 0; i < output_signature->element_count; ++i)
- {
- const struct wined3d_shader_signature_element *e = &output_signature->elements[i];
- unsigned int mask;
-
- reg_maps->output_registers |= 1u << e->register_idx;
- if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
- {
- if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask)))
- return hr;
- reg_maps->clip_distance_mask |= mask;
- }
- else if (e->sysval_semantic == WINED3D_SV_CULL_DISTANCE)
- {
- if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask)))
- return hr;
- reg_maps->cull_distance_mask |= mask;
- }
- else if (e->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX)
- {
- reg_maps->viewport_array = 1;
- }
- }
-
- return WINED3D_OK;
-}
-
/* Note that this does not count the loop register as an address register. */
-static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size)
+static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe,
+ struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature,
+ struct wined3d_shader_signature *output_signature, DWORD constf_size)
{
struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT];
- struct wined3d_shader_signature *output_signature = &shader->output_signature;
- struct wined3d_shader_signature *input_signature = &shader->input_signature;
- struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
- const struct wined3d_shader_frontend *fe = shader->frontend;
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
struct wined3d_shader_version shader_version;
struct wined3d_shader_phase *phase = NULL;
shader_record_sample(reg_maps, ins.src[2].reg.idx[0].offset,
ins.src[3].reg.idx[0].offset, reg_maps->sampler_map.count);
}
- else if ((ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE)
- || (ins.handler_idx == WINED3DSIH_SAMPLE_INFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE))
+ else if (ins.handler_idx == WINED3DSIH_BUFINFO && ins.src[0].reg.type == WINED3DSPR_RESOURCE)
{
shader_record_sample(reg_maps, ins.src[0].reg.idx[0].offset,
WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count);
if (output_signature->elements)
{
- if (FAILED(hr = shader_scan_output_signature(shader)))
- return hr;
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ const struct wined3d_shader_signature_element *e = &output_signature->elements[i];
+ unsigned int mask;
+
+ reg_maps->output_registers |= 1u << e->register_idx;
+ if (e->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
+ {
+ if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask)))
+ return hr;
+ reg_maps->clip_distance_mask |= mask;
+ }
+ else if (e->sysval_semantic == WINED3D_SV_CULL_DISTANCE)
+ {
+ if (FAILED(hr = shader_calculate_clip_or_cull_distance_mask(e, &mask)))
+ return hr;
+ reg_maps->cull_distance_mask |= mask;
+ }
+ }
}
else if (reg_maps->output_registers)
{
shader_addline(buffer, "_unknown_flags(%#x)", sync_flags);
}
-static void shader_dump_precise_flags(struct wined3d_string_buffer *buffer, DWORD flags)
-{
- if (!(flags & WINED3DSI_PRECISE_XYZW))
- return;
-
- shader_addline(buffer, " [precise");
- if (flags != WINED3DSI_PRECISE_XYZW)
- {
- shader_addline(buffer, "(%s%s%s%s)",
- flags & WINED3DSI_PRECISE_X ? "x" : "",
- flags & WINED3DSI_PRECISE_Y ? "y" : "",
- flags & WINED3DSI_PRECISE_Z ? "z" : "",
- flags & WINED3DSI_PRECISE_W ? "w" : "");
- }
- shader_addline(buffer, "]");
-}
-
static void shader_dump_uav_flags(struct wined3d_string_buffer *buffer, DWORD uav_flags)
{
if (uav_flags & WINED3DSUF_GLOBALLY_COHERENT)
shader_addline(buffer, "null");
break;
- case WINED3DSPR_RASTERIZER:
- shader_addline(buffer, "rasterizer");
- break;
-
case WINED3DSPR_RESOURCE:
shader_addline(buffer, "t");
break;
{
shader_dump_sync_flags(&buffer, ins.flags);
}
- else
- {
- shader_dump_precise_flags(&buffer, ins.flags);
- }
if (wined3d_shader_instruction_has_texel_offset(&ins))
shader_addline(&buffer, "(%d,%d,%d)", ins.texel_offset.u, ins.texel_offset.v, ins.texel_offset.w);
static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_const_count,
enum wined3d_shader_type type, unsigned int max_version)
{
- const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
const struct wined3d_shader_frontend *fe;
- unsigned int backend_version;
HRESULT hr;
+ unsigned int backend_version;
+ const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
TRACE("shader %p, float_const_count %u, type %#x, max_version %u.\n",
shader, float_const_count, type, max_version);
shader_trace_init(fe, shader->frontend_data);
/* Second pass: figure out which registers are used, what the semantics are, etc. */
- if (FAILED(hr = shader_get_registers_used(shader, float_const_count)))
+ if (FAILED(hr = shader_get_registers_used(shader, fe, reg_maps, &shader->input_signature,
+ &shader->output_signature, float_const_count)))
return hr;
if (reg_maps->shader_version.type != type)
TRACE("byte_code %p, byte_code_size %#lx, format %#x, max_version %#x.\n",
desc->byte_code, (long)desc->byte_code_size, desc->format, desc->max_version);
+ if (!desc->byte_code)
+ return WINED3DERR_INVALIDCALL;
+
if (!(shader->frontend = shader_select_frontend(desc->format)))
{
FIXME("Unable to find frontend for shader.\n");
byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr);
}
- if (desc->byte_code && byte_code_size)
+ if (!(shader->function = heap_alloc(byte_code_size)))
{
- if (!(shader->function = heap_alloc(byte_code_size)))
- {
- shader_cleanup(shader);
- return E_OUTOFMEMORY;
- }
- memcpy(shader->function, desc->byte_code, byte_code_size);
- shader->functionLength = byte_code_size;
-
- if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version)))
- {
- WARN("Failed to set function, hr %#x.\n", hr);
- shader_cleanup(shader);
- return hr;
- }
+ shader_cleanup(shader);
+ return E_OUTOFMEMORY;
}
- else
- {
- shader->reg_maps.shader_version.type = type;
- shader->reg_maps.shader_version.major = 4;
- shader->reg_maps.shader_version.minor = 0;
- shader_set_limits(shader);
+ memcpy(shader->function, desc->byte_code, byte_code_size);
+ shader->functionLength = byte_code_size;
- if (FAILED(hr = shader_scan_output_signature(shader)))
- {
- shader_cleanup(shader);
- return hr;
- }
+ if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version)))
+ {
+ WARN("Failed to set function, hr %#x.\n", hr);
+ shader_cleanup(shader);
+ return hr;
}
shader->load_local_constsF = shader->lconst_inf_or_nan;
+ wined3d_cs_init_object(shader->device->cs, wined3d_shader_init_object, shader);
+
return hr;
}
const struct wined3d_shader_desc *desc, const struct wined3d_stream_output_desc *so_desc,
void *parent, const struct wined3d_parent_ops *parent_ops)
{
- struct wined3d_shader_desc shader_desc = *desc;
- struct wined3d_stream_output_element *elements;
- enum wined3d_shader_type shader_type;
+ struct wined3d_stream_output_element *elements = NULL;
HRESULT hr;
- if (so_desc)
- {
- shader_type = shader_get_shader_type(desc);
- switch (shader_type)
- {
- case WINED3D_SHADER_TYPE_VERTEX:
- shader_desc.byte_code = NULL;
- shader_desc.byte_code_size = 0;
- break;
- case WINED3D_SHADER_TYPE_DOMAIN:
- FIXME("Stream output not supported for %s.\n", debug_shader_type(shader_type));
- return E_NOTIMPL;
- default:
- break;
- }
- }
+ if (so_desc && !(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
+ return E_OUTOFMEMORY;
- if (FAILED(hr = shader_init(shader, device, &shader_desc, 0,
- WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops)))
+ if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_GEOMETRY, parent, parent_ops)))
+ {
+ heap_free(elements);
return hr;
+ }
if (so_desc)
{
- if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
- {
- shader_cleanup(shader);
- return E_OUTOFMEMORY;
- }
-
shader->u.gs.so_desc = *so_desc;
shader->u.gs.so_desc.elements = elements;
memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements));
args->output_count = pixel_shader ? pixel_shader->limits->packed_input : shader->limits->packed_output;
- if (!(args->primitive_type = shader->u.gs.input_type))
- args->primitive_type = d3d_primitive_type_from_gl(state->gl_primitive_type);
-
init_interpolation_compile_args(args->interpolation_mode, pixel_shader, gl_info);
}
switch (texture->target)
{
/* RECT textures are distinguished from 2D textures via np2_fixup */
- default:
+ case GL_TEXTURE_RECTANGLE_ARB:
+ case GL_TEXTURE_2D:
break;
case GL_TEXTURE_3D:
if (shader->reg_maps.shader_version.major >= 3)
{
if (position_transformed)
- args->vp_mode = WINED3D_VP_MODE_NONE;
+ args->vp_mode = pretransformed;
else if (use_vs(state))
- args->vp_mode = WINED3D_VP_MODE_SHADER;
+ args->vp_mode = vertexshader;
else
- args->vp_mode = WINED3D_VP_MODE_FF;
+ args->vp_mode = fixedfunction;
args->fog = WINED3D_FFP_PS_FOG_OFF;
}
else
{
- args->vp_mode = WINED3D_VP_MODE_SHADER;
+ args->vp_mode = vertexshader;
if (state->render_states[WINED3D_RS_FOGENABLE])
{
switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
- if (!desc->byte_code)
- return WINED3DERR_INVALIDCALL;
-
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
return hr;
}
- wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
-
TRACE("Created compute shader %p.\n", object);
*shader = object;
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
- if (!desc->byte_code)
- return WINED3DERR_INVALIDCALL;
-
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
return hr;
}
- wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
-
TRACE("Created domain shader %p.\n", object);
*shader = object;
TRACE("device %p, desc %p, so_desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, so_desc, parent, parent_ops, shader);
- if (!desc->byte_code)
- return WINED3DERR_INVALIDCALL;
-
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
return hr;
}
- wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
-
TRACE("Created geometry shader %p.\n", object);
*shader = object;
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
- if (!desc->byte_code)
- return WINED3DERR_INVALIDCALL;
-
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
return hr;
}
- wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
-
TRACE("Created hull shader %p.\n", object);
*shader = object;
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
- if (!desc->byte_code)
- return WINED3DERR_INVALIDCALL;
-
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
return hr;
}
- wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
-
TRACE("Created pixel shader %p.\n", object);
*shader = object;
TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
device, desc, parent, parent_ops, shader);
- if (!desc->byte_code)
- return WINED3DERR_INVALIDCALL;
-
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
return hr;
}
- wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
-
TRACE("Created vertex shader %p.\n", object);
*shader = object;
#define WINED3D_SM4_GLOBAL_FLAGS_SHIFT 11
#define WINED3D_SM4_GLOBAL_FLAGS_MASK (0xffu << WINED3D_SM4_GLOBAL_FLAGS_SHIFT)
-#define WINED3D_SM5_PRECISE_SHIFT 19
-#define WINED3D_SM5_PRECISE_MASK (0xfu << WINED3D_SM5_PRECISE_SHIFT)
-
#define WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT 11
#define WINED3D_SM5_CONTROL_POINT_COUNT_MASK (0xffu << WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT)
WINED3D_SM4_RT_PRIMID = 0x0b,
WINED3D_SM4_RT_DEPTHOUT = 0x0c,
WINED3D_SM4_RT_NULL = 0x0d,
- WINED3D_SM4_RT_RASTERIZER = 0x0e,
WINED3D_SM4_RT_OMASK = 0x0f,
WINED3D_SM5_RT_STREAM = 0x10,
WINED3D_SM5_RT_FUNCTION_BODY = 0x11,
/* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID,
/* WINED3D_SM4_RT_DEPTHOUT */ WINED3DSPR_DEPTHOUT,
/* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL,
- /* WINED3D_SM4_RT_RASTERIZER */ WINED3DSPR_RASTERIZER,
+ /* UNKNOWN */ ~0u,
/* WINED3D_SM4_RT_OMASK */ WINED3DSPR_SAMPLEMASK,
/* WINED3D_SM5_RT_STREAM */ WINED3DSPR_STREAM,
/* WINED3D_SM5_RT_FUNCTION_BODY */ WINED3DSPR_FUNCTIONBODY,
}
}
-enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code, size_t byte_code_size)
-{
- DWORD shader_type;
-
- if (byte_code_size / sizeof(*byte_code) < 1)
- {
- WARN("Invalid byte code size %lu.\n", (long)byte_code_size);
- return WINED3D_SHADER_TYPE_INVALID;
- }
-
- shader_type = byte_code[0] >> 16;
- switch (shader_type)
- {
- case WINED3D_SM4_PS:
- return WINED3D_SHADER_TYPE_PIXEL;
- break;
- case WINED3D_SM4_VS:
- return WINED3D_SHADER_TYPE_VERTEX;
- break;
- case WINED3D_SM4_GS:
- return WINED3D_SHADER_TYPE_GEOMETRY;
- break;
- case WINED3D_SM5_HS:
- return WINED3D_SHADER_TYPE_HULL;
- break;
- case WINED3D_SM5_DS:
- return WINED3D_SHADER_TYPE_DOMAIN;
- break;
- case WINED3D_SM5_CS:
- return WINED3D_SHADER_TYPE_COMPUTE;
- break;
- default:
- FIXME("Unrecognised shader type %#x.\n", shader_type);
- return WINED3D_SHADER_TYPE_INVALID;
- }
-}
-
static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
const struct wined3d_shader_signature *output_signature)
{
priv->start = &byte_code[2];
priv->end = &byte_code[token_count];
- priv->shader_version.type = wined3d_get_sm4_shader_type(byte_code, byte_code_size);
- if (priv->shader_version.type == WINED3D_SHADER_TYPE_INVALID)
+ switch (version_token >> 16)
{
- heap_free(priv);
- return NULL;
- }
+ case WINED3D_SM4_PS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+ break;
+
+ case WINED3D_SM4_VS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+ break;
+
+ case WINED3D_SM4_GS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
+ break;
+ case WINED3D_SM5_HS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_HULL;
+ break;
+
+ case WINED3D_SM5_DS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_DOMAIN;
+ break;
+
+ case WINED3D_SM5_CS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_COMPUTE;
+ break;
+
+ default:
+ FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
+ }
priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
unsigned int i, len;
SIZE_T remaining;
const DWORD *p;
- DWORD precise;
list_move_head(&priv->src_free, &priv->src);
shader_sm4_read_instruction_modifier(previous_token = *p++, ins);
ins->flags = (opcode_token & WINED3D_SM4_INSTRUCTION_FLAGS_MASK) >> WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT;
+
if (ins->flags & WINED3D_SM4_INSTRUCTION_FLAG_SATURATE)
{
ins->flags &= ~WINED3D_SM4_INSTRUCTION_FLAG_SATURATE;
instruction_dst_modifier = WINED3DSPDM_SATURATE;
}
- precise = (opcode_token & WINED3D_SM5_PRECISE_MASK) >> WINED3D_SM5_PRECISE_SHIFT;
- ins->flags |= precise << WINED3DSI_PRECISE_SHIFT;
for (i = 0; i < ins->dst_count; ++i)
{
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
ULONG CDECL wined3d_blend_state_incref(struct wined3d_blend_state *state)
{
}
}
-static void state_stencilwrite2s_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
const struct wined3d_gl_info *gl_info = context->gl_info;
checkGLcall("depth bias");
}
+static void state_depthclip(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_DEPTHCLIP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
+ checkGLcall("glDisable(GL_DEPTH_CLAMP)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
+ checkGLcall("glEnable(GL_DEPTH_CLAMP)");
+ }
+}
+
+static void state_depthclip_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (!state->render_states[WINED3D_RS_DEPTHCLIP])
+ FIXME("Depth clamping not supported by GL.\n");
+}
+
static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (state->render_states[WINED3D_RS_ZVISIBLE])
checkGLcall("glLoadMatrixf");
}
+static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
+{
+ unsigned int texture_idx;
+
+ for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
+ {
+ GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+}
+
+static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
+ GLuint *curVBO, const struct wined3d_state *state)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int mapped_stage = 0;
+ unsigned int textureNo;
+
+ for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo)
+ {
+ int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
+
+ mapped_stage = context->tex_unit_map[textureNo];
+ if (mapped_stage == 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 (coordIdx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
+ {
+ const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
+
+ TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
+ textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
+
+ if (*curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ *curVBO = 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 (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
+ {
+ GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
+ }
+ }
+
+ checkGLcall("loadTexCoords");
+}
+
static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
*/
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
- context_unload_tex_coords(context);
- context_load_tex_coords(context, &context->stream_info, &curVBO, state);
+ unload_tex_coords(gl_info);
+ load_tex_coords(context, &context->stream_info, &curVBO, state);
}
}
static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
- unsigned int matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
+ UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum glMat;
+
+ TRACE("Setting world matrix %d\n", matrix);
+
+ if (matrix >= gl_info->limits.blends)
+ {
+ WARN("Unsupported blend matrix set\n");
+ return;
+ }
+
+ if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
+ return;
+
+ /* GL_MODELVIEW0_ARB: 0x1700
+ * GL_MODELVIEW1_ARB: 0x850a
+ * GL_MODELVIEW2_ARB: 0x8722
+ * GL_MODELVIEW3_ARB: 0x8723
+ * etc
+ * GL_MODELVIEW31_ARB: 0x873f
+ */
+ if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
+ else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
+
+ gl_info->gl_ops.gl.p_glMatrixMode(glMat);
+ checkGLcall("glMatrixMode(glMat)");
- WARN("Unsupported world matrix %u set.\n", matrix);
+ /* World matrix 0 is multiplied with the view matrix because d3d uses 3
+ * matrices while gl uses only 2. To avoid weighting the view matrix
+ * incorrectly it has to be multiplied into every GL modelview matrix. */
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11);
+ checkGLcall("glLoadMatrixf");
+ gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)]._11);
+ checkGLcall("glMultMatrixf");
}
static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
else WARN("Vertex blend flags %#x not supported.\n", f);
}
+static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_device *device = context->device;
+ static unsigned int once;
+
+ switch (val)
+ {
+ case WINED3D_VBF_1WEIGHTS:
+ case WINED3D_VBF_2WEIGHTS:
+ case WINED3D_VBF_3WEIGHTS:
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
+ checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
+
+ /* D3D adds one more matrix which has weight (1 - sum(weights)).
+ * This is enabled at context creation with enabling
+ * GL_WEIGHT_SUM_UNITY_ARB. */
+ GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
+
+ if (!device->vertexBlendUsed)
+ {
+ unsigned int i;
+ for (i = 1; i < gl_info->limits.blends; ++i)
+ {
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
+ transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
+ }
+ device->vertexBlendUsed = TRUE;
+ }
+ break;
+
+ case WINED3D_VBF_TWEENING:
+ case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
+ if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
+ else WARN("Vertex blend flags %#x not supported.\n", val);
+ /* Fall through. */
+ case WINED3D_VBF_DISABLE:
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
+ checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
+ break;
+ }
+}
+
static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
* No need to do it here if the state is scheduled for update. */
if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+
+ /* Avoid looping over a number of matrices if the app never used the functionality */
+ if (context->device->vertexBlendUsed)
+ {
+ for (k = 1; k < gl_info->limits.blends; ++k)
+ {
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
+ transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
+ }
+ }
}
static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
checkGLcall("glLoadMatrixf");
}
+/* This should match any arrays loaded in load_vertex_data.
+ * TODO: Only load / unload arrays if we have to. */
+static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
+{
+ 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);
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
+ unload_tex_coords(gl_info);
+}
+
+static inline void unload_numbered_array(struct wined3d_context *context, 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);
+}
+
+/* This should match any arrays loaded in loadNumberedArrays
+ * TODO: Only load / unload arrays if we have to. */
+static void unload_numbered_arrays(struct wined3d_context *context)
+{
+ /* disable any attribs (this is the same for both GLSL and ARB modes) */
+ int i;
+
+ for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
+ unload_numbered_array(context, i);
+ }
+}
+
+static void 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 curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+ unsigned int i;
+
+ /* Default to no instancing */
+ context->instance_count = 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))
+ 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))
+ unload_numbered_array(context, i);
+ continue;
+ }
+
+ TRACE_(d3d_shader)("Loading array %u [VBO=%u].\n", i, element->data.buffer_object);
+
+ if (element->stride)
+ {
+ if (curVBO != element->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ curVBO = 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
+ * curVBO 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))
+ unload_numbered_array(context, i);
+
+ 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");
+}
+
+static void 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;
+ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+ const struct wined3d_stream_info_element *e;
+
+ TRACE("Using fast vertex array code\n");
+
+ /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
+ context->instance_count = 0;
+
+ /* Blend Data ---------------------------------------------- */
+ if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT))
+ || si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
+ {
+ e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
+
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ TRACE("Blend %u %p %u\n", e->format->component_count,
+ e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
+
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
+ checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
+
+ GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ curVBO = e->data.buffer_object;
+ }
+
+ TRACE("glWeightPointerARB(%#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_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride));
+
+ checkGLcall("glWeightPointerARB");
+
+ if (si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
+ {
+ static BOOL warned;
+ if (!warned)
+ {
+ FIXME("blendMatrixIndices support\n");
+ warned = TRUE;
+ }
+ }
+ }
+ else
+ {
+ /* 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");
+ }
+ }
+ else
+ {
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ static const GLbyte one = 1;
+ GL_EXTCALL(glWeightbvARB(1, &one));
+ checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
+ }
+ }
+
+ /* Point Size ----------------------------------------------*/
+ if (si->use_map & (1u << WINED3D_FFP_PSIZE))
+ {
+ /* no such functionality in the fixed function GL pipeline */
+ TRACE("Cannot change ptSize here in openGl\n");
+ /* TODO: Implement this function in using shaders if they are available */
+ }
+
+ /* Vertex Pointers -----------------------------------------*/
+ if (si->use_map & (1u << WINED3D_FFP_POSITION))
+ {
+ e = &si->elements[WINED3D_FFP_POSITION];
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ curVBO = 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 (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ curVBO = 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 (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ curVBO = 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 (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
+ checkGLcall("glBindBuffer");
+ curVBO = 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 color pointers for type %x\n", type);
+ /* Make sure that the right color 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 coords -------------------------------------------*/
+ load_tex_coords(context, si, &curVBO, state);
+}
+
static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
- if (isStateDirty(context, STATE_VDECL))
- return;
- context_update_stream_sources(context, state);
+ BOOL load_numbered = context->d3d_info->ffp_generic_attributes
+ || (use_vs(state) && !context->use_immediate_mode_draw);
+ BOOL load_named = !context->d3d_info->ffp_generic_attributes
+ && !use_vs(state) && !context->use_immediate_mode_draw;
+
+ if (isStateDirty(context, STATE_VDECL)) return;
+ if (context->numberedArraysLoaded && !load_numbered)
+ {
+ unload_numbered_arrays(context);
+ context->numberedArraysLoaded = FALSE;
+ context->numbered_array_mask = 0;
+ }
+ else if (context->namedArraysLoaded)
+ {
+ unload_vertex_data(context->gl_info);
+ context->namedArraysLoaded = FALSE;
+ }
+
+ if (load_numbered)
+ {
+ TRACE("Loading numbered arrays\n");
+ load_numbered_arrays(context, &context->stream_info, state);
+ context->numberedArraysLoaded = TRUE;
+ }
+ else if (load_named)
+ {
+ TRACE("Loading vertex data\n");
+ load_vertex_data(context, &context->stream_info, state);
+ context->namedArraysLoaded = TRUE;
+ }
}
static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (isStateDirty(context, STATE_STREAMSRC))
return;
- context_update_stream_sources(context, state);
+ streamsrc(context, state, STATE_STREAMSRC);
}
static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
}
}
-static void get_viewports(struct wined3d_context *context, const struct wined3d_state *state,
- unsigned int viewport_count, struct wined3d_viewport *viewports)
+static void get_viewport(struct wined3d_context *context, const struct wined3d_state *state,
+ struct wined3d_viewport *viewport)
{
const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil;
const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
- unsigned int width, height, i;
+ unsigned int width, height;
- for (i = 0; i < viewport_count; ++i)
- viewports[i] = state->viewports[i];
+ *viewport = state->viewport;
+
+ if (target)
+ {
+ if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT)
+ {
+ if (viewport->width > target->width)
+ viewport->width = target->width;
+ if (viewport->height > target->height)
+ viewport->height = target->height;
+ }
+ }
- /* Note: GL uses a lower left origin while DirectX uses upper left. This
- * is reversed when using offscreen rendering. */
+ /*
+ * Note: GL requires lower left, DirectX supplies upper left. This is
+ * reversed when using offscreen rendering.
+ */
if (context->render_offscreen)
return;
return;
}
- for (i = 0; i < viewport_count; ++i)
- viewports[i].y = height - (viewports[i].y + viewports[i].height);
+ viewport->y = height - (viewport->y + viewport->height);
}
static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS];
-
- if (gl_info->supported[ARB_VIEWPORT_ARRAY])
- {
- GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS];
- GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS];
+ struct wined3d_viewport vp;
- unsigned int i, reset_count = 0;
+ get_viewport(context, state, &vp);
- get_viewports(context, state, state->viewport_count, vp);
- for (i = 0; i < state->viewport_count; ++i)
- {
- depth_ranges[i * 2] = vp[i].min_z;
- depth_ranges[i * 2 + 1] = vp[i].max_z;
-
- viewports[i * 4] = vp[i].x;
- viewports[i * 4 + 1] = vp[i].y;
- viewports[i * 4 + 2] = vp[i].width;
- viewports[i * 4 + 3] = vp[i].height;
- }
-
- if (context->viewport_count > state->viewport_count)
- reset_count = context->viewport_count - state->viewport_count;
-
- if (reset_count)
- {
- memset(&depth_ranges[state->viewport_count * 2], 0, reset_count * 2 * sizeof(*depth_ranges));
- memset(&viewports[state->viewport_count * 4], 0, reset_count * 4 * sizeof(*viewports));
- }
+ gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
- GL_EXTCALL(glDepthRangeArrayv(0, state->viewport_count + reset_count, depth_ranges));
- GL_EXTCALL(glViewportArrayv(0, state->viewport_count + reset_count, viewports));
- context->viewport_count = state->viewport_count;
- }
+ if (gl_info->supported[ARB_VIEWPORT_ARRAY])
+ GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height));
else
- {
- get_viewports(context, state, 1, vp);
- gl_info->gl_ops.gl.p_glDepthRange(vp[0].min_z, vp[0].max_z);
- gl_info->gl_ops.gl.p_glViewport(vp[0].x, vp[0].y, vp[0].width, vp[0].height);
- }
+ gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
checkGLcall("setting clip space and viewport");
}
float pixel_center_offset = context->d3d_info->wined3d_creation_flags
& WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f;
const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS];
- GLdouble depth_ranges[2 * WINED3D_MAX_VIEWPORTS];
- GLfloat viewports[4 * WINED3D_MAX_VIEWPORTS];
- unsigned int i, reset_count = 0;
-
- get_viewports(context, state, state->viewport_count, vp);
-
- GL_EXTCALL(glClipControl(context->render_offscreen ? GL_UPPER_LEFT : GL_LOWER_LEFT, GL_ZERO_TO_ONE));
-
- for (i = 0; i < state->viewport_count; ++i)
- {
- depth_ranges[i * 2] = vp[i].min_z;
- depth_ranges[i * 2 + 1] = vp[i].max_z;
-
- viewports[i * 4] = vp[i].x + pixel_center_offset;
- viewports[i * 4 + 1] = vp[i].y + pixel_center_offset;
- viewports[i * 4 + 2] = vp[i].width;
- viewports[i * 4 + 3] = vp[i].height;
- }
-
- if (context->viewport_count > state->viewport_count)
- reset_count = context->viewport_count - state->viewport_count;
+ struct wined3d_viewport vp;
- if (reset_count)
- {
- memset(&depth_ranges[state->viewport_count * 2], 0, reset_count * 2 * sizeof(*depth_ranges));
- memset(&viewports[state->viewport_count * 4], 0, reset_count * 4 * sizeof(*viewports));
- }
+ get_viewport(context, state, &vp);
+ vp.x += pixel_center_offset;
+ vp.y += pixel_center_offset;
- GL_EXTCALL(glDepthRangeArrayv(0, state->viewport_count + reset_count, depth_ranges));
- GL_EXTCALL(glViewportArrayv(0, state->viewport_count + reset_count, viewports));
- context->viewport_count = state->viewport_count;
+ gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
+ GL_EXTCALL(glClipControl(context->render_offscreen ? GL_UPPER_LEFT : GL_LOWER_LEFT, GL_ZERO_TO_ONE));
+ GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height));
checkGLcall("setting clip space and viewport");
}
static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- unsigned int height = 0;
- const RECT *r;
+ const RECT *r = &state->scissor_rect;
/* Warning: glScissor uses window coordinates, not viewport coordinates,
* so our viewport correction does not apply. Warning2: Even in windowed
* mode the coords are relative to the window, not the screen. */
+ TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
- if (!context->render_offscreen)
- {
- const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
- unsigned int width;
-
- wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
- }
-
- if (gl_info->supported[ARB_VIEWPORT_ARRAY])
+ if (context->render_offscreen)
{
- GLint sr[4 * WINED3D_MAX_VIEWPORTS];
- unsigned int i, reset_count = 0;
-
- for (i = 0; i < state->scissor_rect_count; ++i)
- {
- r = &state->scissor_rects[i];
-
- sr[i * 4] = r->left;
- sr[i * 4 + 1] = height ? height - r->top : r->top;
- sr[i * 4 + 2] = r->right - r->left;
- sr[i * 4 + 3] = r->bottom - r->top;
- }
-
- if (context->scissor_rect_count > state->scissor_rect_count)
- reset_count = context->scissor_rect_count - state->scissor_rect_count;
-
- if (reset_count)
- memset(&sr[state->scissor_rect_count * 4], 0, reset_count * 4 * sizeof(GLint));
-
- GL_EXTCALL(glScissorArrayv(0, state->scissor_rect_count + reset_count, sr));
- checkGLcall("glScissorArrayv");
- context->scissor_rect_count = state->scissor_rect_count;
+ gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
}
else
{
- r = &state->scissor_rects[0];
- gl_info->gl_ops.gl.p_glScissor(r->left, height ? height - r->top : r->top,
- r->right - r->left, r->bottom - r->top);
- checkGLcall("glScissor");
+ const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
+ UINT height;
+ UINT width;
+
+ wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
+ gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
}
+ checkGLcall("glScissor");
}
static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
}
}
-static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info)
-{
- if (!gl_info->supported[ARB_DEPTH_CLAMP])
- {
- if (r && !r->desc.depth_clip)
- FIXME("Depth clamp not supported by this GL implementation.\n");
- return;
- }
-
- if (r && !r->desc.depth_clip)
- gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
- else
- gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
- checkGLcall("depth clip");
-}
-
-static void rasterizer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum mode;
gl_info->gl_ops.gl.p_glFrontFace(mode);
checkGLcall("glFrontFace");
- depth_clip(state->rasterizer_state, gl_info);
}
-static void rasterizer_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void frontface_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum mode;
gl_info->gl_ops.gl.p_glFrontFace(mode);
checkGLcall("glFrontFace");
- depth_clip(state->rasterizer_state, gl_info);
}
static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{ STATE_BLEND, { STATE_BLEND, state_blend_object }, WINED3D_GL_EXT_NONE },
{ STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
{ STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
- { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer_cc }, ARB_CLIP_CONTROL },
- { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer }, WINED3D_GL_EXT_NONE },
+ { STATE_FRONTFACE, { STATE_FRONTFACE, frontface_cc }, ARB_CLIP_CONTROL },
+ { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
{ STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
{ STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, state_nop }, ARB_CLIP_CONTROL },
{ STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
{ STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s_ext}, EXT_STENCIL_TWO_SIDE },
+ { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
{ STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_DEPTHBIASCLAMP), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip }, ARB_DEPTH_CLAMP },
+ { STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip_w }, WINED3D_GL_EXT_NONE },
/* Samplers */
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
{ STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
caps->xyzrhw = FALSE;
caps->ffp_generic_attributes = FALSE;
caps->max_active_lights = gl_info->limits.lights;
- caps->max_vertex_blend_matrices = 1;
+ caps->max_vertex_blend_matrices = gl_info->limits.blends;
caps->max_vertex_blend_matrix_index = 0;
caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
| WINED3DVTXPCAPS_MATERIALSOURCE7
STATE_VIEWPORT,
STATE_LIGHT_TYPE,
STATE_SCISSORRECT,
- STATE_RASTERIZER,
+ STATE_FRONTFACE,
STATE_POINTSPRITECOORDORIGIN,
STATE_BASEVERTEXINDEX,
STATE_FRAMEBUFFER,
WINED3D_RS_ZENABLE,
WINED3D_RS_ZFUNC,
WINED3D_RS_ZWRITEENABLE,
+ WINED3D_RS_DEPTHCLIP,
};
static const DWORD pixel_states_texture[] =
stateblock->state.material = src_state->material;
}
- assert(src_state->viewport_count <= 1);
-
if (stateblock->changed.viewport
- && (src_state->viewport_count != stateblock->state.viewport_count
- || memcmp(src_state->viewports, stateblock->state.viewports,
- src_state->viewport_count * sizeof(*stateblock->state.viewports))))
+ && memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport)))
{
- TRACE("Updating viewports.\n");
+ TRACE("Updating viewport.\n");
- if ((stateblock->state.viewport_count = src_state->viewport_count))
- memcpy(stateblock->state.viewports, src_state->viewports, sizeof(src_state->viewports));
- else
- memset(stateblock->state.viewports, 0, sizeof(*stateblock->state.viewports));
+ stateblock->state.viewport = src_state->viewport;
}
- if (stateblock->changed.scissorRect
- && (src_state->scissor_rect_count != stateblock->state.scissor_rect_count
- || memcmp(src_state->scissor_rects, stateblock->state.scissor_rects,
- src_state->scissor_rect_count * sizeof(*stateblock->state.scissor_rects))))
+ if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect,
+ &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect)))
{
- TRACE("Updating scissor rects.\n");
+ TRACE("Updating scissor rect.\n");
- if ((stateblock->state.scissor_rect_count = src_state->scissor_rect_count))
- memcpy(stateblock->state.scissor_rects, src_state->scissor_rects,
- src_state->scissor_rect_count * sizeof(*src_state->scissor_rects));
- else
- SetRectEmpty(stateblock->state.scissor_rects);
+ stateblock->state.scissor_rect = src_state->scissor_rect;
}
map = stateblock->changed.streamSource;
wined3d_device_set_material(device, &stateblock->state.material);
if (stateblock->changed.viewport)
- wined3d_device_set_viewports(device, stateblock->state.viewport_count, stateblock->state.viewports);
+ wined3d_device_set_viewport(device, &stateblock->state.viewport);
if (stateblock->changed.scissorRect)
- wined3d_device_set_scissor_rects(device, stateblock->state.scissor_rect_count,
- stateblock->state.scissor_rects);
+ wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect);
map = stateblock->changed.streamSource;
for (i = 0; map; map >>= 1, ++i)
state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
tmpfloat.f = 0.0f;
state->render_states[WINED3D_RS_DEPTHBIASCLAMP] = tmpfloat.d;
+ state->render_states[WINED3D_RS_DEPTHCLIP] = TRUE;
state->render_states[WINED3D_RS_WRAP8] = 0;
state->render_states[WINED3D_RS_WRAP9] = 0;
state->render_states[WINED3D_RS_WRAP10] = 0;
static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM
| WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER;
+struct blt_info
+{
+ GLenum binding;
+ GLenum bind_target;
+ enum wined3d_gl_resource_type tex_type;
+ struct wined3d_vec3 texcoords[4];
+};
+
+struct float_rect
+{
+ float l;
+ float t;
+ float r;
+ float b;
+};
+
+static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f)
+{
+ f->l = ((r->left * 2.0f) / w) - 1.0f;
+ f->t = ((r->top * 2.0f) / h) - 1.0f;
+ f->r = ((r->right * 2.0f) / w) - 1.0f;
+ f->b = ((r->bottom * 2.0f) / h) - 1.0f;
+}
+
+static void texture2d_get_blt_info(const struct wined3d_texture *texture,
+ unsigned int sub_resource_idx, const RECT *rect, struct blt_info *info)
+{
+ struct wined3d_vec3 *coords = info->texcoords;
+ struct float_rect f;
+ unsigned int level;
+ GLenum target;
+ GLsizei w, h;
+
+ level = sub_resource_idx % texture->level_count;
+ w = wined3d_texture_get_level_pow2_width(texture, level);
+ h = wined3d_texture_get_level_pow2_height(texture, level);
+ target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+
+ switch (target)
+ {
+ default:
+ FIXME("Unsupported texture target %#x.\n", target);
+ /* Fall back to GL_TEXTURE_2D */
+ case GL_TEXTURE_2D:
+ info->binding = GL_TEXTURE_BINDING_2D;
+ info->bind_target = GL_TEXTURE_2D;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_2D;
+ coords[0].x = (float)rect->left / w;
+ coords[0].y = (float)rect->top / h;
+ coords[0].z = 0.0f;
+
+ coords[1].x = (float)rect->right / w;
+ coords[1].y = (float)rect->top / h;
+ coords[1].z = 0.0f;
+
+ coords[2].x = (float)rect->left / w;
+ coords[2].y = (float)rect->bottom / h;
+ coords[2].z = 0.0f;
+
+ coords[3].x = (float)rect->right / w;
+ coords[3].y = (float)rect->bottom / h;
+ coords[3].z = 0.0f;
+ break;
+
+ case GL_TEXTURE_RECTANGLE_ARB:
+ info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
+ info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_RECT;
+ coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f;
+ coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f;
+ coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f;
+ coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l;
+ coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r;
+ coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l;
+ coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l;
+ coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r;
+ coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l;
+ coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t;
+ coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t;
+ coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b;
+ coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t;
+ coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t;
+ coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b;
+ coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f;
+ coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f;
+ coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f;
+ coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f;
+ coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f;
+ coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f;
+ coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f;
+ break;
+ }
+}
+
+/* Context activation is done by the caller. */
+void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ struct wined3d_context *context, 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 blt_info info;
+
+ 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)");
+
+ context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
+
+ /* Filtering for StretchRect */
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
+ checkGLcall("glTexParameteri");
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER,
+ wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
+ checkGLcall("glTexParameteri");
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+ 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();
+
+ /* Unbind the texture */
+ context_bind_texture(context, info.bind_target, 0);
+
+ /* We changed the filtering settings on the texture. Inform the
+ * container about this to get the filters reset properly next draw. */
+ texture->texture_rgb.sampler_desc.mag_filter = WINED3D_TEXF_POINT;
+ texture->texture_rgb.sampler_desc.min_filter = WINED3D_TEXF_POINT;
+ texture->texture_rgb.sampler_desc.mip_filter = WINED3D_TEXF_NONE;
+ texture->texture_rgb.sampler_desc.srgb_decode = FALSE;
+}
+
/* Works correctly only for <= 4 bpp formats. */
static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
{
return TRUE;
}
-static void texture2d_depth_blt_fbo(const struct wined3d_device *device, 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)
+static void surface_depth_blt_fbo(const struct wined3d_device *device,
+ 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_gl_info *gl_info = context->gl_info;
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ struct wined3d_texture *dst_texture = dst_surface->container;
+ struct wined3d_texture *src_texture = src_surface->container;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
DWORD src_mask, dst_mask;
GLbitfield gl_mask;
- TRACE("device %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.\n", device,
- 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));
+ TRACE("device %p\n", device);
+ TRACE("src_surface %p, src_location %s, src_rect %s,\n",
+ src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect));
+ TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n",
+ dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect));
src_mask = src_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
dst_mask = dst_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
if (src_mask & WINED3DFMT_FLAG_STENCIL)
gl_mask |= GL_STENCIL_BUFFER_BIT;
+ context = context_acquire(device, NULL, 0);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping blit.\n");
+ return;
+ }
+
/* Make sure the locations are up-to-date. Loading the destination
* surface isn't required if the entire surface is overwritten. */
wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location);
else
wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
- context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, 0,
- &src_texture->resource, src_sub_resource_idx, src_location);
+ gl_info = context->gl_info;
+
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, src_location);
context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
- context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, 0,
- &dst_texture->resource, dst_sub_resource_idx, dst_location);
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, dst_surface, dst_location);
context_set_draw_buffer(context, GL_NONE);
context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
context_invalidate_state(context, STATE_FRAMEBUFFER);
gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom,
dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST);
checkGLcall("glBlitFramebuffer()");
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
}
static BOOL is_multisample_location(const struct wined3d_texture *texture, DWORD location)
/* Blit between surface locations. Onscreen on different swapchains is not supported.
* Depth / stencil is not supported. Context activation is done by the caller. */
-static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3d_context *context,
- enum wined3d_texture_filter_type filter, 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_texture *required_texture, *restore_texture;
- unsigned int required_idx, restore_idx;
+static void surface_blt_fbo(const struct wined3d_device *device,
+ struct wined3d_context *old_ctx, enum wined3d_texture_filter_type filter,
+ struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect_in,
+ struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect_in)
+{
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ struct wined3d_texture *dst_texture = dst_surface->container;
+ struct wined3d_texture *src_texture = src_surface->container;
const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *required_rt, *restore_rt = NULL;
+ RECT src_rect, dst_rect;
GLenum gl_filter;
GLenum buffer;
- RECT s, d;
int i;
- TRACE("device %p, context %p, filter %s, 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.\n",
- device, context, debug_d3dtexturefiltertype(filter), 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));
+ TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter));
+ TRACE("src_surface %p, src_location %s, src_rect %s,\n",
+ src_surface, wined3d_debug_location(src_location), wine_dbgstr_rect(src_rect_in));
+ TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n",
+ dst_surface, wined3d_debug_location(dst_location), wine_dbgstr_rect(dst_rect_in));
+
+ src_rect = *src_rect_in;
+ dst_rect = *dst_rect_in;
switch (filter)
{
/* Resolve the source surface first if needed. */
if (is_multisample_location(src_texture, src_location)
&& (src_texture->resource.format->id != dst_texture->resource.format->id
- || abs(src_rect->bottom - src_rect->top) != abs(dst_rect->bottom - dst_rect->top)
- || abs(src_rect->right - src_rect->left) != abs(dst_rect->right - dst_rect->left)))
+ || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top)
+ || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left)))
src_location = WINED3D_LOCATION_RB_RESOLVED;
/* Make sure the locations are up-to-date. Loading the destination
* surface isn't required if the entire surface is overwritten. (And is
* in fact harmful if we're being called by surface_load_location() with
* the purpose of loading the destination surface.) */
- wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, src_location);
- if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, dst_rect))
- wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
+ wined3d_texture_load_location(src_texture, src_sub_resource_idx, old_ctx, src_location);
+ if (!texture2d_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, &dst_rect))
+ wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location);
else
- wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
+ wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, old_ctx, dst_location);
- if (src_location == WINED3D_LOCATION_DRAWABLE)
- {
- required_texture = src_texture;
- required_idx = src_sub_resource_idx;
- }
- else if (dst_location == WINED3D_LOCATION_DRAWABLE)
- {
- required_texture = dst_texture;
- required_idx = dst_sub_resource_idx;
- }
- else
- {
- required_texture = NULL;
- required_idx = 0;
- }
+ if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface;
+ else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface;
+ else required_rt = NULL;
- restore_texture = context->current_rt.texture;
- restore_idx = context->current_rt.sub_resource_idx;
- if (restore_texture != required_texture || restore_idx != required_idx)
- context = context_acquire(device, required_texture, required_idx);
+ restore_rt = context_get_rt_surface(old_ctx);
+ if (restore_rt != required_rt)
+ context = context_acquire(device, required_rt ? required_rt->container : NULL,
+ required_rt ? surface_get_sub_resource_idx(required_rt) : 0);
else
- restore_texture = NULL;
+ restore_rt = NULL;
if (!context->valid)
{
if (src_location == WINED3D_LOCATION_DRAWABLE)
{
- TRACE("Source texture %p is onscreen.\n", src_texture);
+ TRACE("Source surface %p is onscreen.\n", src_surface);
buffer = wined3d_texture_get_gl_buffer(src_texture);
- s = *src_rect;
- wined3d_texture_translate_drawable_coords(src_texture, context->win_handle, &s);
- src_rect = &s;
+ surface_translate_drawable_coords(src_surface, context->win_handle, &src_rect);
}
else
{
- TRACE("Source texture %p is offscreen.\n", src_texture);
+ TRACE("Source surface %p is offscreen.\n", src_surface);
buffer = GL_COLOR_ATTACHMENT0;
}
- context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER,
- &src_texture->resource, src_sub_resource_idx, NULL, 0, src_location);
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL, src_location);
gl_info->gl_ops.gl.p_glReadBuffer(buffer);
checkGLcall("glReadBuffer()");
context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
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);
- d = *dst_rect;
- wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &d);
- dst_rect = &d;
+ surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect);
}
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);
gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
- gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom,
- dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, GL_COLOR_BUFFER_BIT, gl_filter);
+ gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
+ dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter);
checkGLcall("glBlitFramebuffer()");
- if (dst_location == WINED3D_LOCATION_DRAWABLE && dst_texture->swapchain->front_buffer == dst_texture)
+ if (wined3d_settings.strict_draw_ordering || (dst_location == WINED3D_LOCATION_DRAWABLE
+ && dst_texture->swapchain->front_buffer == dst_texture))
gl_info->gl_ops.gl.p_glFlush();
- if (restore_texture)
- context_restore(context, restore_texture, restore_idx);
+ if (restore_rt)
+ context_restore(context, restore_rt);
}
static BOOL fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct wined3d_gl_info *gl_info,
if (!(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
return FALSE;
- if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
- return FALSE;
-
switch (blit_op)
{
case WINED3D_BLIT_OP_COLOR_BLIT:
/* This call just downloads data, the caller is responsible for binding the
* correct texture. */
/* Context activation is done by the caller. */
-static void texture2d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- const struct wined3d_context *context, DWORD dst_location)
+static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+ DWORD dst_location)
{
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
+ struct wined3d_texture *texture = surface->container;
const struct wined3d_format *format = texture->resource.format;
- const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_texture_sub_resource *sub_resource;
unsigned int dst_row_pitch, dst_slice_pitch;
unsigned int src_row_pitch, src_slice_pitch;
GLenum target;
void *mem;
- /* Only support read back of converted P8 textures. */
+ /* Only support read back of converted P8 surfaces. */
if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT && !format->download)
{
- ERR("Trying to read back converted texture %p, %u with format %s.\n",
- texture, sub_resource_idx, debug_d3dformat(format->id));
+ ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id));
return;
}
if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
ERR("Array texture %p uses NP2 emulation.\n", texture);
- WARN_(d3d_perf)("Downloading all miplevel layers to get the data for a single sub-resource.\n");
+ WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n");
if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size)))
{
if (data.buffer_object)
ERR("Converted texture %p uses PBO unexpectedly.\n", texture);
- WARN_(d3d_perf)("Downloading converted texture %p, %u with format %s.\n",
- texture, sub_resource_idx, debug_d3dformat(format->id));
+ WARN_(d3d_perf)("Downloading converted surface %p with format %s.\n", surface, debug_d3dformat(format->id));
f = *format;
f.byte_count = format->conv_byte_count;
if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED)
{
- TRACE("Downloading compressed texture %p, %u, level %u, format %#x, type %#x, data %p.\n",
- texture, sub_resource_idx, level, format->glFormat, format->glType, mem);
+ TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n",
+ surface, level, format->glFormat, format->glType, mem);
GL_EXTCALL(glGetCompressedTexImage(target, level, mem));
checkGLcall("glGetCompressedTexImage");
}
else
{
- TRACE("Downloading texture %p, %u, level %u, format %#x, type %#x, data %p.\n",
- texture, sub_resource_idx, level, format->glFormat, format->glType, mem);
+ TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n",
+ surface, level, format->glFormat, format->glType, mem);
gl_info->gl_ops.gl.p_glGetTexImage(target, level, format->glFormat, format->glType, mem);
checkGLcall("glGetTexImage");
heap_free(temporary_mem);
}
+/* This call just uploads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
+void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point,
+ BOOL srgb, const struct wined3d_const_bo_address *data)
+{
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
+ struct wined3d_texture *texture = surface->container;
+ UINT update_w = src_rect->right - src_rect->left;
+ UINT update_h = src_rect->bottom - src_rect->top;
+ unsigned int level, layer;
+ GLenum target;
+
+ TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_pitch %u, dst_point %s, srgb %#x, data {%#x:%p}.\n",
+ surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch,
+ wine_dbgstr_point(dst_point), srgb, data->buffer_object, data->addr);
+
+ if (texture->sub_resources[sub_resource_idx].map_count)
+ {
+ WARN("Uploading a surface that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n");
+ texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
+ }
+
+ if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE)
+ {
+ update_h *= format->height_scale.numerator;
+ update_h /= format->height_scale.denominator;
+ }
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+ checkGLcall("glBindBuffer");
+ }
+
+ target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+ level = sub_resource_idx % texture->level_count;
+ layer = sub_resource_idx / texture->level_count;
+
+ if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ unsigned int dst_row_pitch, dst_slice_pitch;
+ const BYTE *addr = data->addr;
+ GLenum internal;
+
+ addr += (src_rect->top / format->block_height) * src_pitch;
+ addr += (src_rect->left / format->block_width) * format->block_byte_count;
+
+ if (srgb)
+ internal = format->glGammaInternal;
+ else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
+ && wined3d_resource_is_offscreen(&texture->resource))
+ internal = format->rtInternal;
+ else
+ internal = format->glInternal;
+
+ wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
+
+ TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
+ "format %#x, image_size %#x, addr %p.\n",
+ target, level, layer, dst_point->x, dst_point->y,
+ update_w, update_h, internal, dst_slice_pitch, addr);
+
+ if (dst_row_pitch == src_pitch)
+ {
+ if (target == GL_TEXTURE_2D_ARRAY)
+ {
+ GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, dst_point->y,
+ layer, update_w, update_h, 1, internal, dst_slice_pitch, addr));
+ }
+ else
+ {
+ GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, dst_point->y,
+ update_w, update_h, internal, dst_slice_pitch, addr));
+ }
+ }
+ else
+ {
+ UINT row_count = (update_h + format->block_height - 1) / format->block_height;
+ UINT row, y;
+
+ /* glCompressedTexSubImage2D() ignores pixel store state, so we
+ * can't use the unpack row length like for glTexSubImage2D. */
+ for (row = 0, y = dst_point->y; row < row_count; ++row)
+ {
+ if (target == GL_TEXTURE_2D_ARRAY)
+ {
+ GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_point->x, y,
+ layer, update_w, format->block_height, 1, internal, dst_row_pitch, addr));
+ }
+ else
+ {
+ GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_point->x, y,
+ update_w, format->block_height, internal, dst_row_pitch, addr));
+ }
+
+ y += format->block_height;
+ addr += src_pitch;
+ }
+ }
+ checkGLcall("Upload compressed surface data");
+ }
+ else
+ {
+ const BYTE *addr = data->addr;
+
+ addr += src_rect->top * src_pitch;
+ addr += src_rect->left * format->byte_count;
+
+ TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
+ "format %#x, type %#x, addr %p.\n",
+ target, level, layer, dst_point->x, dst_point->y,
+ update_w, update_h, format->glFormat, format->glType, addr);
+
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count);
+ if (target == GL_TEXTURE_2D_ARRAY)
+ {
+ GL_EXTCALL(glTexSubImage3D(target, level, dst_point->x, dst_point->y,
+ layer, update_w, update_h, 1, format->glFormat, format->glType, addr));
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_point->x, dst_point->y,
+ update_w, update_h, format->glFormat, format->glType, addr);
+ }
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ checkGLcall("Upload surface data");
+ }
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+ checkGLcall("glBindBuffer");
+ }
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush();
+
+ if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE)
+ {
+ struct wined3d_device *device = texture->resource.device;
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context_surface_update(device->contexts[i], surface);
+ }
+ }
+}
+
+static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
+ struct wined3d_surface *src_surface, const RECT *src_rect)
+{
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
+ struct wined3d_texture *src_texture = src_surface->container;
+ struct wined3d_texture *dst_texture = dst_surface->container;
+ unsigned int src_row_pitch, src_slice_pitch;
+ const struct wined3d_gl_info *gl_info;
+ unsigned int src_level, dst_level;
+ struct wined3d_context *context;
+ struct wined3d_bo_address data;
+ UINT update_w, update_h;
+
+ TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n",
+ dst_surface, wine_dbgstr_point(dst_point),
+ src_surface, wine_dbgstr_rect(src_rect));
+
+ context = context_acquire(dst_texture->resource.device, NULL, 0);
+ gl_info = context->gl_info;
+
+ /* Only load the surface for partial updates. For newly allocated texture
+ * the texture wouldn't be the current location, and we'd upload zeroes
+ * just to overwrite them again. */
+ update_w = src_rect->right - src_rect->left;
+ update_h = src_rect->bottom - src_rect->top;
+ dst_level = dst_sub_resource_idx % dst_texture->level_count;
+ if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level)
+ && update_h == wined3d_texture_get_level_height(dst_texture, dst_level))
+ wined3d_texture_prepare_texture(dst_texture, context, FALSE);
+ else
+ wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
+
+ src_level = src_sub_resource_idx % src_texture->level_count;
+ wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data,
+ src_texture->sub_resources[src_sub_resource_idx].locations);
+ wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch);
+
+ wined3d_surface_upload_data(dst_surface, gl_info, src_texture->resource.format, src_rect,
+ src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
+
+ context_release(context);
+
+ wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
+
+ return WINED3D_OK;
+}
+
+/* In D3D the depth stencil dimensions have to be greater than or equal to the
+ * render target dimensions. With FBOs, the dimensions have to be an exact match. */
+/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
+/* Context activation is done by the caller. */
+void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt)
+{
+ unsigned int sub_resource_idx, width, height, level;
+ struct wined3d_renderbuffer_entry *entry;
+ const struct wined3d_texture *texture;
+ const struct wined3d_gl_info *gl_info;
+ unsigned int src_width, src_height;
+ GLuint renderbuffer = 0;
+
+ texture = surface->container;
+ gl_info = &texture->resource.device->adapter->gl_info;
+ sub_resource_idx = surface_get_sub_resource_idx(surface);
+ level = sub_resource_idx % texture->level_count;
+
+ if (rt && rt->resource->format->id != WINED3DFMT_NULL)
+ {
+ struct wined3d_texture *rt_texture;
+ unsigned int rt_level;
+
+ if (rt->resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
+ return;
+ }
+ rt_texture = wined3d_texture_from_resource(rt->resource);
+ rt_level = rt->sub_resource_idx % rt_texture->level_count;
+
+ width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level);
+ height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level);
+ }
+ else
+ {
+ width = wined3d_texture_get_level_pow2_width(texture, level);
+ height = wined3d_texture_get_level_pow2_height(texture, level);
+ }
+
+ src_width = wined3d_texture_get_level_pow2_width(texture, level);
+ src_height = wined3d_texture_get_level_pow2_height(texture, level);
+
+ /* A depth stencil smaller than the render target is not valid */
+ if (width > src_width || height > src_height) return;
+
+ /* Remove any renderbuffer set if the sizes match */
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
+ || (width == src_width && height == src_height))
+ {
+ surface->current_renderbuffer = NULL;
+ return;
+ }
+
+ /* Look if we've already got a renderbuffer of the correct dimensions */
+ LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ if (entry->width == width && entry->height == height)
+ {
+ renderbuffer = entry->id;
+ surface->current_renderbuffer = entry;
+ break;
+ }
+ }
+
+ if (!renderbuffer)
+ {
+ gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
+ texture->resource.format->glInternal, width, height);
+
+ entry = heap_alloc(sizeof(*entry));
+ entry->width = width;
+ entry->height = height;
+ entry->id = renderbuffer;
+ list_add_head(&surface->renderbuffers, &entry->entry);
+
+ surface->current_renderbuffer = entry;
+ }
+
+ checkGLcall("set_compatible_renderbuffer");
+}
+
/* See also float_16_to_32() in wined3d_private.h */
static inline unsigned short float_32_to_16(const float *in)
{
const struct wined3d_format *src_format = src_texture->resource.format;
struct wined3d_device *device = src_texture->resource.device;
const struct d3dfmt_converter_desc *conv = NULL;
+ const struct wined3d_gl_info *gl_info = NULL;
unsigned int src_row_pitch, src_slice_pitch;
struct wined3d_context *context = NULL;
struct wined3d_texture *dst_texture;
}
if (device->d3d_initialized)
+ {
context = context_acquire(device, NULL, 0);
+ gl_info = context->gl_info;
+ }
map_binding = src_texture->resource.map_binding;
if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding))
}
else
{
- struct wined3d_box src_box = {0, 0, desc.width, desc.height, 0, 1};
+ RECT src_rect = {0, 0, desc.width, desc.height};
+ POINT dst_point = {0, 0};
TRACE("Using upload conversion.\n");
wined3d_texture_prepare_texture(dst_texture, context, FALSE);
wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
- wined3d_texture_upload_data(dst_texture, 0, context, src_format, &src_box,
- wined3d_const_bo_address(&src_data), src_row_pitch, src_slice_pitch, 0, 0, 0, FALSE);
+ wined3d_surface_upload_data(dst_texture->sub_resources[0].u.surface, gl_info, src_format,
+ &src_rect, src_row_pitch, &dst_point, FALSE, wined3d_const_bo_address(&src_data));
wined3d_texture_validate_location(dst_texture, 0, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_invalidate_location(dst_texture, 0, ~WINED3D_LOCATION_TEXTURE_RGB);
return dst_texture;
}
-static void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, DWORD src_location, DWORD dst_location)
+static void read_from_framebuffer(struct wined3d_surface *surface,
+ struct wined3d_context *old_ctx, DWORD src_location, DWORD dst_location)
{
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
+ struct wined3d_texture *texture = surface->container;
struct wined3d_device *device = texture->resource.device;
- struct wined3d_texture *restore_texture;
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *restore_rt = NULL;
const struct wined3d_gl_info *gl_info;
unsigned int row_pitch, slice_pitch;
unsigned int width, height, level;
struct wined3d_bo_address data;
- unsigned int restore_idx;
BYTE *row, *top, *bottom;
BOOL src_is_upside_down;
unsigned int i;
wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location);
- restore_texture = context->current_rt.texture;
- restore_idx = context->current_rt.sub_resource_idx;
- if (restore_texture != texture || restore_idx != sub_resource_idx)
+ restore_rt = context_get_rt_surface(old_ctx);
+ if (restore_rt != surface)
context = context_acquire(device, texture, sub_resource_idx);
else
- restore_texture = NULL;
+ restore_rt = NULL;
gl_info = context->gl_info;
if (src_location != texture->resource.draw_binding)
{
- context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER,
- &texture->resource, sub_resource_idx, NULL, 0, src_location);
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, surface, NULL, src_location);
context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
context_invalidate_state(context, STATE_FRAMEBUFFER);
}
checkGLcall("glBindBuffer");
}
- if (restore_texture)
- context_restore(context, restore_texture, restore_idx);
+ if (restore_rt)
+ context_restore(context, restore_rt);
}
/* Read the framebuffer contents into a texture. Note that this function
*
* Context activation is done by the caller. This function may temporarily
* switch to a different context and restore the original one before return. */
-void texture2d_load_fb_texture(struct wined3d_texture *texture,
- unsigned int sub_resource_idx, BOOL srgb, struct wined3d_context *context)
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx)
{
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
+ struct wined3d_texture *texture = surface->container;
struct wined3d_device *device = texture->resource.device;
- struct wined3d_texture *restore_texture;
const struct wined3d_gl_info *gl_info;
- unsigned int restore_idx, level;
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *restore_rt = NULL;
+ unsigned int level;
GLenum target;
- restore_texture = context->current_rt.texture;
- restore_idx = context->current_rt.sub_resource_idx;
- if (restore_texture != texture || restore_idx != sub_resource_idx)
+ restore_rt = context_get_rt_surface(old_ctx);
+ if (restore_rt != surface)
context = context_acquire(device, texture, sub_resource_idx);
else
- restore_texture = NULL;
+ restore_rt = NULL;
gl_info = context->gl_info;
device_invalidate_state(device, STATE_FRAMEBUFFER);
wined3d_texture_prepare_texture(texture, context, srgb);
wined3d_texture_bind_and_dirtify(texture, context, srgb);
- TRACE("Reading back offscreen render target %p, %u.\n", texture, sub_resource_idx);
+ TRACE("Reading back offscreen render target %p.\n", surface);
if (wined3d_resource_is_offscreen(&texture->resource))
gl_info->gl_ops.gl.p_glReadBuffer(context_get_offscreen_gl_buffer(context));
wined3d_texture_get_level_height(texture, level));
checkGLcall("glCopyTexSubImage2D");
- if (restore_texture)
- context_restore(context, restore_texture, restore_idx);
+ if (restore_rt)
+ context_restore(context, restore_rt);
}
/* Does a direct frame buffer -> texture copy. Stretching is done with single
* pixel copy calls. */
-static void fb_copy_to_texture_direct(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- const RECT *dst_rect_in, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
- const RECT *src_rect, enum wined3d_texture_filter_type filter)
+static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
+ const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
{
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_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;
unsigned int src_height, src_level, dst_level;
const struct wined3d_gl_info *gl_info;
}
/* Uses the hardware to stretch and flip the image */
-static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- const RECT *dst_rect_in, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
- const RECT *src_rect, enum wined3d_texture_filter_type filter)
+static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
+ const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
{
unsigned int src_width, src_height, src_pow2_width, src_pow2_height, src_level;
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_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;
GLenum src_target, dst_target, texture_target;
GLuint src, backup = 0;
/* Activate the Proper context for reading from the source surface, set it up for blitting */
context = context_acquire(device, src_texture, src_sub_resource_idx);
gl_info = context->gl_info;
- context_apply_ffp_blit_state(context, device);
+ context_apply_blit_state(context, device);
wined3d_texture_load(dst_texture, context, FALSE);
offscreen_buffer = context_get_offscreen_gl_buffer(context);
checkGLcall("glEnable(texture_target)");
/* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
- src_texture->sub_resources[src_sub_resource_idx].locations &= ~WINED3D_LOCATION_TEXTURE_RGB;
+ surface_get_sub_resource(src_surface)->locations &= ~WINED3D_LOCATION_TEXTURE_RGB;
}
/* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
checkGLcall("glDeleteTextures(1, &backup)");
}
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
context_release(context);
/* The texture is now most up to date - If the surface is a render target
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
}
-static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
- const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
+/* Front buffer coordinates are always full screen coordinates, but our GL
+ * drawable is limited to the window's client area. The sysmem and texture
+ * copies do have the full screen size. Note that GL has a bottom-left
+ * origin, while D3D has a top-left origin. */
+void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect)
{
- struct wined3d_swapchain *src_swapchain, *dst_swapchain;
- const struct wined3d_rendertarget_view *rtv;
+ struct wined3d_texture *texture = surface->container;
+ POINT offset = {0, 0};
+ UINT drawable_height;
+ RECT windowsize;
- TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, "
- "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n",
- dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, src_sub_resource_idx,
- wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter));
+ if (!texture->swapchain)
+ return;
- if (dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
+ if (texture == texture->swapchain->front_buffer)
{
- FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_texture->resource.type));
- return WINED3DERR_INVALIDCALL;
+ ScreenToClient(window, &offset);
+ OffsetRect(rect, offset.x, offset.y);
}
+ GetClientRect(window, &windowsize);
+ drawable_height = windowsize.bottom - windowsize.top;
+
+ rect->top = drawable_height - rect->top;
+ rect->bottom = drawable_height - rect->bottom;
+}
+
+static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
+ const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
+{
+ struct wined3d_texture *dst_texture = dst_surface->container;
+ struct wined3d_device *device = dst_texture->resource.device;
+ const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]);
+ struct wined3d_swapchain *src_swapchain, *dst_swapchain;
+ struct wined3d_texture *src_texture;
+
+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n",
+ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
+ flags, fx, debug_d3dtexturefiltertype(filter));
+
/* Get the swapchain. One of the surfaces has to be a primary surface. */
if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
{
return WINED3DERR_INVALIDCALL;
}
- if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
+ dst_swapchain = dst_texture->swapchain;
+
+ if (src_surface)
{
- WARN("Source resource is not GPU accessible, rejecting GL blit.\n");
- return WINED3DERR_INVALIDCALL;
- }
+ src_texture = src_surface->container;
+ if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
+ {
+ WARN("Source resource is not GPU accessible, rejecting GL blit.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
- src_swapchain = src_texture->swapchain;
- dst_swapchain = dst_texture->swapchain;
+ src_swapchain = src_texture->swapchain;
+ }
+ else
+ {
+ src_texture = NULL;
+ src_swapchain = NULL;
+ }
/* Early sort out of cases where no render target is used */
- if (!(rtv = dst_texture->resource.device->fb.render_targets[0]) || (!src_swapchain && !dst_swapchain
- && (&src_texture->resource != rtv->resource || src_sub_resource_idx != rtv->sub_resource_idx)
- && (&dst_texture->resource != rtv->resource || dst_sub_resource_idx != rtv->sub_resource_idx)))
+ if (!dst_swapchain && !src_swapchain && src_surface != rt && dst_surface != rt)
{
TRACE("No surface is render target, not using hardware blit.\n");
return WINED3DERR_INVALIDCALL;
if (dst_swapchain)
{
/* Handled with regular texture -> swapchain blit */
- if (&src_texture->resource == rtv->resource && src_sub_resource_idx == rtv->sub_resource_idx)
+ if (src_surface == rt)
TRACE("Blit from active render target to a swapchain\n");
}
- else if (src_swapchain && &dst_texture->resource == rtv->resource
- && dst_sub_resource_idx == rtv->sub_resource_idx)
+ else if (src_swapchain && dst_surface == rt)
{
FIXME("Implement blit from a swapchain to the active render target\n");
return WINED3DERR_INVALIDCALL;
}
- if (!dst_swapchain && (src_swapchain || (&src_texture->resource == rtv->resource
- && src_sub_resource_idx == rtv->sub_resource_idx)))
+ if ((src_swapchain || src_surface == rt) && !dst_swapchain)
{
unsigned int src_level, src_width, src_height;
/* Blit from render target to texture */
* back buffer. This is slower than reading line per line, thus not used for flipping
* -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
* pixel by pixel. */
- src_level = src_sub_resource_idx % src_texture->level_count;
+ src_level = surface_get_sub_resource_idx(src_surface) % src_texture->level_count;
src_width = wined3d_texture_get_level_width(src_texture, src_level);
src_height = wined3d_texture_get_level_height(src_texture, src_level);
if (!stretchx || dst_rect->right - dst_rect->left > src_width
|| dst_rect->bottom - dst_rect->top > src_height)
{
TRACE("No stretching in x direction, using direct framebuffer -> texture copy.\n");
- fb_copy_to_texture_direct(dst_texture, dst_sub_resource_idx, dst_rect,
- src_texture, src_sub_resource_idx, src_rect, filter);
+ fb_copy_to_texture_direct(dst_surface, src_surface, src_rect, dst_rect, filter);
}
else
{
TRACE("Using hardware stretching to flip / stretch the texture.\n");
- fb_copy_to_texture_hwstretch(dst_texture, dst_sub_resource_idx, dst_rect,
- src_texture, src_sub_resource_idx, src_rect, filter);
+ fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter);
}
return WINED3D_OK;
}
/* Context activation is done by the caller. */
-BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+static BOOL surface_load_sysmem(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD dst_location)
{
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_texture *texture = surface->container;
struct wined3d_texture_sub_resource *sub_resource;
sub_resource = &texture->sub_resources[sub_resource_idx];
if (is_multisample_location(texture, WINED3D_LOCATION_TEXTURE_RGB))
{
wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_RB_RESOLVED);
- texture2d_read_from_framebuffer(texture, sub_resource_idx, context,
- WINED3D_LOCATION_RB_RESOLVED, dst_location);
+ read_from_framebuffer(surface, context, WINED3D_LOCATION_RB_RESOLVED, dst_location);
return TRUE;
}
else
if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
- /* Download the sub-resource to system memory. */
+ /* Download the surface to system memory. */
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
wined3d_texture_bind_and_dirtify(texture, context,
!(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
- texture2d_download_data(texture, sub_resource_idx, context, dst_location);
+ surface_download_data(surface, gl_info, dst_location);
++texture->download_count;
return TRUE;
if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
&& (sub_resource->locations & WINED3D_LOCATION_DRAWABLE))
{
- texture2d_read_from_framebuffer(texture, sub_resource_idx, context,
- texture->resource.draw_binding, dst_location);
+ read_from_framebuffer(surface, context, texture->resource.draw_binding, dst_location);
return TRUE;
}
- FIXME("Can't load texture %p, %u with location flags %s into sysmem.\n",
- texture, sub_resource_idx, wined3d_debug_location(sub_resource->locations));
+ FIXME("Can't load surface %p with location flags %s into sysmem.\n",
+ surface, wined3d_debug_location(sub_resource->locations));
return FALSE;
}
/* Context activation is done by the caller. */
-BOOL texture2d_load_drawable(struct wined3d_texture *texture,
- unsigned int sub_resource_idx, struct wined3d_context *context)
+static BOOL surface_load_drawable(struct wined3d_surface *surface,
+ struct wined3d_context *context)
{
- struct wined3d_texture *restore_texture;
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
+ struct wined3d_texture *texture = surface->container;
+ struct wined3d_surface *restore_rt = NULL;
struct wined3d_device *device;
- unsigned int restore_idx;
unsigned int level;
RECT r;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
&& wined3d_resource_is_offscreen(&texture->resource))
{
- ERR("Trying to load offscreen texture into WINED3D_LOCATION_DRAWABLE.\n");
+ ERR("Trying to load offscreen surface into WINED3D_LOCATION_DRAWABLE.\n");
return FALSE;
}
device = texture->resource.device;
- restore_texture = context->current_rt.texture;
- restore_idx = context->current_rt.sub_resource_idx;
- if (restore_texture != texture || restore_idx != sub_resource_idx)
+ restore_rt = context_get_rt_surface(context);
+ if (restore_rt != surface)
context = context_acquire(device, texture, sub_resource_idx);
else
- restore_texture = NULL;
+ restore_rt = NULL;
level = sub_resource_idx % texture->level_count;
SetRect(&r, 0, 0, wined3d_texture_get_level_width(texture, level),
wined3d_texture_get_level_height(texture, level));
wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context,
- texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &r,
- texture, sub_resource_idx, WINED3D_LOCATION_DRAWABLE, &r,
+ surface, WINED3D_LOCATION_TEXTURE_RGB, &r,
+ surface, WINED3D_LOCATION_DRAWABLE, &r,
NULL, WINED3D_TEXF_POINT);
- if (restore_texture)
- context_restore(context, restore_texture, restore_idx);
+ if (restore_rt)
+ context_restore(context, restore_rt);
return TRUE;
}
-BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+static BOOL surface_load_texture(struct wined3d_surface *surface,
struct wined3d_context *context, BOOL srgb)
{
unsigned int width, height, level, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch;
+ unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_texture *texture = surface->container;
struct wined3d_device *device = texture->resource.device;
const struct wined3d_color_key_conversion *conversion;
struct wined3d_texture_sub_resource *sub_resource;
- const struct wined3d_format *format;
struct wined3d_bo_address data;
BYTE *src_mem, *dst_mem = NULL;
- struct wined3d_box src_box;
+ struct wined3d_format format;
+ POINT dst_point = {0, 0};
+ RECT src_rect;
BOOL depth;
depth = texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL;
- sub_resource = &texture->sub_resources[sub_resource_idx];
+ sub_resource = surface_get_sub_resource(surface);
if (!depth && wined3d_settings.offscreen_rendering_mode != ORM_FBO
&& wined3d_resource_is_offscreen(&texture->resource)
&& (sub_resource->locations & WINED3D_LOCATION_DRAWABLE))
{
- texture2d_load_fb_texture(texture, sub_resource_idx, srgb, context);
+ surface_load_fb_texture(surface, srgb, context);
return TRUE;
}
level = sub_resource_idx % texture->level_count;
width = wined3d_texture_get_level_width(texture, level);
height = wined3d_texture_get_level_height(texture, level);
- wined3d_box_set(&src_box, 0, 0, width, height, 0, 1);
+ SetRect(&src_rect, 0, 0, width, height);
if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
&& (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
&texture->resource, WINED3D_LOCATION_TEXTURE_RGB,
&texture->resource, WINED3D_LOCATION_TEXTURE_SRGB))
{
- RECT src_rect;
-
- SetRect(&src_rect, 0, 0, width, height);
if (srgb)
- texture2d_blt_fbo(device, context, WINED3D_TEXF_POINT,
- texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect,
- texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect);
+ surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
+ &src_rect, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect);
else
- texture2d_blt_fbo(device, context, WINED3D_TEXF_POINT,
- texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect,
- texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, &src_rect);
+ surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB,
+ &src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect);
return TRUE;
}
DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ?
WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE;
DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
- RECT src_rect;
- SetRect(&src_rect, 0, 0, width, height);
if (fbo_blitter_supported(WINED3D_BLIT_OP_COLOR_BLIT, gl_info,
&texture->resource, src_location, &texture->resource, dst_location))
- texture2d_blt_fbo(device, context, WINED3D_TEXF_POINT, texture, sub_resource_idx,
- src_location, &src_rect, texture, sub_resource_idx, dst_location, &src_rect);
+ surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location,
+ &src_rect, surface, dst_location, &src_rect);
return TRUE;
}
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_RGB)
{
- FIXME_(d3d_perf)("Downloading RGB texture %p, %u to reload it as sRGB.\n", texture, sub_resource_idx);
+ FIXME_(d3d_perf)("Downloading RGB surface %p to reload it as sRGB.\n", surface);
wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
}
}
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_SRGB)
{
- FIXME_(d3d_perf)("Downloading sRGB texture %p, %u to reload it as RGB.\n", texture, sub_resource_idx);
+ FIXME_(d3d_perf)("Downloading sRGB surface %p to reload it as RGB.\n", surface);
wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
}
}
wined3d_texture_bind_and_dirtify(texture, context, srgb);
wined3d_texture_get_pitch(texture, level, &src_row_pitch, &src_slice_pitch);
- format = texture->resource.format;
+ format = *texture->resource.format;
if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
- format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
+ format = *wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
/* Don't use PBOs for converted surfaces. During PBO conversion we look at
* WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
* getting called. */
- if (conversion && sub_resource->buffer_object)
+#if !defined(STAGING_CSMT)
+ if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer_object)
+#else /* STAGING_CSMT */
+ if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer)
+#endif /* STAGING_CSMT */
{
- TRACE("Removing the pbo attached to texture %p, %u.\n", texture, sub_resource_idx);
+ TRACE("Removing the pbo attached to surface %p.\n", surface);
wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM);
wined3d_texture_set_map_binding(texture, WINED3D_LOCATION_SYSMEM);
}
wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations);
- if (conversion)
+ if (format.conv_byte_count)
+ {
+ /* This code is entered for texture formats which need a fixup. */
+ format.byte_count = format.conv_byte_count;
+ wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch);
+
+ src_mem = context_map_bo_address(context, &data, src_slice_pitch,
+ GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
+ if (!(dst_mem = heap_alloc(dst_slice_pitch)))
+ {
+ ERR("Out of memory (%u).\n", dst_slice_pitch);
+ context_release(context);
+ return FALSE;
+ }
+ format.upload(src_mem, dst_mem, src_row_pitch, src_slice_pitch,
+ dst_row_pitch, dst_slice_pitch, width, height, 1);
+ src_row_pitch = dst_row_pitch;
+ context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER);
+
+ data.buffer_object = 0;
+ data.addr = dst_mem;
+ }
+ else if (conversion)
{
- wined3d_format_calculate_pitch(format, device->surface_alignment,
+ /* This code is only entered for color keying fixups */
+ struct wined3d_palette *palette = NULL;
+
+ wined3d_format_calculate_pitch(&format, device->surface_alignment,
width, height, &dst_row_pitch, &dst_slice_pitch);
src_mem = context_map_bo_address(context, &data, src_slice_pitch,
context_release(context);
return FALSE;
}
+ if (texture->swapchain && texture->swapchain->palette)
+ palette = texture->swapchain->palette;
conversion->convert(src_mem, src_row_pitch, dst_mem, dst_row_pitch,
- width, height, &texture->async.gl_color_key);
+ width, height, palette, &texture->async.gl_color_key);
src_row_pitch = dst_row_pitch;
- src_slice_pitch = dst_slice_pitch;
context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER);
data.buffer_object = 0;
data.addr = dst_mem;
}
- wined3d_texture_upload_data(texture, sub_resource_idx, context, format, &src_box,
- wined3d_const_bo_address(&data), src_row_pitch, src_slice_pitch, 0, 0, 0, srgb);
+ wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
+ src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
heap_free(dst_mem);
}
/* Context activation is done by the caller. */
-BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, DWORD dst_location)
+static BOOL surface_load_renderbuffer(struct wined3d_surface *surface, struct wined3d_context *context,
+ DWORD dst_location)
{
- unsigned int level = sub_resource_idx % texture->level_count;
+ struct wined3d_texture *texture = surface->container;
+ unsigned int level = surface_get_sub_resource_idx(surface) % texture->level_count;
const RECT rect = {0, 0,
wined3d_texture_get_level_width(texture, level),
wined3d_texture_get_level_height(texture, level)};
- struct wined3d_texture_sub_resource *sub_resource;
- DWORD src_location, locations;
+ DWORD locations = surface_get_sub_resource(surface)->locations;
+ DWORD src_location;
- sub_resource = &texture->sub_resources[sub_resource_idx];
- locations = sub_resource->locations;
if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
{
FIXME("Unimplemented copy from %s for depth/stencil buffers.\n",
src_location = WINED3D_LOCATION_RB_RESOLVED;
else if (locations & WINED3D_LOCATION_TEXTURE_SRGB)
src_location = WINED3D_LOCATION_TEXTURE_SRGB;
- else if (locations & WINED3D_LOCATION_TEXTURE_RGB)
- src_location = WINED3D_LOCATION_TEXTURE_RGB;
- else if (locations & WINED3D_LOCATION_DRAWABLE)
- src_location = WINED3D_LOCATION_DRAWABLE;
- else /* texture2d_blt_fbo() will load the source location if necessary. */
+ else /* surface_blt_fbo will load the source location if necessary. */
src_location = WINED3D_LOCATION_TEXTURE_RGB;
- texture2d_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT, texture,
- sub_resource_idx, src_location, &rect, texture, sub_resource_idx, dst_location, &rect);
+ surface_blt_fbo(texture->resource.device, context, WINED3D_TEXF_POINT,
+ surface, src_location, &rect, surface, dst_location, &rect);
return TRUE;
}
+/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */
+BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location)
+{
+ TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location));
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_USER_MEMORY:
+ case WINED3D_LOCATION_SYSMEM:
+ case WINED3D_LOCATION_BUFFER:
+ return surface_load_sysmem(surface, context, location);
+
+ case WINED3D_LOCATION_DRAWABLE:
+ return surface_load_drawable(surface, context);
+
+ case WINED3D_LOCATION_RB_RESOLVED:
+ case WINED3D_LOCATION_RB_MULTISAMPLE:
+ return surface_load_renderbuffer(surface, context, location);
+
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ return surface_load_texture(surface, context,
+ location == WINED3D_LOCATION_TEXTURE_SRGB);
+
+ default:
+ ERR("Don't know how to handle location %#x.\n", location);
+ return FALSE;
+ }
+}
+
/* Context activation is done by the caller. */
static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
{
}
static DWORD fbo_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 *colour_key, enum wined3d_texture_filter_type filter)
{
- struct wined3d_resource *src_resource, *dst_resource;
+ struct wined3d_resource *src_resource = &src_surface->container->resource;
+ struct wined3d_resource *dst_resource = &dst_surface->container->resource;
+ struct wined3d_device *device = dst_resource->device;
enum wined3d_blit_op blit_op = op;
- struct wined3d_device *device;
struct wined3d_blitter *next;
- 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), colour_key, debug_d3dtexturefiltertype(filter));
-
- src_resource = &src_texture->resource;
- dst_resource = &dst_texture->resource;
-
- device = dst_resource->device;
-
if (blit_op == WINED3D_BLIT_OP_RAW_BLIT && dst_resource->format->id == src_resource->format->id)
{
if (dst_resource->format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
if (!fbo_blitter_supported(blit_op, context->gl_info,
src_resource, src_location, dst_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, colour_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, colour_key, filter);
}
if (blit_op == WINED3D_BLIT_OP_COLOR_BLIT)
{
TRACE("Colour blit.\n");
- texture2d_blt_fbo(device, context, filter, src_texture, src_sub_resource_idx, src_location,
- src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect);
+ surface_blt_fbo(device, context, filter, src_surface, src_location,
+ src_rect, dst_surface, dst_location, dst_rect);
return dst_location;
}
if (blit_op == WINED3D_BLIT_OP_DEPTH_BLIT)
{
TRACE("Depth/stencil blit.\n");
- texture2d_depth_blt_fbo(device, context, src_texture, src_sub_resource_idx, src_location,
- src_rect, dst_texture, dst_sub_resource_idx, dst_location, dst_rect);
+ surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect);
return dst_location;
}
/* Context activation is done by the caller. */
static DWORD raw_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 *colour_key, enum wined3d_texture_filter_type filter)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int src_sub_resource_idx, dst_sub_resource_idx;
unsigned int src_level, src_layer, dst_level, dst_layer;
+ struct wined3d_texture *src_texture, *dst_texture;
struct wined3d_blitter *next;
GLuint src_name, dst_name;
DWORD location;
+ src_texture = src_surface->container;
+ dst_texture = dst_surface->container;
+
/* If we would need to copy from a renderbuffer or drawable, we'd probably
* be better of using the FBO blitter directly, since we'd need to use it
* to copy the resource contents to the texture anyway. */
}
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, colour_key, filter);
+ return next->ops->blitter_blit(next, op, context, src_surface, src_location,
+ src_rect, dst_surface, dst_location, dst_rect, colour_key, filter);
}
TRACE("Blit using ARB_copy_image.\n");
+ src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
src_level = src_sub_resource_idx % src_texture->level_count;
src_layer = src_sub_resource_idx / src_texture->level_count;
+ dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
dst_level = dst_sub_resource_idx % dst_texture->level_count;
dst_layer = dst_sub_resource_idx / dst_texture->level_count;
const struct wined3d_format *dst_format = dst_resource->format;
BOOL decompress;
- if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D)
- return FALSE;
-
decompress = src_format && (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
&& !(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED);
if (!decompress && !(src_resource->access & dst_resource->access & WINED3D_RESOURCE_ACCESS_GPU))
}
static DWORD ffp_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;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_resource *src_resource, *dst_resource;
- struct wined3d_texture *staging_texture = NULL;
struct wined3d_color_key old_blt_key;
struct wined3d_device *device;
struct wined3d_blitter *next;
if (!ffp_blit_supported(op, context, src_resource, src_location, dst_resource, dst_location))
{
if ((next = blitter->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);
+ return next->ops->blitter_blit(next, op, context, src_surface, src_location,
+ src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
}
- TRACE("Blt from texture %p, %u to rendertarget %p, %u.\n",
- src_texture, src_sub_resource_idx, dst_texture, dst_sub_resource_idx);
+ TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
old_blt_key = src_texture->async.src_blt_color_key;
old_color_key_flags = src_texture->async.color_key_flags;
wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, color_key);
- if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
- {
- struct wined3d_resource_desc desc;
- struct wined3d_box upload_box;
- unsigned int src_level;
- 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
- {
- /* Make sure the surface is up-to-date. This should probably use
- * surface_load_location() and worry about the destination surface
- * too, unless we're overwriting it completely. */
- wined3d_texture_load(src_texture, context, FALSE);
- }
+ /* Make sure the surface is up-to-date. This should probably use
+ * surface_load_location() and worry about the destination surface too,
+ * unless we're overwriting it completely. */
+ wined3d_texture_load(src_texture, context, FALSE);
- context_apply_ffp_blit_state(context, device);
+ /* Activate the destination context, set it up for blitting. */
+ context_apply_blit_state(context, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE)
{
r = *dst_rect;
- wined3d_texture_translate_drawable_coords(dst_texture, context->win_handle, &r);
+ surface_translate_drawable_coords(dst_surface, context->win_handle, &r);
dst_rect = &r;
}
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_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);
checkGLcall("glAlphaFunc");
}
- 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);
if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key)
{
checkGLcall("glDisable(GL_ALPHA_TEST)");
}
+ /* Leave the OpenGL state valid for blitting. */
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
- if (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture)
- gl_info->gl_ops.gl.p_glFlush();
+ if (wined3d_settings.strict_draw_ordering
+ || (dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture))
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
/* Restore the color key parameters */
wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT,
(old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL);
- if (staging_texture)
- wined3d_texture_decref(staging_texture);
-
return dst_location;
}
}
static DWORD cpu_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)
{
struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1};
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
+ struct wined3d_texture *dst_texture = dst_surface->container;
+ struct wined3d_texture *src_texture = src_surface->container;
struct wined3d_blt_fx fx;
DWORD flags = 0;
return blitter;
}
-HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- const struct wined3d_box *dst_box, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
- const struct wined3d_box *src_box, DWORD flags, const struct wined3d_blt_fx *fx,
- enum wined3d_texture_filter_type filter)
+HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
+ const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
{
+ struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
+ struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1};
+ unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface);
+ unsigned int src_sub_resource_idx = surface_get_sub_resource_idx(src_surface);
struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource;
+ struct wined3d_texture *dst_texture = dst_surface->container;
+ struct wined3d_texture *src_texture = src_surface->container;
struct wined3d_device *device = dst_texture->resource.device;
struct wined3d_swapchain *src_swapchain, *dst_swapchain;
const struct wined3d_color_key *colour_key = NULL;
struct wined3d_context *context;
enum wined3d_blit_op blit_op;
BOOL scale, convert, resolve;
- RECT src_rect, dst_rect;
static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY
| WINED3D_BLT_SRC_CKEY_OVERRIDE
| WINED3D_BLT_ALPHA_TEST
| WINED3D_BLT_RAW;
- TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, "
- "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n",
- dst_texture, dst_sub_resource_idx, debug_box(dst_box), src_texture, src_sub_resource_idx,
- debug_box(src_box), flags, fx, debug_d3dtexturefiltertype(filter));
+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n",
+ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
+ flags, fx, debug_d3dtexturefiltertype(filter));
TRACE("Usage is %s.\n", debug_d3dusage(dst_texture->resource.usage));
if (fx)
fx->src_color_key.color_space_high_value);
}
- SetRect(&src_rect, src_box->left, src_box->top, src_box->right, src_box->bottom);
- SetRect(&dst_rect, dst_box->left, dst_box->top, dst_box->right, dst_box->bottom);
-
if (!fx || !(fx->fx))
flags &= ~WINED3D_BLT_FX;
goto cpu;
}
+ /* We want to avoid invalidating the sysmem location for converted
+ * surfaces, since otherwise we'd have to convert the data back when
+ * locking them. */
+ if (dst_texture->flags & WINED3D_TEXTURE_CONVERTED || dst_texture->resource.format->conv_byte_count
+ || wined3d_format_get_color_key_conversion(dst_texture, TRUE))
+ {
+ WARN_(d3d_perf)("Converted surface, using CPU blit.\n");
+ goto cpu;
+ }
+
if (flags & ~simple_blit)
{
WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags);
goto fallback;
}
- scale = src_box->right - src_box->left != dst_box->right - dst_box->left
- || src_box->bottom - src_box->top != dst_box->bottom - dst_box->top;
+ scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left
+ || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top;
convert = src_texture->resource.format->id != dst_texture->resource.format->id;
resolve = src_texture->resource.multisample_type != dst_texture->resource.multisample_type;
context = context_acquire(device, dst_texture, dst_sub_resource_idx);
valid_locations = device->blitter->ops->blitter_blit(device->blitter,
WINED3D_BLIT_OP_DEPTH_BLIT, context,
- src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect,
- dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, NULL, filter);
+ src_surface, src_texture->resource.draw_binding, src_rect,
+ dst_surface, dst_location, dst_rect, NULL, filter);
context_release(context);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations);
TRACE("Not doing upload because the destination format needs conversion.\n");
else
{
- wined3d_texture_upload_from_texture(dst_texture, dst_sub_resource_idx, dst_box->left,
- dst_box->top, dst_box->front, src_texture, src_sub_resource_idx, src_box);
- if (!wined3d_resource_is_offscreen(&dst_texture->resource))
+ POINT dst_point = {dst_rect->left, dst_rect->top};
+
+ if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect)))
{
- context = context_acquire(device, dst_texture, dst_sub_resource_idx);
- wined3d_texture_load_location(dst_texture, dst_sub_resource_idx,
- context, dst_texture->resource.draw_binding);
- context_release(context);
+ if (!wined3d_resource_is_offscreen(&dst_texture->resource))
+ {
+ context = context_acquire(device, dst_texture, dst_sub_resource_idx);
+ wined3d_texture_load_location(dst_texture, dst_sub_resource_idx,
+ context, dst_texture->resource.draw_binding);
+ context_release(context);
+ }
+ return WINED3D_OK;
}
- return WINED3D_OK;
}
}
else if (dst_swapchain && dst_swapchain->back_buffers
/* Set the swap effect to COPY, we don't want the backbuffer to become
* undefined. */
dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
- wined3d_swapchain_present(dst_swapchain, NULL, NULL,
- dst_swapchain->win_handle, dst_swapchain->swap_interval, 0);
+ wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, 0, 0);
dst_swapchain->desc.swap_effect = swap_effect;
return WINED3D_OK;
context = context_acquire(device, dst_texture, dst_sub_resource_idx);
valid_locations = device->blitter->ops->blitter_blit(device->blitter, blit_op, context,
- src_texture, src_sub_resource_idx, src_texture->resource.draw_binding, &src_rect,
- dst_texture, dst_sub_resource_idx, dst_location, &dst_rect, colour_key, filter);
+ src_surface, src_texture->resource.draw_binding, src_rect,
+ dst_surface, dst_location, dst_rect, colour_key, filter);
context_release(context);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, valid_locations);
fallback:
/* Special cases for render targets. */
- if (SUCCEEDED(wined3d_texture_blt_special(dst_texture, dst_sub_resource_idx, &dst_rect,
- src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter)))
+ if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter)))
return WINED3D_OK;
cpu:
- return surface_cpu_blt(dst_texture, dst_sub_resource_idx, dst_box,
- src_texture, src_sub_resource_idx, src_box, flags, fx, filter);
+ return surface_cpu_blt(dst_texture, dst_sub_resource_idx, &dst_box,
+ src_texture, src_sub_resource_idx, &src_box, flags, fx, filter);
}
HRESULT CDECL wined3d_swapchain_present(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)
{
+ static DWORD notified_flags = 0;
RECT s, d;
TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, flags %#x.\n",
swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
dst_window_override, flags);
- if (flags)
- FIXME("Ignoring flags %#x.\n", flags);
+ if (flags & ~notified_flags)
+ {
+ FIXME("Ignoring flags %#x.\n", flags & ~notified_flags);
+ notified_flags |= flags;
+ }
if (!swapchain->back_buffers)
{
- WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL.\n");
+ WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect)
{
struct wined3d_texture *texture = swapchain->back_buffers[0];
+ struct wined3d_surface *back_buffer = texture->sub_resources[0].u.surface;
struct wined3d_device *device = swapchain->device;
enum wined3d_texture_filter_type filter;
DWORD location;
location = WINED3D_LOCATION_RB_RESOLVED;
wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE);
- device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, texture, 0,
- location, src_rect, texture, 0, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter);
+ device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, back_buffer,
+ location, src_rect, back_buffer, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter);
wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE);
}
{
struct wined3d_texture *back_buffer = swapchain->back_buffers[0];
const struct wined3d_fb_state *fb = &swapchain->device->cs->fb;
- struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
const struct wined3d_gl_info *gl_info;
struct wined3d_texture *logo_texture;
struct wined3d_context *context;
if (swapchain->render_to_fbo)
swapchain_blit(swapchain, context, src_rect, dst_rect);
+#if !defined(STAGING_CSMT)
if (swapchain->num_contexts > 1)
+#else /* STAGING_CSMT */
+ if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded)
+#endif /* STAGING_CSMT */
gl_info->gl_ops.gl.p_glFinish();
/* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
wined3d_texture_validate_location(swapchain->back_buffers[swapchain->desc.backbuffer_count - 1],
0, WINED3D_LOCATION_DISCARDED);
- if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER)
+ if (fb->depth_stencil)
{
- struct wined3d_texture *ds = texture_from_resource(dsv->resource);
+ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil);
- if ((swapchain->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
- || ds->flags & WINED3D_TEXTURE_DISCARD))
- wined3d_texture_validate_location(ds, dsv->sub_resource_idx, WINED3D_LOCATION_DISCARDED);
+ if (ds && (swapchain->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
+ || ds->container->flags & WINED3D_TEXTURE_DISCARD))
+ wined3d_texture_validate_location(ds->container,
+ fb->depth_stencil->sub_resource_idx, WINED3D_LOCATION_DISCARDED);
}
context_release(context);
static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain)
{
- struct wined3d_dc_info *front;
+ struct wined3d_surface *front;
POINT offset = {0, 0};
HDC src_dc, dst_dc;
RECT draw_rect;
TRACE("swapchain %p.\n", swapchain);
- front = &swapchain->front_buffer->dc_info[0];
+ front = swapchain->front_buffer->sub_resources[0].u.surface;
if (swapchain->palette)
wined3d_palette_apply_to_dc(swapchain->palette, front->dc);
- if (swapchain->front_buffer->resource.map_count)
+ if (front->container->resource.map_count)
ERR("Trying to blit a mapped surface.\n");
TRACE("Copying surface %p to screen.\n", front);
static void swapchain_gdi_present(struct wined3d_swapchain *swapchain,
const RECT *src_rect, const RECT *dst_rect, DWORD flags)
{
- struct wined3d_dc_info *front, *back;
+ struct wined3d_surface *front, *back;
HBITMAP bitmap;
void *data;
HDC dc;
- front = &swapchain->front_buffer->dc_info[0];
- back = &swapchain->back_buffers[0]->dc_info[0];
+ front = swapchain->front_buffer->sub_resources[0].u.surface;
+ back = swapchain->back_buffers[0]->sub_resources[0].u.surface;
/* Flip the surface data. */
dc = front->dc;
bitmap = front->bitmap;
- data = swapchain->front_buffer->resource.heap_memory;
+ data = front->container->resource.heap_memory;
front->dc = back->dc;
front->bitmap = back->bitmap;
- swapchain->front_buffer->resource.heap_memory = swapchain->back_buffers[0]->resource.heap_memory;
+ front->container->resource.heap_memory = back->container->resource.heap_memory;
back->dc = dc;
back->bitmap = bitmap;
- swapchain->back_buffers[0]->resource.heap_memory = data;
+ back->container->resource.heap_memory = data;
/* FPS support */
if (TRACE_ON(fps))
*quality = 0;
}
-void wined3d_swapchain_set_swap_interval(struct wined3d_swapchain *swapchain,
- unsigned int swap_interval)
+static void wined3d_swapchain_update_swap_interval_cs(void *object)
{
+ struct wined3d_swapchain *swapchain = object;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
-
- swap_interval = swap_interval <= 4 ? swap_interval : 1;
- if (swapchain->swap_interval == swap_interval)
- return;
-
- swapchain->swap_interval = swap_interval;
+ int swap_interval;
context = context_acquire(swapchain->device, swapchain->front_buffer, 0);
gl_info = context->gl_info;
+ switch (swapchain->desc.swap_interval)
+ {
+ case WINED3DPRESENT_INTERVAL_IMMEDIATE:
+ swap_interval = 0;
+ break;
+ case WINED3DPRESENT_INTERVAL_DEFAULT:
+ case WINED3DPRESENT_INTERVAL_ONE:
+ swap_interval = 1;
+ break;
+ case WINED3DPRESENT_INTERVAL_TWO:
+ swap_interval = 2;
+ break;
+ case WINED3DPRESENT_INTERVAL_THREE:
+ swap_interval = 3;
+ break;
+ case WINED3DPRESENT_INTERVAL_FOUR:
+ swap_interval = 4;
+ break;
+ default:
+ FIXME("Unhandled present interval %#x.\n", swapchain->desc.swap_interval);
+ swap_interval = 1;
+ }
+
if (gl_info->supported[WGL_EXT_SWAP_CONTROL])
{
if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval)))
- ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x.\n",
- swap_interval, context, GetLastError());
+ ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x\n",
+ swap_interval, context, GetLastError());
}
context_release(context);
FIXME("Add OpenGL context recreation support.\n");
context_release(swapchain->context[0]);
-}
-void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const struct wined3d_device *device)
-{
- /* Subtract 1 for the implicit OpenGL latency. */
- swapchain->max_frame_latency = device->max_frame_latency >= 2 ? device->max_frame_latency - 1 : 1;
+ wined3d_swapchain_update_swap_interval_cs(swapchain);
}
static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device,
BOOL displaymode_set = FALSE;
DWORD texture_flags = 0;
RECT client_rect;
- unsigned int i;
HWND window;
HRESULT hr;
+ UINT i;
if (desc->backbuffer_count > 1)
{
swapchain->ref = 1;
swapchain->win_handle = window;
swapchain->device_window = window;
- swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT;
- swapchain_set_max_frame_latency(swapchain, device);
if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d,
adapter->ordinal, &swapchain->original_mode, NULL)))
GetClientRect(window, &client_rect);
if (desc->windowed)
{
- TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect));
-
if (!desc->backbuffer_width)
{
- desc->backbuffer_width = client_rect.right ? client_rect.right : 8;
+ desc->backbuffer_width = client_rect.right;
TRACE("Updating width to %u.\n", desc->backbuffer_width);
}
+
if (!desc->backbuffer_height)
{
- desc->backbuffer_height = client_rect.bottom ? client_rect.bottom : 8;
+ desc->backbuffer_height = client_rect.bottom;
TRACE("Updating height to %u.\n", desc->backbuffer_height);
}
}
}
+void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain)
+{
+ wined3d_cs_init_object(swapchain->device->cs, wined3d_swapchain_update_swap_interval_cs, swapchain);
+}
+
void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate)
{
struct wined3d_device *device = swapchain->device;
#define WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD 50
-struct wined3d_texture_idx
-{
- struct wined3d_texture *texture;
- unsigned int sub_resource_idx;
-};
-
-struct wined3d_rect_f
-{
- float l;
- float t;
- float r;
- float b;
-};
-
static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
{
return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU)
&& !(texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE);
}
-/* Front buffer coordinates are always full screen coordinates, but our GL
- * drawable is limited to the window's client area. The sysmem and texture
- * copies do have the full screen size. Note that GL has a bottom-left
- * origin, while D3D has a top-left origin. */
-void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, HWND window, RECT *rect)
-{
- unsigned int drawable_height;
- POINT offset = {0, 0};
- RECT windowsize;
-
- if (!texture->swapchain)
- return;
-
- if (texture == texture->swapchain->front_buffer)
- {
- ScreenToClient(window, &offset);
- OffsetRect(rect, offset.x, offset.y);
- }
-
- GetClientRect(window, &windowsize);
- drawable_height = windowsize.bottom - windowsize.top;
-
- rect->top = drawable_height - rect->top;
- rect->bottom = drawable_height - rect->bottom;
-}
-
GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture)
{
const struct wined3d_swapchain *swapchain = texture->swapchain;
}
}
-static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct wined3d_rect_f *f)
-{
- f->l = ((r->left * 2.0f) / w) - 1.0f;
- f->t = ((r->top * 2.0f) / h) - 1.0f;
- f->r = ((r->right * 2.0f) / w) - 1.0f;
- f->b = ((r->bottom * 2.0f) / h) - 1.0f;
-}
-
-void texture2d_get_blt_info(const struct wined3d_texture *texture,
- unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info)
+static BOOL is_power_of_two(UINT x)
{
- struct wined3d_vec3 *coords = info->texcoords;
- struct wined3d_rect_f f;
- unsigned int level;
- GLenum target;
- GLsizei w, h;
-
- level = sub_resource_idx % texture->level_count;
- w = wined3d_texture_get_level_pow2_width(texture, level);
- h = wined3d_texture_get_level_pow2_height(texture, level);
- target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
-
- switch (target)
- {
- default:
- FIXME("Unsupported texture target %#x.\n", target);
- /* Fall back to GL_TEXTURE_2D */
- case GL_TEXTURE_2D:
- info->bind_target = GL_TEXTURE_2D;
- coords[0].x = (float)rect->left / w;
- coords[0].y = (float)rect->top / h;
- coords[0].z = 0.0f;
-
- coords[1].x = (float)rect->right / w;
- coords[1].y = (float)rect->top / h;
- coords[1].z = 0.0f;
-
- coords[2].x = (float)rect->left / w;
- coords[2].y = (float)rect->bottom / h;
- coords[2].z = 0.0f;
-
- coords[3].x = (float)rect->right / w;
- coords[3].y = (float)rect->bottom / h;
- coords[3].z = 0.0f;
- break;
-
- case GL_TEXTURE_RECTANGLE_ARB:
- info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
- coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f;
- coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f;
- coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f;
- coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(rect, w, h, &f);
-
- coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l;
- coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r;
- coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l;
- coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r;
- break;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(rect, w, h, &f);
-
- coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l;
- coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r;
- coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l;
- coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(rect, w, h, &f);
-
- coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t;
- coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t;
- coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b;
- coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b;
- break;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(rect, w, h, &f);
-
- coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t;
- coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t;
- coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b;
- coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(rect, w, h, &f);
-
- coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f;
- coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f;
- coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f;
- coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f;
- break;
-
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
- cube_coords_float(rect, w, h, &f);
-
- coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f;
- coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f;
- coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f;
- coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f;
- break;
- }
+ return (x != 0) && !(x & (x - 1));
}
static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
if (locations & WINED3D_LOCATION_BUFFER)
{
data->addr = NULL;
+#if !defined(STAGING_CSMT)
data->buffer_object = sub_resource->buffer_object;
+#else /* STAGING_CSMT */
+ data->buffer_object = sub_resource->buffer->name;
+#endif /* STAGING_CSMT */
return;
}
if (locations & WINED3D_LOCATION_USER_MEMORY)
data->buffer_object = 0;
}
+static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
+ UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD flags,
+ struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops,
+ const struct wined3d_resource_ops *resource_ops)
+{
+ unsigned int i, j, size, offset = 0;
+ const struct wined3d_format *format;
+ HRESULT hr;
+
+ TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
+ "multisample_type %#x, multisample_quality %#x, usage %s, access %s, width %u, height %u, depth %u, "
+ "flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n",
+ texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
+ debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
+ debug_d3dusage(desc->usage), wined3d_debug_resource_access(desc->access),
+ desc->width, desc->height, desc->depth, flags, device, parent, parent_ops, resource_ops);
+
+ if (!desc->width || !desc->height || !desc->depth)
+ return WINED3DERR_INVALIDCALL;
+
+ format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage);
+
+ for (i = 0; i < layer_count; ++i)
+ {
+ for (j = 0; j < level_count; ++j)
+ {
+ unsigned int idx = i * level_count + j;
+
+ size = wined3d_format_calculate_size(format, device->surface_alignment,
+ max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j));
+ texture->sub_resources[idx].offset = offset;
+ texture->sub_resources[idx].size = size;
+ offset += size;
+ }
+ offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
+ }
+
+ if (!offset)
+ return WINED3DERR_INVALIDCALL;
+
+ if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
+ desc->multisample_type, desc->multisample_quality, desc->usage, desc->access,
+ desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops)))
+ {
+ static unsigned int once;
+
+ /* DXTn 3D textures are not supported. Do not write the ERR for them. */
+ if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3
+ || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5)
+ && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)
+ && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++)
+ ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n");
+
+ WARN("Failed to initialize resource, returning %#x\n", hr);
+ return hr;
+ }
+ wined3d_resource_update_draw_binding(&texture->resource);
+ if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE)
+ texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+
+ texture->texture_ops = texture_ops;
+
+ texture->layer_count = layer_count;
+ texture->level_count = level_count;
+ texture->lod = 0;
+ texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
+ if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)
+ texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT;
+ if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT))
+ texture->flags |= WINED3D_TEXTURE_GET_DC;
+ if (flags & WINED3D_TEXTURE_CREATE_DISCARD)
+ texture->flags |= WINED3D_TEXTURE_DISCARD;
+ if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS)
+ {
+ if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP))
+ WARN("Format doesn't support mipmaps generation, "
+ "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n");
+ else
+ texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS;
+ }
+
+ return WINED3D_OK;
+}
+
/* Context activation is done by the caller. */
static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
+#if !defined(STAGING_CSMT)
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
{
GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER);
*buffer_object = 0;
+#else /* STAGING_CSMT */
+ unsigned int sub_resource_idx, struct wined3d_context *context)
+{
+ struct wined3d_gl_bo *buffer = texture->sub_resources[sub_resource_idx].buffer;
+ GLuint name = buffer->name;
+
+ wined3d_device_release_bo(texture->resource.device, buffer, context);
+ texture->sub_resources[sub_resource_idx].buffer = NULL;
+ wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER);
+
+ TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n",
+ name, texture, sub_resource_idx);
+#endif /* STAGING_CSMT */
}
static void wined3d_texture_update_map_binding(struct wined3d_texture *texture)
&& !wined3d_texture_load_location(texture, i, context, map_binding))
ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER)
+#if !defined(STAGING_CSMT)
wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
+#else /* STAGING_CSMT */
+ wined3d_texture_remove_buffer_object(texture, i, context);
+#endif /* STAGING_CSMT */
}
if (context)
const struct wined3d_gl_info *gl_info)
{
unsigned int level, level_count, layer, layer_count;
- GLsizei width, height, depth;
+ GLsizei width, height;
GLenum target;
level_count = texture->level_count;
- if (texture->target == GL_TEXTURE_1D_ARRAY || texture->target == GL_TEXTURE_2D_ARRAY)
- layer_count = 1;
- else
- layer_count = texture->layer_count;
+ layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count;
for (layer = 0; layer < layer_count; ++layer)
{
TRACE("texture %p, layer %u, level %u, target %#x, width %u, height %u.\n",
texture, layer, level, target, width, height);
- if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY)
+ if (texture->target == GL_TEXTURE_2D_ARRAY)
{
- depth = wined3d_texture_get_level_depth(texture, level);
GL_EXTCALL(glTexImage3D(target, level, gl_internal_format, width, height,
- target == GL_TEXTURE_2D_ARRAY ? texture->layer_count : depth, 0,
- format->glFormat, format->glType, NULL));
+ texture->layer_count, 0, format->glFormat, format->glType, NULL));
checkGLcall("glTexImage3D");
}
- else if (target == GL_TEXTURE_1D)
- {
- gl_info->gl_ops.gl.p_glTexImage1D(target, level, gl_internal_format,
- width, 0, format->glFormat, format->glType, NULL);
- }
else
{
- gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, width,
- target == GL_TEXTURE_1D_ARRAY ? texture->layer_count : height, 0,
- format->glFormat, format->glType, NULL);
+ gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format,
+ width, height, 0, format->glFormat, format->glType, NULL);
checkGLcall("glTexImage2D");
}
}
switch (texture->target)
{
- case GL_TEXTURE_3D:
- GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count,
- gl_internal_format, width, height, wined3d_texture_get_level_depth(texture, 0)));
- break;
case GL_TEXTURE_2D_ARRAY:
GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count,
gl_internal_format, width, height, texture->layer_count));
GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples,
gl_internal_format, width, height, texture->layer_count, GL_FALSE));
break;
- case GL_TEXTURE_1D_ARRAY:
- GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
- gl_internal_format, width, texture->layer_count));
- break;
- case GL_TEXTURE_1D:
- GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, gl_internal_format, width));
- break;
default:
GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
gl_internal_format, width, height));
}
}
-static void wined3d_texture_create_dc(void *object)
-{
- const struct wined3d_texture_idx *idx = object;
- struct wined3d_context *context = NULL;
- unsigned int sub_resource_idx, level;
- const struct wined3d_format *format;
- unsigned int row_pitch, slice_pitch;
- struct wined3d_texture *texture;
- struct wined3d_dc_info *dc_info;
- struct wined3d_bo_address data;
- D3DKMT_CREATEDCFROMMEMORY desc;
- struct wined3d_device *device;
- NTSTATUS status;
-
- TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx);
-
- texture = idx->texture;
- sub_resource_idx = idx->sub_resource_idx;
- level = sub_resource_idx % texture->level_count;
- device = texture->resource.device;
-
- format = texture->resource.format;
- if (!format->ddi_format)
- {
- WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
- return;
- }
-
- if (!texture->dc_info)
- {
- unsigned int sub_count = texture->level_count * texture->layer_count;
-
- if (!(texture->dc_info = heap_calloc(sub_count, sizeof(*texture->dc_info))))
- {
- ERR("Failed to allocate DC info.\n");
- return;
- }
- }
-
- if (device->d3d_initialized)
- context = context_acquire(device, NULL, 0);
-
- wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
- wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
- wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch);
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
- desc.pMemory = context_map_bo_address(context, &data,
- texture->sub_resources[sub_resource_idx].size,
- GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE);
-
- if (context)
- context_release(context);
-
- desc.Format = format->ddi_format;
- desc.Width = wined3d_texture_get_level_width(texture, level);
- desc.Height = wined3d_texture_get_level_height(texture, level);
- desc.Pitch = row_pitch;
- desc.hDeviceDc = CreateCompatibleDC(NULL);
- desc.pColorTable = NULL;
-
- status = D3DKMTCreateDCFromMemory(&desc);
- DeleteDC(desc.hDeviceDc);
- if (status)
- {
- WARN("Failed to create DC, status %#x.\n", status);
- return;
- }
-
- dc_info = &texture->dc_info[sub_resource_idx];
- dc_info->dc = desc.hDc;
- dc_info->bitmap = desc.hBitmap;
-
- TRACE("Created DC %p, bitmap %p for texture %p, %u.\n", dc_info->dc, dc_info->bitmap, texture, sub_resource_idx);
-}
-
-static void wined3d_texture_destroy_dc(void *object)
-{
- const struct wined3d_texture_idx *idx = object;
- D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
- struct wined3d_context *context = NULL;
- struct wined3d_texture *texture;
- struct wined3d_dc_info *dc_info;
- struct wined3d_bo_address data;
- unsigned int sub_resource_idx;
- struct wined3d_device *device;
- NTSTATUS status;
-
- texture = idx->texture;
- sub_resource_idx = idx->sub_resource_idx;
- device = texture->resource.device;
- dc_info = &texture->dc_info[sub_resource_idx];
-
- if (!dc_info->dc)
- {
- ERR("Sub-resource {%p, %u} has no DC.\n", texture, sub_resource_idx);
- return;
- }
-
- TRACE("dc %p, bitmap %p.\n", dc_info->dc, dc_info->bitmap);
-
- destroy_desc.hDc = dc_info->dc;
- destroy_desc.hBitmap = dc_info->bitmap;
- if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
- ERR("Failed to destroy dc, status %#x.\n", status);
- dc_info->dc = NULL;
- dc_info->bitmap = NULL;
-
- if (device->d3d_initialized)
- context = context_acquire(device, NULL, 0);
-
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
- context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER);
-
- if (context)
- context_release(context);
-}
-
static void wined3d_texture_cleanup(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
struct wined3d_device *device = texture->resource.device;
- struct wined3d_renderbuffer_entry *entry, *entry2;
- const struct wined3d_gl_info *gl_info = NULL;
struct wined3d_context *context = NULL;
- struct wined3d_dc_info *dc_info;
+#if !defined(STAGING_CSMT)
+ const struct wined3d_gl_info *gl_info;
GLuint buffer_object;
+#else /* STAGING_CSMT */
+ struct wined3d_gl_bo *buffer;
+#endif /* STAGING_CSMT */
unsigned int i;
TRACE("texture %p.\n", texture);
for (i = 0; i < sub_count; ++i)
{
+#if !defined(STAGING_CSMT)
if (!(buffer_object = texture->sub_resources[i].buffer_object))
continue;
TRACE("Deleting buffer object %u.\n", buffer_object);
+#else /* STAGING_CSMT */
+ if (!(buffer = texture->sub_resources[i].buffer))
+ continue;
+
+ TRACE("Deleting buffer object %u.\n", buffer->name);
+#endif /* STAGING_CSMT */
/* We may not be able to get a context in wined3d_texture_cleanup() in
* general, but if a buffer object was previously created we can. */
if (!context)
+#if !defined(STAGING_CSMT)
{
context = context_acquire(device, NULL, 0);
gl_info = context->gl_info;
}
GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
- }
-
- if (!context && !list_empty(&texture->renderbuffers))
- {
- context = context_acquire(device, NULL, 0);
- gl_info = context->gl_info;
- }
+#else /* STAGING_CSMT */
+ context = context_acquire(device, NULL, 0);
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- TRACE("Deleting renderbuffer %u.\n", entry->id);
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- heap_free(entry);
+ wined3d_device_release_bo(device, buffer, context);
+ texture->sub_resources[i].buffer = NULL;
+#endif /* STAGING_CSMT */
}
-
if (context)
context_release(context);
- if ((dc_info = texture->dc_info))
- {
- for (i = 0; i < sub_count; ++i)
- {
- if (dc_info[i].dc)
- {
- struct wined3d_texture_idx texture_idx = {texture, i};
-
- wined3d_texture_destroy_dc(&texture_idx);
- }
- }
- heap_free(dc_info);
- }
-
+ texture->texture_ops->texture_cleanup_sub_resources(texture);
if (texture->overlay_info)
{
for (i = 0; i < sub_count; ++i)
return WINED3D_OK;
}
-/* In D3D the depth stencil dimensions have to be greater than or equal to the
- * render target dimensions. With FBOs, the dimensions have to be an exact match. */
-/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
-/* Context activation is done by the caller. */
-void wined3d_texture_set_compatible_renderbuffer(struct wined3d_texture *texture,
- unsigned int level, const struct wined3d_rendertarget_info *rt)
+static void texture2d_create_dc(void *object)
{
- struct wined3d_renderbuffer_entry *entry;
- const struct wined3d_gl_info *gl_info;
- unsigned int src_width, src_height;
- unsigned int width, height;
- GLuint renderbuffer = 0;
+ struct wined3d_surface *surface = object;
+ struct wined3d_context *context = NULL;
+ const struct wined3d_format *format;
+ unsigned int row_pitch, slice_pitch;
+ struct wined3d_texture *texture;
+ struct wined3d_bo_address data;
+ D3DKMT_CREATEDCFROMMEMORY desc;
+ unsigned int sub_resource_idx;
+ struct wined3d_device *device;
+ NTSTATUS status;
- gl_info = &texture->resource.device->adapter->gl_info;
- if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
- return;
+ TRACE("surface %p.\n", surface);
- if (rt && rt->resource->format->id != WINED3DFMT_NULL)
- {
- struct wined3d_texture *rt_texture;
- unsigned int rt_level;
+ texture = surface->container;
+ sub_resource_idx = surface_get_sub_resource_idx(surface);
+ device = texture->resource.device;
- if (rt->resource->type == WINED3D_RTYPE_BUFFER)
- {
- FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
- return;
- }
- rt_texture = wined3d_texture_from_resource(rt->resource);
- rt_level = rt->sub_resource_idx % rt_texture->level_count;
-
- width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level);
- height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level);
- }
- else
+ format = texture->resource.format;
+ if (!format->ddi_format)
{
- width = wined3d_texture_get_level_pow2_width(texture, level);
- height = wined3d_texture_get_level_pow2_height(texture, level);
+ WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
+ return;
}
- src_width = wined3d_texture_get_level_pow2_width(texture, level);
- src_height = wined3d_texture_get_level_pow2_height(texture, level);
+ if (device->d3d_initialized)
+ context = context_acquire(device, NULL, 0);
- /* A depth stencil smaller than the render target is not valid */
- if (width > src_width || height > src_height)
- return;
+ wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
+ wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
+ wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
+ wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+ desc.pMemory = context_map_bo_address(context, &data,
+ texture->sub_resources[sub_resource_idx].size,
+ GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ | WINED3D_MAP_WRITE);
+
+ if (context)
+ context_release(context);
+
+ desc.Format = format->ddi_format;
+ desc.Width = wined3d_texture_get_level_width(texture, surface->texture_level);
+ desc.Height = wined3d_texture_get_level_height(texture, surface->texture_level);
+ desc.Pitch = row_pitch;
+ desc.hDeviceDc = CreateCompatibleDC(NULL);
+ desc.pColorTable = NULL;
- /* Remove any renderbuffer set if the sizes match */
- if (width == src_width && height == src_height)
+ status = D3DKMTCreateDCFromMemory(&desc);
+ DeleteDC(desc.hDeviceDc);
+ if (status)
{
- texture->current_renderbuffer = NULL;
+ WARN("Failed to create DC, status %#x.\n", status);
return;
}
- /* Look if we've already got a renderbuffer of the correct dimensions */
- LIST_FOR_EACH_ENTRY(entry, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ surface->dc = desc.hDc;
+ surface->bitmap = desc.hBitmap;
+
+ TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface);
+}
+
+static void texture2d_destroy_dc(void *object)
+{
+ struct wined3d_surface *surface = object;
+ D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
+ struct wined3d_context *context = NULL;
+ struct wined3d_texture *texture;
+ struct wined3d_bo_address data;
+ unsigned int sub_resource_idx;
+ struct wined3d_device *device;
+ NTSTATUS status;
+
+ texture = surface->container;
+ sub_resource_idx = surface_get_sub_resource_idx(surface);
+ device = texture->resource.device;
+
+ if (!surface->dc)
{
- if (entry->width == width && entry->height == height)
- {
- renderbuffer = entry->id;
- texture->current_renderbuffer = entry;
- break;
- }
+ ERR("Surface %p has no DC.\n", surface);
+ return;
}
- if (!renderbuffer)
- {
- gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
- gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
- gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
- texture->resource.format->glInternal, width, height);
+ TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap);
- entry = heap_alloc(sizeof(*entry));
- entry->width = width;
- entry->height = height;
- entry->id = renderbuffer;
- list_add_head(&texture->renderbuffers, &entry->entry);
+ destroy_desc.hDc = surface->dc;
+ destroy_desc.hBitmap = surface->bitmap;
+ if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
+ ERR("Failed to destroy dc, status %#x.\n", status);
+ surface->dc = NULL;
+ surface->bitmap = NULL;
- texture->current_renderbuffer = entry;
- }
+ if (device->d3d_initialized)
+ context = context_acquire(device, NULL, 0);
- checkGLcall("set_compatible_renderbuffer");
+ wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+ context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER);
+
+ if (context)
+ context_release(context);
}
HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height,
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, texture->resource.usage);
UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
struct wined3d_texture_sub_resource *sub_resource;
+ struct wined3d_surface *surface;
DWORD valid_location = 0;
BOOL create_dib = FALSE;
return WINED3DERR_INVALIDCALL;
}
+ if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D)
+ {
+ FIXME("Not yet supported for 1D textures.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
if (texture->resource.map_count)
{
WARN("Texture is mapped.\n");
wined3d_resource_wait_idle(&texture->resource);
sub_resource = &texture->sub_resources[0];
- if (texture->dc_info && texture->dc_info[0].dc)
+ surface = sub_resource->u.surface;
+ if (surface->dc)
{
- struct wined3d_texture_idx texture_idx = {texture, 0};
-
- wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx);
+ wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface);
device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
create_dib = TRUE;
}
else
texture->target = GL_TEXTURE_2D;
- if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
+ if ((!is_power_of_two(width) || !is_power_of_two(height)) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
&& !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
{
texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED;
if (create_dib)
{
- struct wined3d_texture_idx texture_idx = {texture, 0};
-
- wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx);
+ wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
}
/* Context activation is done by the caller. */
static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
+#if !defined(STAGING_CSMT)
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
+#else /* STAGING_CSMT */
+ unsigned int sub_resource_idx, struct wined3d_context *context)
+#endif /* STAGING_CSMT */
{
struct wined3d_texture_sub_resource *sub_resource;
sub_resource = &texture->sub_resources[sub_resource_idx];
+#if !defined(STAGING_CSMT)
if (sub_resource->buffer_object)
return;
TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
sub_resource->buffer_object, texture, sub_resource_idx);
+#else /* STAGING_CSMT */
+ if (sub_resource->buffer)
+ return;
+
+ sub_resource->buffer = wined3d_device_get_bo(texture->resource.device,
+ sub_resource->size, GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context);
+
+ TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
+ sub_resource->buffer->name, texture, sub_resource_idx);
+#endif /* STAGING_CSMT */
}
static void wined3d_texture_force_reload(struct wined3d_texture *texture)
}
}
-/* Context activation is done by the caller. */
void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
{
DWORD alloc_flag = srgb ? WINED3D_TEXTURE_SRGB_ALLOCATED : WINED3D_TEXTURE_RGB_ALLOCATED;
- const struct wined3d_format *format = texture->resource.format;
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
- const struct wined3d_gl_info *gl_info = context->gl_info;
- const struct wined3d_color_key_conversion *conversion;
- GLenum internal;
-
- TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
if (!d3d_info->shader_color_key
&& !(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
if (texture->flags & alloc_flag)
return;
- if (format->conv_byte_count)
- {
- texture->flags |= WINED3D_TEXTURE_CONVERTED;
- }
- else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
- {
- texture->flags |= WINED3D_TEXTURE_CONVERTED;
- format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
- TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
- }
-
- wined3d_texture_bind_and_dirtify(texture, context, srgb);
-
- if (srgb)
- internal = format->glGammaInternal;
- else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
- && wined3d_resource_is_offscreen(&texture->resource))
- internal = format->rtInternal;
- else
- internal = format->glInternal;
-
- if (!internal)
- FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
-
- TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
-
- if (wined3d_texture_use_immutable_storage(texture, gl_info))
- wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info);
- else
- wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info);
+ texture->texture_ops->texture_prepare_texture(texture, context, srgb);
texture->flags |= alloc_flag;
}
return TRUE;
if (!wined3d_resource_allocate_sysmem(&texture->resource))
+ {
+ ERR("Failed to allocate system memory.\n");
return FALSE;
+ }
return TRUE;
case WINED3D_LOCATION_USER_MEMORY:
return TRUE;
case WINED3D_LOCATION_BUFFER:
+#if !defined(STAGING_CSMT)
wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info);
+#else /* STAGING_CSMT */
+ wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context);
+#endif /* STAGING_CSMT */
return TRUE;
case WINED3D_LOCATION_TEXTURE_RGB:
return WINED3D_OK;
}
+void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_box *box,
+ const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
+{
+ texture->texture_ops->texture_upload_data(texture, sub_resource_idx,
+ context, box, data, row_pitch, slice_pitch);
+}
+
+
/* This call just uploads data, the caller is responsible for binding the
* correct texture. */
/* Context activation is done by the caller. */
-void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
- const struct wined3d_const_bo_address *data, unsigned int src_row_pitch, unsigned int src_slice_pitch,
- unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb)
+static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data,
+ unsigned int row_pitch, unsigned int slice_pitch)
{
+ struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
+ const struct wined3d_format *format = texture->resource.format;
+ unsigned int level = sub_resource_idx % texture->level_count;
const struct wined3d_gl_info *gl_info = context->gl_info;
- unsigned int update_w = src_box->right - src_box->left;
- unsigned int update_h = src_box->bottom - src_box->top;
- unsigned int update_d = src_box->back - src_box->front;
- struct wined3d_bo_address bo;
+ const void *mem = data->addr;
void *converted_mem = NULL;
- struct wined3d_format f;
- unsigned int level;
+ unsigned int width, x, update_w;
GLenum target;
- TRACE("texture %p, sub_resource_idx %u, context %p, format %s, src_box %s, data {%#x:%p}, "
- "src_row_pitch %#x, src_slice_pitch %#x, dst_x %u, dst_y %u, dst_z %u, srgb %#x.\n",
- texture, sub_resource_idx, context, debug_d3dformat(format->id), debug_box(src_box),
- data->buffer_object, data->addr, src_row_pitch, src_slice_pitch, dst_x, dst_y, dst_z, srgb);
+ TRACE("texture %p, sub_resource_idx %u, context %p, box %p, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n",
+ texture, sub_resource_idx, context, box, data->buffer_object, data->addr, row_pitch, slice_pitch);
+
+ width = wined3d_texture_get_level_width(texture, level);
- if (texture->sub_resources[sub_resource_idx].map_count)
+ if (!box)
{
- WARN("Uploading a texture that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n");
- texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
+ x = 0;
+ update_w = width;
}
-
- if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE)
+ else
{
- update_h *= format->height_scale.numerator;
- update_h /= format->height_scale.denominator;
+ x = box->left;
+ update_w = box->right - box->left;
}
- target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
- level = sub_resource_idx % texture->level_count;
+ if (format->upload)
+ {
+ unsigned int dst_row_pitch;
- switch (target)
+ if (data->buffer_object)
+ ERR("Loading a converted texture from a PBO.\n");
+ if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+ ERR("Converting a block-based format.\n");
+
+ dst_row_pitch = update_w * format->conv_byte_count;
+
+ converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_row_pitch);
+ format->upload(data->addr, converted_mem, row_pitch, slice_pitch, dst_row_pitch, dst_row_pitch, update_w, 1, 1);
+ mem = converted_mem;
+ }
+
+ if (data->buffer_object)
{
- case GL_TEXTURE_1D_ARRAY:
- dst_y = sub_resource_idx / texture->level_count;
- update_h = 1;
- break;
- case GL_TEXTURE_2D_ARRAY:
- dst_z = sub_resource_idx / texture->level_count;
- update_d = 1;
- break;
- case GL_TEXTURE_2D_MULTISAMPLE:
- case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- FIXME("Not supported for multisample textures.\n");
- return;
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+ checkGLcall("glBindBuffer");
}
- bo.buffer_object = data->buffer_object;
- bo.addr = (BYTE *)data->addr + src_box->front * src_slice_pitch;
- if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+ target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+ if (target == GL_TEXTURE_1D_ARRAY)
{
- bo.addr += (src_box->top / format->block_height) * src_row_pitch;
- bo.addr += (src_box->left / format->block_width) * format->block_byte_count;
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count);
+
+ gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem);
+ checkGLcall("glTexSubImage2D");
+
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
else
{
- bo.addr += src_box->top * src_row_pitch;
- bo.addr += src_box->left * format->byte_count;
+ gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, x, update_w, format->glFormat, format->glType, mem);
+ checkGLcall("glTexSubImage1D");
}
- if (format->upload)
+ if (data->buffer_object)
{
- unsigned int dst_row_pitch, dst_slice_pitch;
- void *src_mem;
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+ checkGLcall("glBindBuffer");
+ }
- if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
- ERR("Converting a block-based format.\n");
+ HeapFree(GetProcessHeap(), 0, converted_mem);
+}
+
+/* Context activation is done by the caller. */
+static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_bo_address *data)
+{
+ struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
+ const struct wined3d_format *format = texture->resource.format;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_texture_sub_resource *sub_resource;
+ BYTE *temporary_mem = NULL;
+ void *mem;
+ GLenum target;
- f = *format;
- f.byte_count = format->conv_byte_count;
- format = &f;
+ sub_resource = &texture->sub_resources[sub_resource_idx];
- wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
+ if (format->conv_byte_count)
+ {
+ FIXME("Attempting to download a converted 1d texture, format %s.\n",
+ debug_d3dformat(format->id));
+ return;
+ }
+
+ target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+ if (target == GL_TEXTURE_1D_ARRAY)
+ {
+ WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n");
- if (!(converted_mem = heap_calloc(update_d, dst_slice_pitch)))
+ if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size)))
{
- ERR("Failed to allocate upload buffer.\n");
+ ERR("Out of memory.\n");
return;
}
- src_mem = context_map_bo_address(context, &bo, src_slice_pitch,
- GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
- format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch,
- dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
- context_unmap_bo_address(context, &bo, GL_PIXEL_UNPACK_BUFFER);
+ mem = temporary_mem;
+ }
+ else if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+ checkGLcall("glBindBuffer");
+ mem = data->addr;
+ }
+ else
+ mem = data->addr;
- bo.buffer_object = 0;
- bo.addr = converted_mem;
- src_row_pitch = dst_row_pitch;
- src_slice_pitch = dst_slice_pitch;
+ gl_info->gl_ops.gl.p_glGetTexImage(target, sub_resource_idx,
+ format->glFormat, format->glType, mem);
+ checkGLcall("glGetTexImage");
+
+ if (temporary_mem)
+ {
+ void *src_data = temporary_mem + surface->texture_layer * sub_resource->size;
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+ checkGLcall("glBindBuffer");
+ GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data));
+ checkGLcall("glBufferSubData");
+ }
+ else
+ {
+ memcpy(data->addr, src_data, sub_resource->size);
+ }
}
- if (bo.buffer_object)
+ if (data->buffer_object)
{
- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bo.buffer_object));
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
checkGLcall("glBindBuffer");
}
- if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
+ HeapFree(GetProcessHeap(), 0, temporary_mem);
+}
+
+/* Context activation is done by the caller. */
+static void texture1d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ struct wined3d_context *context, BOOL dest_is_srgb)
+{
+ struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+ unsigned int row_pitch, slice_pitch;
+ struct wined3d_bo_address data;
+
+ WARN_(d3d_perf)("Performing slow rgb/srgb 1d texture transfer.\n");
+ data.buffer_object = 0;
+ if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size)))
+ return;
+
+ wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+ wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
+ texture1d_download_data(texture, sub_resource_idx, context, &data);
+ wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
+ texture1d_upload_data(texture, sub_resource_idx, context, NULL,
+ wined3d_const_bo_address(&data), row_pitch, slice_pitch);
+
+ HeapFree(GetProcessHeap(), 0, data.addr);
+}
+
+/* Context activation is done by the caller. */
+static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ struct wined3d_context *context, DWORD location)
+{
+ struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+ DWORD required_access = wined3d_resource_access_from_location(location);
+ unsigned int row_pitch, slice_pitch;
+
+ TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
+ texture, sub_resource_idx, context, wined3d_debug_location(location));
+
+ TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations));
+
+ if ((sub_resource->locations & location) == location)
+ {
+ TRACE("Location(s) already up to date.\n");
+ return TRUE;
+ }
+
+ if ((texture->resource.access & required_access) != required_access)
{
- unsigned int dst_row_pitch, dst_slice_pitch;
- const BYTE *addr = bo.addr;
- GLenum internal;
+ ERR("Operation requires %#x access, but 1d texture only has %#x.\n",
+ required_access, texture->resource.access);
+ return FALSE;
+ }
- if (srgb)
- internal = format->glGammaInternal;
- else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
- && wined3d_resource_is_offscreen(&texture->resource))
- internal = format->rtInternal;
- else
- internal = format->glInternal;
+ if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
+ return FALSE;
- wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
+ if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
+ {
+ TRACE("1d texture previously discarded, nothing to do.\n");
+ wined3d_texture_validate_location(texture, sub_resource_idx, location);
+ wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED);
+ goto done;
+ }
- TRACE("Uploading compressed data, target %#x, level %u, x %u, y %u, z %u, "
- "w %u, h %u, d %u, format %#x, image_size %#x, addr %p.\n",
- target, level, dst_x, dst_y, dst_z, update_w, update_h,
- update_d, internal, dst_slice_pitch, addr);
+ switch (location)
+ {
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
+ {
+ struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
+ data.addr += sub_resource->offset;
+ wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB);
+ wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+ texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
+ }
+ else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
+ {
+#if !defined(STAGING_CSMT)
+ struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
+#else /* STAGING_CSMT */
+ struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
+ wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB);
+ wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+ texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
+ }
+ else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ {
+ texture1d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
+ }
+ else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
+ {
+ texture1d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
+ }
+ else
+ {
+ FIXME("Implement 1d texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
+ return FALSE;
+ }
+ break;
- if (target == GL_TEXTURE_1D)
- {
- GL_EXTCALL(glCompressedTexSubImage1D(target, level, dst_x,
- update_w, internal, dst_row_pitch, addr));
- }
- else if (dst_row_pitch == src_row_pitch)
- {
- if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
+ case WINED3D_LOCATION_SYSMEM:
+ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
- GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, dst_y, dst_z,
- update_w, update_h, update_d, internal, dst_slice_pitch * update_d, addr));
+ struct wined3d_bo_address data = {0, texture->resource.heap_memory};
+
+ data.addr += sub_resource->offset;
+ if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+ else
+ wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+ texture1d_download_data(texture, sub_resource_idx, context, &data);
+ ++texture->download_count;
}
else
{
- GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, dst_y,
- update_w, update_h, internal, dst_slice_pitch, addr));
+ FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
+ wined3d_debug_location(sub_resource->locations));
+ return FALSE;
}
- }
- else
- {
- unsigned int row_count = (update_h + format->block_height - 1) / format->block_height;
- unsigned int row, y, z;
+ break;
- /* glCompressedTexSubImage2D() ignores pixel store state, so we
- * can't use the unpack row length like for glTexSubImage2D. */
- for (z = dst_z; z < dst_z + update_d; ++z)
+ case WINED3D_LOCATION_BUFFER:
+ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
- for (row = 0, y = dst_y; row < row_count; ++row)
- {
- if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
- {
- GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, y, z,
- update_w, format->block_height, 1, internal, dst_row_pitch, addr));
- }
- else
- {
- GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, y,
- update_w, format->block_height, internal, dst_row_pitch, addr));
- }
-
- y += format->block_height;
- addr += src_row_pitch;
- }
+#if !defined(STAGING_CSMT)
+ struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
+#else /* STAGING_CSMT */
+ struct wined3d_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
+
+ if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+ wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+ else
+ wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+ texture1d_download_data(texture, sub_resource_idx, context, &data);
}
- }
- checkGLcall("Upload compressed texture data");
+ else
+ {
+ FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
+ wined3d_debug_location(sub_resource->locations));
+ return FALSE;
+ }
+ break;
+
+ default:
+ FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
+ wined3d_debug_location(sub_resource->locations));
+ return FALSE;
}
+
+done:
+ wined3d_texture_validate_location(texture, sub_resource_idx, location);
+
+ return TRUE;
+}
+
+static void texture1d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+ const struct wined3d_format *format = texture->resource.format;
+ unsigned int sub_count = texture->level_count * texture->layer_count;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int width;
+ GLenum internal;
+
+ wined3d_texture_bind_and_dirtify(texture, context, srgb);
+
+ if (srgb)
+ internal = format->glGammaInternal;
+ else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
+ && wined3d_resource_is_offscreen(&texture->resource))
+ internal = format->rtInternal;
else
+ internal = format->glInternal;
+
+ if (wined3d_texture_use_immutable_storage(texture, gl_info))
{
- TRACE("Uploading data, target %#x, level %u, x %u, y %u, z %u, "
- "w %u, h %u, d %u, format %#x, type %#x, addr %p.\n",
- target, level, dst_x, dst_y, dst_z, update_w, update_h,
- update_d, format->glFormat, format->glType, bo.addr);
+ width = wined3d_texture_get_level_width(texture, 0);
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_row_pitch / format->byte_count);
- if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
- {
- GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y, dst_z,
- update_w, update_h, update_d, format->glFormat, format->glType, bo.addr));
- }
- else if (target == GL_TEXTURE_1D)
+ if (texture->target == GL_TEXTURE_1D_ARRAY)
{
- gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x,
- update_w, format->glFormat, format->glType, bo.addr);
+ GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, internal, width, texture->layer_count));
+ checkGLcall("glTexStorage2D");
}
else
{
- gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y,
- update_w, update_h, format->glFormat, format->glType, bo.addr);
+ GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, internal, width));
+ checkGLcall("glTexStorage1D");
}
- gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- checkGLcall("Upload texture data");
- }
-
- if (bo.buffer_object)
- {
- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
- checkGLcall("glBindBuffer");
}
- heap_free(converted_mem);
-
- if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE)
+ else
{
- struct wined3d_device *device = texture->resource.device;
unsigned int i;
- for (i = 0; i < device->context_count; ++i)
+ for (i = 0; i < sub_count; ++i)
{
- context_texture_update(device->contexts[i], texture);
+ GLenum target;
+ struct wined3d_surface *surface = texture->sub_resources[i].u.surface;
+ width = wined3d_texture_get_level_width(texture, surface->texture_level);
+ target = wined3d_texture_get_sub_resource_target(texture, i);
+
+ if (texture->target == GL_TEXTURE_1D_ARRAY)
+ {
+ gl_info->gl_ops.gl.p_glTexImage2D(target, surface->texture_level,
+ internal, width, texture->layer_count, 0, format->glFormat, format->glType, NULL);
+ checkGLcall("glTexImage2D");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glTexImage1D(target, surface->texture_level,
+ internal, width, 0, format->glFormat, format->glType, NULL);
+ checkGLcall("glTexImage1D");
+ }
}
}
}
-/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */
+static void texture1d_cleanup_sub_resources(struct wined3d_texture *texture)
+{
+}
+
+static const struct wined3d_texture_ops texture1d_ops =
+{
+ texture1d_upload_data,
+ texture1d_load_location,
+ texture1d_prepare_texture,
+ texture1d_cleanup_sub_resources,
+};
+
+static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_box *box,
+ const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
+{
+ unsigned int texture_level;
+ POINT dst_point;
+ RECT src_rect;
+
+ src_rect.left = 0;
+ src_rect.top = 0;
+ if (box)
+ {
+ dst_point.x = box->left;
+ dst_point.y = box->top;
+ src_rect.right = box->right - box->left;
+ src_rect.bottom = box->bottom - box->top;
+ }
+ else
+ {
+ dst_point.x = dst_point.y = 0;
+ texture_level = sub_resource_idx % texture->level_count;
+ src_rect.right = wined3d_texture_get_level_width(texture, texture_level);
+ src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level);
+ }
+
+ wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info,
+ texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data);
+}
+
static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, DWORD location)
{
- TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
- texture, sub_resource_idx, context, wined3d_debug_location(location));
+ return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location);
+}
- switch (location)
+/* Context activation is done by the caller. */
+static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+ const struct wined3d_format *format = texture->resource.format;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_color_key_conversion *conversion;
+ GLenum internal;
+
+ TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
+
+ if (format->conv_byte_count)
{
- case WINED3D_LOCATION_USER_MEMORY:
- case WINED3D_LOCATION_SYSMEM:
- case WINED3D_LOCATION_BUFFER:
- return texture2d_load_sysmem(texture, sub_resource_idx, context, location);
+ texture->flags |= WINED3D_TEXTURE_CONVERTED;
+ }
+ else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
+ {
+ texture->flags |= WINED3D_TEXTURE_CONVERTED;
+ format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
+ TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
+ }
+
+ wined3d_texture_bind_and_dirtify(texture, context, srgb);
+
+ if (srgb)
+ internal = format->glGammaInternal;
+ else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
+ && wined3d_resource_is_offscreen(&texture->resource))
+ internal = format->rtInternal;
+ else
+ internal = format->glInternal;
+
+ if (!internal)
+ FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
+
+ TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
+
+ if (wined3d_texture_use_immutable_storage(texture, gl_info))
+ wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info);
+ else
+ wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info);
+}
+
+static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
+{
+ unsigned int sub_count = texture->level_count * texture->layer_count;
+ struct wined3d_device *device = texture->resource.device;
+ struct wined3d_texture_sub_resource *sub_resource;
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+ const struct wined3d_gl_info *gl_info = NULL;
+ struct wined3d_context *context = NULL;
+ struct wined3d_surface *surface;
+ unsigned int i;
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ sub_resource = &texture->sub_resources[i];
+ if (!(surface = sub_resource->u.surface))
+ continue;
- case WINED3D_LOCATION_DRAWABLE:
- return texture2d_load_drawable(texture, sub_resource_idx, context);
+ TRACE("surface %p.\n", surface);
- case WINED3D_LOCATION_RB_RESOLVED:
- case WINED3D_LOCATION_RB_MULTISAMPLE:
- return texture2d_load_renderbuffer(texture, sub_resource_idx, context, location);
+ if (!context && !list_empty(&surface->renderbuffers))
+ {
+ context = context_acquire(device, NULL, 0);
+ gl_info = context->gl_info;
+ }
- case WINED3D_LOCATION_TEXTURE_RGB:
- case WINED3D_LOCATION_TEXTURE_SRGB:
- return texture2d_load_texture(texture, sub_resource_idx, context,
- location == WINED3D_LOCATION_TEXTURE_SRGB);
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ TRACE("Deleting renderbuffer %u.\n", entry->id);
+ context_gl_resource_released(device, entry->id, TRUE);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ heap_free(entry);
+ }
- default:
- ERR("Don't know how to handle location %#x.\n", location);
- return FALSE;
+ if (surface->dc)
+ texture2d_destroy_dc(surface);
}
+ if (context)
+ context_release(context);
+ heap_free(texture->sub_resources[0].u.surface);
}
static const struct wined3d_texture_ops texture2d_ops =
{
+ texture2d_upload_data,
texture2d_load_location,
+ texture2d_prepare_texture,
+ texture2d_cleanup_sub_resources,
};
struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource)
{
struct wined3d_texture *texture = texture_from_resource(resource);
UINT sub_count = texture->level_count * texture->layer_count;
- struct wined3d_renderbuffer_entry *entry, *entry2;
struct wined3d_device *device = resource->device;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED);
}
+#if !defined(STAGING_CSMT)
if (sub_resource->buffer_object)
wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
- }
+#else /* STAGING_CSMT */
+ if (sub_resource->buffer)
+ wined3d_texture_remove_buffer_object(texture, i, context);
+#endif /* STAGING_CSMT */
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- list_remove(&entry->entry);
- heap_free(entry);
+ if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
+ {
+ struct wined3d_surface *surface = sub_resource->u.surface;
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ context_gl_resource_released(device, entry->id, TRUE);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ list_remove(&entry->entry);
+ heap_free(entry);
+ }
+ list_init(&surface->renderbuffers);
+ surface->current_renderbuffer = NULL;
+ }
}
- list_init(&texture->renderbuffers);
- texture->current_renderbuffer = NULL;
context_release(context);
texture_resource_sub_resource_unmap,
};
-/* Context activation is done by the caller. */
-static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- const struct wined3d_context *context, const struct wined3d_bo_address *data)
+static HRESULT texture1d_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent,
+ const struct wined3d_parent_ops *parent_ops)
{
- const struct wined3d_format *format = texture->resource.format;
- const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_device_parent *device_parent = device->device_parent;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_surface *surfaces;
+ unsigned int i, j;
+ HRESULT hr;
- if (format->conv_byte_count)
+ if (layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY])
{
- FIXME("Attempting to download a converted texture, format %s.\n",
- debug_d3dformat(format->id));
- return;
+ WARN("OpenGL implementation does not support array textures.\n");
+ return WINED3DERR_INVALIDCALL;
}
- if (data->buffer_object)
+ /* TODO: It should only be possible to create textures for formats
+ * that are reported as supported. */
+ if (WINED3DFMT_UNKNOWN >= desc->format)
{
- GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
- checkGLcall("glBindBuffer");
+ WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+ return WINED3DERR_INVALIDCALL;
}
- gl_info->gl_ops.gl.p_glGetTexImage(texture->target, sub_resource_idx,
- format->glFormat, format->glType, data->addr);
- checkGLcall("glGetTexImage");
-
- if (data->buffer_object)
+ if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
{
- GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
- checkGLcall("glBindBuffer");
+ WARN("1d textures can not be used for cube mapping, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
}
-}
-
-/* Context activation is done by the caller. */
-static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, DWORD location)
-{
- struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
- unsigned int row_pitch, slice_pitch;
- TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
- texture, sub_resource_idx, context, wined3d_debug_location(location));
+ if ((desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access))
+ || (desc->usage & WINED3DUSAGE_SCRATCH))
+ {
+ WARN("Attempted to create a DYNAMIC texture in pool %s.\n", wined3d_debug_resource_access(desc->access));
+ return WINED3DERR_INVALIDCALL;
+ }
- if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
- return FALSE;
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !is_power_of_two(desc->width))
+ {
+ if (desc->usage & WINED3DUSAGE_SCRATCH)
+ {
+ WARN("Creating a scratch NPOT 1d texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a NPOT 1d texture (%u, %u, %u) without GL support.\n",
+ desc->width, desc->height, desc->depth);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
- switch (location)
+ if (desc->usage & WINED3DUSAGE_QUERY_GENMIPMAP)
{
- case WINED3D_LOCATION_TEXTURE_RGB:
- case WINED3D_LOCATION_TEXTURE_SRGB:
- if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
- {
- struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
- struct wined3d_box src_box;
+ if (level_count != 1)
+ {
+ WARN("WINED3DUSAGE_QUERY_GENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
- data.addr += sub_resource->offset;
- wined3d_texture_bind_and_dirtify(texture, context,
- location == WINED3D_LOCATION_TEXTURE_SRGB);
- wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
- wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
- wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
- &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
- }
- else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
- {
- struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
- struct wined3d_box src_box;
+ if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc,
+ 0, device, parent, parent_ops, &texture_resource_ops)))
+ {
+ WARN("Failed to initialize texture, returning %#x.\n", hr);
+ return hr;
+ }
- wined3d_texture_bind_and_dirtify(texture, context,
- location == WINED3D_LOCATION_TEXTURE_SRGB);
- wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
- wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
- wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
- &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
- }
- else
- {
- FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
- return FALSE;
- }
- break;
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D;
- case WINED3D_LOCATION_SYSMEM:
- if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
- {
- struct wined3d_bo_address data = {0, texture->resource.heap_memory};
+ if (wined3d_texture_use_pbo(texture, gl_info))
+ {
+ wined3d_resource_free_sysmem(&texture->resource);
+ texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
+ }
- data.addr += sub_resource->offset;
- if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
- wined3d_texture_bind_and_dirtify(texture, context, FALSE);
- else
- wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+ if (level_count > ~(SIZE_T)0 / layer_count
+ || !(surfaces = heap_calloc(level_count * layer_count, sizeof(*surfaces))))
+ {
+ wined3d_texture_cleanup_sync(texture);
+ return E_OUTOFMEMORY;
+ }
- texture1d_download_data(texture, sub_resource_idx, context, &data);
- ++texture->download_count;
- }
- else
+ /* Generate all the surfaces. */
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < texture->layer_count; ++j)
+ {
+ struct wined3d_texture_sub_resource *sub_resource;
+ unsigned int idx = j * texture->level_count + i;
+ struct wined3d_surface *surface;
+
+ surface = &surfaces[idx];
+ surface->container = texture;
+ surface->texture_level = i;
+ surface->texture_layer = j;
+ list_init(&surface->renderbuffers);
+
+ sub_resource = &texture->sub_resources[idx];
+ sub_resource->locations = WINED3D_LOCATION_DISCARDED;
+ sub_resource->u.surface = surface;
+
+ if (FAILED(hr = device_parent->ops->surface_created(device_parent,
+ texture, idx, &sub_resource->parent, &sub_resource->parent_ops)))
{
- FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
- wined3d_debug_location(sub_resource->locations));
- return FALSE;
+ WARN("Failed to create texture1d parent, hr %#x.\n", hr);
+ sub_resource->parent = NULL;
+ wined3d_texture_cleanup_sync(texture);
+ return hr;
}
- break;
-
- case WINED3D_LOCATION_BUFFER:
- if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
- {
- struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
-
- if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
- wined3d_texture_bind_and_dirtify(texture, context, FALSE);
- else
- wined3d_texture_bind_and_dirtify(texture, context, TRUE);
- texture1d_download_data(texture, sub_resource_idx, context, &data);
- }
- else
- {
- FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
- wined3d_debug_location(sub_resource->locations));
- return FALSE;
- }
- break;
+ TRACE("parent %p, parent_ops %p.\n", parent, parent_ops);
- default:
- FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
- wined3d_debug_location(sub_resource->locations));
- return FALSE;
+ TRACE("Created 1d texture surface level %u, layer %u @ %p.\n", i, j, surface);
+ }
}
- return TRUE;
+ return WINED3D_OK;
}
-static const struct wined3d_texture_ops texture1d_ops =
-{
- texture1d_load_location,
-};
-
-static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
- void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_texture_ops *texture_ops)
+ void *parent, const struct wined3d_parent_ops *parent_ops)
{
struct wined3d_device_parent *device_parent = device->device_parent;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
- unsigned int sub_count, i, j, size, offset = 0;
- unsigned int pow2_width, pow2_height;
- const struct wined3d_format *format;
+ struct wined3d_surface *surfaces;
+ UINT pow2_width, pow2_height;
+ unsigned int i, j, sub_count;
HRESULT hr;
- TRACE("texture %p, resource_type %s, format %s, multisample_type %#x, multisample_quality %#x, "
- "usage %s, access %s, width %u, height %u, depth %u, layer_count %u, level_count %u, "
- "flags %#x, device %p, parent %p, parent_ops %p, texture_ops %p.\n",
- texture, debug_d3dresourcetype(desc->resource_type), debug_d3dformat(desc->format),
- desc->multisample_type, desc->multisample_quality, debug_d3dusage(desc->usage),
- wined3d_debug_resource_access(desc->access), desc->width, desc->height, desc->depth,
- layer_count, level_count, flags, device, parent, parent_ops, texture_ops);
-
- if (!desc->width || !desc->height || !desc->depth)
- return WINED3DERR_INVALIDCALL;
-
- if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
- {
- if (layer_count != 1)
- {
- ERR("Invalid layer count for volume texture.\n");
- return E_INVALIDARG;
- }
-
- if (!gl_info->supported[EXT_TEXTURE3D])
- {
- WARN("OpenGL implementation does not support 3D textures.\n");
- return WINED3DERR_INVALIDCALL;
- }
- }
-
if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
&& !gl_info->supported[EXT_TEXTURE_ARRAY])
{
* that are reported as supported. */
if (WINED3DFMT_UNKNOWN >= desc->format)
{
- WARN("Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access)
- || desc->usage & WINED3DUSAGE_SCRATCH))
- {
- WARN("Attempted to create a dynamic texture with access %s and usage %s.\n",
- wined3d_debug_resource_access(desc->access), debug_d3dusage(desc->usage));
+ WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
return WINED3DERR_INVALIDCALL;
}
+ if (desc->usage & WINED3DUSAGE_DYNAMIC && wined3d_resource_access_is_managed(desc->access))
+ FIXME("Trying to create a managed texture with dynamic usage.\n");
if (!(desc->usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))
&& (flags & WINED3D_TEXTURE_CREATE_MAPPABLE))
WARN("Creating a mappable texture that doesn't specify dynamic usage.\n");
pow2_width = desc->width;
pow2_height = desc->height;
- if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)) || (desc->depth & (desc->depth - 1)))
+ if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)))
&& !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
{
/* level_count == 0 returns an error as well. */
- if (level_count != 1 || layer_count != 1 || desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
+ if (level_count != 1 || layer_count != 1)
{
if (!(desc->usage & WINED3DUSAGE_SCRATCH))
{
- WARN("Attempted to create a mipmapped/cube/array/volume NPOT "
- "texture without unconditional NPOT support.\n");
+ WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n");
return WINED3DERR_INVALIDCALL;
}
}
texture->flags |= WINED3D_TEXTURE_COND_NP2;
- if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !gl_info->supported[ARB_TEXTURE_RECTANGLE]
- && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+ if (!gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
{
const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage);
* 16 and a width > 3000 and blt 16x16 letter areas from them to
* the render target. */
if (desc->access & WINED3D_RESOURCE_ACCESS_GPU)
- {
- WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
- return WINED3DERR_NOTAVAILABLE;
- }
-
- /* We should never use this surface in combination with OpenGL. */
- TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
- }
-
- format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage);
- for (i = 0; i < layer_count; ++i)
- {
- for (j = 0; j < level_count; ++j)
- {
- unsigned int idx = i * level_count + j;
-
- size = wined3d_format_calculate_size(format, device->surface_alignment,
- max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j));
- texture->sub_resources[idx].offset = offset;
- texture->sub_resources[idx].size = size;
- offset += size;
- }
- offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
- }
-
- if (!offset)
- return WINED3DERR_INVALIDCALL;
-
- if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
- desc->multisample_type, desc->multisample_quality, desc->usage, desc->access,
- desc->width, desc->height, desc->depth, offset, parent, parent_ops, &texture_resource_ops)))
- {
- static unsigned int once;
-
- /* DXTn 3D textures are not supported. Do not write the ERR for them. */
- if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3
- || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5)
- && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)
- && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++)
- ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n");
-
- WARN("Failed to initialize resource, returning %#x\n", hr);
- return hr;
- }
- wined3d_resource_update_draw_binding(&texture->resource);
- if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE)
- texture->resource.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
-
- texture->texture_ops = texture_ops;
-
- texture->layer_count = layer_count;
- texture->level_count = level_count;
- texture->lod = 0;
- texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
- if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)
- texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT;
- if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT))
- texture->flags |= WINED3D_TEXTURE_GET_DC;
- if (flags & WINED3D_TEXTURE_CREATE_DISCARD)
- texture->flags |= WINED3D_TEXTURE_DISCARD;
- if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS)
- {
- if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP))
- WARN("Format doesn't support mipmaps generation, "
- "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n");
- else
- texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS;
- }
+ {
+ WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
+ return WINED3DERR_NOTAVAILABLE;
+ }
- list_init(&texture->renderbuffers);
+ /* We should never use this surface in combination with OpenGL. */
+ TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
+ }
- switch (desc->resource_type)
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc,
+ flags, device, parent, parent_ops, &texture_resource_ops)))
{
- case WINED3D_RTYPE_TEXTURE_1D:
- if (layer_count > 1)
- texture->target = GL_TEXTURE_1D_ARRAY;
- else
- texture->target = GL_TEXTURE_1D;
- break;
-
- case WINED3D_RTYPE_TEXTURE_2D:
- if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
- {
- texture->target = GL_TEXTURE_CUBE_MAP_ARB;
- }
- else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
- {
- if (layer_count > 1)
- texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
- else
- texture->target = GL_TEXTURE_2D_MULTISAMPLE;
- }
- else
- {
- if (layer_count > 1)
- texture->target = GL_TEXTURE_2D_ARRAY;
- else
- texture->target = GL_TEXTURE_2D;
- }
- break;
-
- case WINED3D_RTYPE_TEXTURE_3D:
- texture->target = GL_TEXTURE_3D;
- break;
-
- default:
- ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
- wined3d_texture_cleanup_sync(texture);
- return WINED3DERR_INVALIDCALL;
+ WARN("Failed to initialize texture, returning %#x.\n", hr);
+ return hr;
}
/* Precalculated scaling for 'faked' non power of two texture coords. */
texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS);
texture->target = GL_TEXTURE_RECTANGLE_ARB;
}
- else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
- {
- texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
- texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
- texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
- }
else
{
- texture->pow2_matrix[0] = 1.0f;
- texture->pow2_matrix[5] = 1.0f;
+ if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
+ {
+ texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
+ texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
+ texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
+ }
+ else
+ {
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ }
+ if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+ {
+ texture->target = GL_TEXTURE_CUBE_MAP_ARB;
+ }
+ else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+ {
+ if (layer_count > 1)
+ texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+ else
+ texture->target = GL_TEXTURE_2D_MULTISAMPLE;
+ }
+ else
+ {
+ if (layer_count > 1)
+ texture->target = GL_TEXTURE_2D_ARRAY;
+ else
+ texture->target = GL_TEXTURE_2D;
+ }
}
texture->pow2_matrix[10] = 1.0f;
texture->pow2_matrix[15] = 1.0f;
if (wined3d_texture_use_pbo(texture, gl_info))
texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
- if ((desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
- && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
- || !wined3d_texture_use_pbo(texture, gl_info))
- {
- if (!wined3d_resource_allocate_sysmem(&texture->resource))
- {
- wined3d_texture_cleanup_sync(texture);
- return E_OUTOFMEMORY;
- }
- }
-
sub_count = level_count * layer_count;
- if (sub_count / layer_count != level_count)
+ if (sub_count / layer_count != level_count
+ || !(surfaces = heap_calloc(sub_count, sizeof(*surfaces))))
{
wined3d_texture_cleanup_sync(texture);
return E_OUTOFMEMORY;
{
if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info))))
{
+ heap_free(surfaces);
wined3d_texture_cleanup_sync(texture);
return E_OUTOFMEMORY;
}
}
}
- /* Generate all sub-resources. */
- for (i = 0; i < sub_count; ++i)
+ /* Generate all the surfaces. */
+ for (i = 0; i < texture->level_count; ++i)
{
- struct wined3d_texture_sub_resource *sub_resource;
-
- sub_resource = &texture->sub_resources[i];
- sub_resource->locations = WINED3D_LOCATION_DISCARDED;
- if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
- && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
+ for (j = 0; j < texture->layer_count; ++j)
{
- wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM);
- wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM);
- }
-
- if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent,
- desc->resource_type, texture, i, &sub_resource->parent, &sub_resource->parent_ops)))
- {
- WARN("Failed to create sub-resource parent, hr %#x.\n", hr);
- sub_resource->parent = NULL;
- wined3d_texture_cleanup_sync(texture);
- return hr;
- }
+ struct wined3d_texture_sub_resource *sub_resource;
+ unsigned int idx = j * texture->level_count + i;
+ struct wined3d_surface *surface;
+
+ surface = &surfaces[idx];
+ surface->container = texture;
+ surface->texture_level = i;
+ surface->texture_layer = j;
+ list_init(&surface->renderbuffers);
+
+ sub_resource = &texture->sub_resources[idx];
+ sub_resource->locations = WINED3D_LOCATION_DISCARDED;
+ sub_resource->u.surface = surface;
+ if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
+ {
+ wined3d_texture_validate_location(texture, idx, WINED3D_LOCATION_SYSMEM);
+ wined3d_texture_invalidate_location(texture, idx, ~WINED3D_LOCATION_SYSMEM);
+ }
- TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops);
+ if (FAILED(hr = device_parent->ops->surface_created(device_parent,
+ texture, idx, &sub_resource->parent, &sub_resource->parent_ops)))
+ {
+ WARN("Failed to create surface parent, hr %#x.\n", hr);
+ sub_resource->parent = NULL;
+ wined3d_texture_cleanup_sync(texture);
+ return hr;
+ }
- TRACE("Created sub-resource %u (level %u, layer %u).\n",
- i, i % texture->level_count, i / texture->level_count);
+ TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops);
- if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
- {
- struct wined3d_texture_idx texture_idx = {texture, i};
+ TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface);
- wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx);
- device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
- if (!texture->dc_info || !texture->dc_info[i].dc)
+ if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
{
- wined3d_texture_cleanup_sync(texture);
- return WINED3DERR_INVALIDCALL;
+ wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
+ device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
+ if (!surface->dc)
+ {
+ wined3d_texture_cleanup_sync(texture);
+ return WINED3DERR_INVALIDCALL;
+ }
}
}
}
return WINED3D_OK;
}
+/* This call just uploads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
+static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_box *box,
+ const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
+{
+ const struct wined3d_format *format = texture->resource.format;
+ unsigned int level = sub_resource_idx % texture->level_count;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int x, y, z, update_w, update_h, update_d;
+ unsigned int dst_row_pitch, dst_slice_pitch;
+ unsigned int width, height, depth;
+ const void *mem = data->addr;
+ void *converted_mem = NULL;
+
+ TRACE("texture %p, sub_resource_idx %u, context %p, box %s, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n",
+ texture, sub_resource_idx, context, debug_box(box),
+ data->buffer_object, data->addr, row_pitch, slice_pitch);
+
+ width = wined3d_texture_get_level_width(texture, level);
+ height = wined3d_texture_get_level_height(texture, level);
+ depth = wined3d_texture_get_level_depth(texture, level);
+
+ if (!box)
+ {
+ x = y = z = 0;
+ update_w = width;
+ update_h = height;
+ update_d = depth;
+ }
+ else
+ {
+ x = box->left;
+ y = box->top;
+ z = box->front;
+ update_w = box->right - box->left;
+ update_h = box->bottom - box->top;
+ update_d = box->back - box->front;
+ }
+
+ if (format->conv_byte_count)
+ {
+ if (data->buffer_object)
+ ERR("Loading a converted texture from a PBO.\n");
+ if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+ ERR("Converting a block-based format.\n");
+
+ dst_row_pitch = update_w * format->conv_byte_count;
+ dst_slice_pitch = dst_row_pitch * update_h;
+
+ converted_mem = heap_calloc(update_d, dst_slice_pitch);
+ format->upload(data->addr, converted_mem, row_pitch, slice_pitch,
+ dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
+ mem = converted_mem;
+ }
+ else
+ {
+ wined3d_texture_get_pitch(texture, sub_resource_idx, &dst_row_pitch, &dst_slice_pitch);
+ if (row_pitch != dst_row_pitch || slice_pitch != dst_slice_pitch)
+ FIXME("Ignoring row/slice pitch (%u/%u).\n", row_pitch, slice_pitch);
+ }
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+ checkGLcall("glBindBuffer");
+ }
+
+ GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, level, x, y, z,
+ update_w, update_h, update_d, format->glFormat, format->glType, mem));
+ checkGLcall("glTexSubImage3D");
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+ checkGLcall("glBindBuffer");
+ }
+
+ heap_free(converted_mem);
+}
+
/* Context activation is done by the caller. */
static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
const struct wined3d_context *context, const struct wined3d_bo_address *data)
struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
unsigned int row_pitch, slice_pitch;
struct wined3d_bo_address data;
- struct wined3d_box src_box;
/* Optimisations are possible, but the effort should be put into either
* implementing EXT_SRGB_DECODE in the driver or finding out why we
return;
wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
- wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
texture3d_download_data(texture, sub_resource_idx, context, &data);
wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
- wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
- &src_box, wined3d_const_bo_address(&data), row_pitch, slice_pitch, 0, 0, 0, FALSE);
+ texture3d_upload_data(texture, sub_resource_idx, context,
+ NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch);
heap_free(data.addr);
}
if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
{
struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
- struct wined3d_box src_box;
-
data.addr += sub_resource->offset;
wined3d_texture_bind_and_dirtify(texture, context,
location == WINED3D_LOCATION_TEXTURE_SRGB);
wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
- wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
- wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
- &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
+ texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
}
else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
{
+#if !defined(STAGING_CSMT)
struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
- struct wined3d_box src_box;
-
+#else /* STAGING_CSMT */
+ struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
wined3d_texture_bind_and_dirtify(texture, context,
location == WINED3D_LOCATION_TEXTURE_SRGB);
wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
- wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
- wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
- &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
+ texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
}
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
{
case WINED3D_LOCATION_BUFFER:
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
+#if !defined(STAGING_CSMT)
struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
+#else /* STAGING_CSMT */
+ struct wined3d_bo_address data = {sub_resource->buffer->name, NULL};
+#endif /* STAGING_CSMT */
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
return TRUE;
}
+static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
+{
+ const struct wined3d_format *format = texture->resource.format;
+ GLenum internal = srgb ? format->glGammaInternal : format->glInternal;
+ unsigned int sub_count = texture->level_count * texture->layer_count;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int i;
+
+ wined3d_texture_bind_and_dirtify(texture, context, srgb);
+
+ if (wined3d_texture_use_immutable_storage(texture, gl_info))
+ {
+ GL_EXTCALL(glTexStorage3D(GL_TEXTURE_3D, texture->level_count, internal,
+ wined3d_texture_get_level_width(texture, 0),
+ wined3d_texture_get_level_height(texture, 0),
+ wined3d_texture_get_level_depth(texture, 0)));
+ checkGLcall("glTexStorage3D");
+ }
+ else
+ {
+ for (i = 0; i < sub_count; ++i)
+ {
+ GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, i, internal,
+ wined3d_texture_get_level_width(texture, i),
+ wined3d_texture_get_level_height(texture, i),
+ wined3d_texture_get_level_depth(texture, i),
+ 0, format->glFormat, format->glType, NULL));
+ checkGLcall("glTexImage3D");
+ }
+ }
+}
+
+static void texture3d_cleanup_sub_resources(struct wined3d_texture *texture)
+{
+}
+
static const struct wined3d_texture_ops texture3d_ops =
{
+ texture3d_upload_data,
texture3d_load_location,
+ texture3d_prepare_texture,
+ texture3d_cleanup_sub_resources,
};
+static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT layer_count, UINT level_count, DWORD flags, struct wined3d_device *device, void *parent,
+ const struct wined3d_parent_ops *parent_ops)
+{
+ struct wined3d_device_parent *device_parent = device->device_parent;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ unsigned int i;
+ HRESULT hr;
+
+ if (layer_count != 1)
+ {
+ ERR("Invalid layer count for volume texture.\n");
+ return E_INVALIDARG;
+ }
+
+ /* TODO: It should only be possible to create textures for formats
+ * that are reported as supported. */
+ if (WINED3DFMT_UNKNOWN >= desc->format)
+ {
+ WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!gl_info->supported[EXT_TEXTURE3D])
+ {
+ WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access)
+ || desc->usage & WINED3DUSAGE_SCRATCH))
+ {
+ WARN("Attempted to create a DYNAMIC texture with access %s.\n",
+ wined3d_debug_resource_access(desc->access));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ if (!is_power_of_two(desc->width) || !is_power_of_two(desc->height) || !is_power_of_two(desc->depth))
+ {
+ if (desc->usage & WINED3DUSAGE_SCRATCH)
+ {
+ WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n",
+ desc->width, desc->height, desc->depth);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+ }
+
+ if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, level_count, desc,
+ flags, device, parent, parent_ops, &texture_resource_ops)))
+ {
+ WARN("Failed to initialize texture, returning %#x.\n", hr);
+ return hr;
+ }
+
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = GL_TEXTURE_3D;
+
+ if (wined3d_texture_use_pbo(texture, gl_info))
+ {
+ wined3d_resource_free_sysmem(&texture->resource);
+ texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
+ }
+
+ /* Generate all the sub resources. */
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_texture_sub_resource *sub_resource;
+
+ sub_resource = &texture->sub_resources[i];
+ sub_resource->locations = WINED3D_LOCATION_DISCARDED;
+
+ if (FAILED(hr = device_parent->ops->volume_created(device_parent,
+ texture, i, &sub_resource->parent, &sub_resource->parent_ops)))
+ {
+ WARN("Failed to create volume parent, hr %#x.\n", hr);
+ sub_resource->parent = NULL;
+ wined3d_texture_cleanup_sync(texture);
+ return hr;
+ }
+
+ TRACE("parent %p, parent_ops %p.\n", parent, parent_ops);
+
+ TRACE("Created volume level %u.\n", i);
+ }
+
+ return WINED3D_OK;
+}
+
HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
|| src_texture->sub_resources[src_sub_resource_idx].map_count)
{
+#if !defined(STAGING_CSMT)
WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
return WINEDDERR_SURFACEBUSY;
+#else /* STAGING_CSMT */
+ 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 && src_texture->sub_resources[src_sub_resource_idx].map_count))
+ {
+ WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
+ return WINEDDERR_SURFACEBUSY;
+ }
+#endif /* STAGING_CSMT */
}
if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
}
overlay = &texture->overlay_info[sub_resource_idx];
- if (!overlay->dst_texture)
+ if (!overlay->dst)
{
TRACE("Overlay not visible.\n");
*x = 0;
const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
const RECT *dst_rect, DWORD flags)
{
+ struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource;
+ struct wined3d_surface *surface, *dst_surface;
struct wined3d_overlay_info *overlay;
- unsigned int level, dst_level;
TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, "
"dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n",
dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), flags);
if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
- || sub_resource_idx >= texture->level_count * texture->layer_count)
+ || !(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
{
WARN("Invalid sub-resource specified.\n");
return WINEDDERR_NOTAOVERLAYSURFACE;
}
if (!dst_texture || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
- || dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count)
+ || !(dst_sub_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx)))
{
WARN("Invalid destination sub-resource specified.\n");
return WINED3DERR_INVALIDCALL;
overlay = &texture->overlay_info[sub_resource_idx];
- level = sub_resource_idx % texture->level_count;
+ surface = sub_resource->u.surface;
if (src_rect)
overlay->src_rect = *src_rect;
else
SetRect(&overlay->src_rect, 0, 0,
- wined3d_texture_get_level_width(texture, level),
- wined3d_texture_get_level_height(texture, level));
+ wined3d_texture_get_level_width(texture, surface->texture_level),
+ wined3d_texture_get_level_height(texture, surface->texture_level));
- dst_level = dst_sub_resource_idx % dst_texture->level_count;
+ dst_surface = dst_sub_resource->u.surface;
if (dst_rect)
overlay->dst_rect = *dst_rect;
else
SetRect(&overlay->dst_rect, 0, 0,
- wined3d_texture_get_level_width(dst_texture, dst_level),
- wined3d_texture_get_level_height(dst_texture, dst_level));
+ wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level),
+ wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level));
- if (overlay->dst_texture && (overlay->dst_texture != dst_texture
- || overlay->dst_sub_resource_idx != dst_sub_resource_idx || flags & WINEDDOVER_HIDE))
+ if (overlay->dst && (overlay->dst != dst_surface || flags & WINEDDOVER_HIDE))
{
- overlay->dst_texture = NULL;
+ overlay->dst = NULL;
list_remove(&overlay->entry);
}
if (flags & WINEDDOVER_SHOW)
{
- if (overlay->dst_texture != dst_texture || overlay->dst_sub_resource_idx != dst_sub_resource_idx)
+ if (overlay->dst != dst_surface)
{
- overlay->dst_texture = dst_texture;
- overlay->dst_sub_resource_idx = dst_sub_resource_idx;
+ overlay->dst = dst_surface;
list_add_tail(&texture->overlay_info[dst_sub_resource_idx].overlays, &overlay->entry);
}
}
/* Tests show that the rectangles are erased on hide. */
SetRectEmpty(&overlay->src_rect);
SetRectEmpty(&overlay->dst_rect);
- overlay->dst_texture = NULL;
+ overlay->dst = NULL;
}
return WINED3D_OK;
UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
{
- const struct wined3d_texture_ops *texture_ops;
struct wined3d_texture *object;
HRESULT hr;
}
}
+ if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
+ sub_resources[level_count * layer_count]))))
+ return E_OUTOFMEMORY;
+
switch (desc->resource_type)
{
case WINED3D_RTYPE_TEXTURE_1D:
- texture_ops = &texture1d_ops;
+ hr = texture1d_init(object, desc, layer_count, level_count, device, parent, parent_ops);
break;
+
case WINED3D_RTYPE_TEXTURE_2D:
- texture_ops = &texture2d_ops;
+ hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops);
break;
+
case WINED3D_RTYPE_TEXTURE_3D:
- texture_ops = &texture3d_ops;
+ hr = volumetexture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops);
break;
+
default:
ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
- return WINED3DERR_INVALIDCALL;
+ hr = WINED3DERR_INVALIDCALL;
+ break;
}
- if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
- sub_resources[level_count * layer_count]))))
- return E_OUTOFMEMORY;
-
- if (FAILED(hr = wined3d_texture_init(object, desc, layer_count,
- level_count, flags, device, parent, parent_ops, texture_ops)))
+ if (FAILED(hr))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
heap_free(object);
for (i = 0; i < sub_count; ++i)
{
wined3d_device_update_sub_resource(device, &object->resource,
- i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch, 0);
+ i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch);
}
}
{
struct wined3d_device *device = texture->resource.device;
struct wined3d_texture_sub_resource *sub_resource;
- struct wined3d_dc_info *dc_info;
+ struct wined3d_surface *surface;
TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
return WINED3DERR_INVALIDCALL;
}
+ surface = sub_resource->u.surface;
+
if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
return WINED3DERR_INVALIDCALL;
- if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc)
+ if (!surface->dc)
{
- struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx};
-
- wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx);
+ wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
- if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc)
- return WINED3DERR_INVALIDCALL;
}
+ if (!surface->dc)
+ return WINED3DERR_INVALIDCALL;
if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
texture->flags |= WINED3D_TEXTURE_DC_IN_USE;
++texture->resource.map_count;
++sub_resource->map_count;
- *dc = dc_info[sub_resource_idx].dc;
+ *dc = surface->dc;
TRACE("Returning dc %p.\n", *dc);
return WINED3D_OK;
{
struct wined3d_device *device = texture->resource.device;
struct wined3d_texture_sub_resource *sub_resource;
- struct wined3d_dc_info *dc_info;
+ struct wined3d_surface *surface;
TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
return WINED3DERR_INVALIDCALL;
}
+ surface = sub_resource->u.surface;
+
if (!(texture->flags & (WINED3D_TEXTURE_GET_DC_LENIENT | WINED3D_TEXTURE_DC_IN_USE)))
return WINED3DERR_INVALIDCALL;
- if (!(dc_info = texture->dc_info) || dc_info[sub_resource_idx].dc != dc)
+ if (surface->dc != dc)
{
- WARN("Application tries to release invalid DC %p, sub-resource DC is %p.\n",
- dc, dc_info ? dc_info[sub_resource_idx].dc : NULL);
+ WARN("Application tries to release invalid DC %p, surface DC is %p.\n", dc, surface->dc);
return WINED3DERR_INVALIDCALL;
}
if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D))
{
- struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx};
-
- wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx);
+ wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface);
device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
}
return WINED3D_OK;
}
-
-void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture,
- unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
-{
- unsigned int src_row_pitch, src_slice_pitch;
- unsigned int update_w, update_h, update_d;
- unsigned int src_level, dst_level;
- struct wined3d_context *context;
- struct wined3d_bo_address data;
-
- TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, "
- "src_texture %p, src_sub_resource_idx %u, src_box %s.\n",
- dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z,
- src_texture, src_sub_resource_idx, debug_box(src_box));
-
- context = context_acquire(dst_texture->resource.device, NULL, 0);
-
- /* Only load the sub-resource for partial updates. For newly allocated
- * textures the texture wouldn't be the current location, and we'd upload
- * zeroes just to overwrite them again. */
- update_w = src_box->right - src_box->left;
- update_h = src_box->bottom - src_box->top;
- update_d = src_box->back - src_box->front;
- dst_level = dst_sub_resource_idx % dst_texture->level_count;
- if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level)
- && update_h == wined3d_texture_get_level_height(dst_texture, dst_level)
- && update_d == wined3d_texture_get_level_depth(dst_texture, dst_level))
- wined3d_texture_prepare_texture(dst_texture, context, FALSE);
- else
- wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
- wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
-
- src_level = src_sub_resource_idx % src_texture->level_count;
- wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data,
- src_texture->sub_resources[src_sub_resource_idx].locations);
- wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch);
-
- wined3d_texture_upload_data(dst_texture, dst_sub_resource_idx, context, src_texture->resource.format,
- src_box, wined3d_const_bo_address(&data), src_row_pitch, src_slice_pitch, dst_x, dst_y, dst_z, FALSE);
-
- context_release(context);
-
- wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
- wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
-}
/* Bump mapping stuff */
{WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0},
{WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
{WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0},
{WINED3DFMT_R10G10B10X2_UINT, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0},
{WINED3DFMT_R10G10B10X2_SNORM, 10, 10, 10, 0, 0, 10, 20, 0, 4, 0, 0},
{WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1},
{WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
{WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4},
+ {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
+ {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
{WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
/* Vendor-specific formats */
{WINED3DFMT_ATI1N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
&& color <= color_key->color_space_high_value;
}
+static void convert_p8_uint_b8g8r8a8_unorm(const BYTE *src, unsigned int src_pitch,
+ BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
+ const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
+{
+ const BYTE *src_row;
+ unsigned int x, y;
+ DWORD *dst_row;
+
+ if (!palette)
+ {
+ /* FIXME: This should probably use the system palette. */
+ FIXME("P8 surface loaded without a palette.\n");
+
+ for (y = 0; y < height; ++y)
+ {
+ memset(&dst[dst_pitch * y], 0, width * 4);
+ }
+
+ return;
+ }
+
+ for (y = 0; y < height; ++y)
+ {
+ src_row = &src[src_pitch * y];
+ dst_row = (DWORD *)&dst[dst_pitch * y];
+ for (x = 0; x < width; ++x)
+ {
+ BYTE src_color = src_row[x];
+ dst_row[x] = 0xff000000
+ | (palette->colors[src_color].rgbRed << 16)
+ | (palette->colors[src_color].rgbGreen << 8)
+ | palette->colors[src_color].rgbBlue;
+ }
+ }
+}
+
static void convert_b5g6r5_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
- const struct wined3d_color_key *color_key)
+ const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const WORD *src_row;
unsigned int x, y;
static void convert_b5g5r5x1_unorm_b5g5r5a1_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
- const struct wined3d_color_key *color_key)
+ const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const WORD *src_row;
unsigned int x, y;
static void convert_b8g8r8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
- const struct wined3d_color_key *color_key)
+ const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const BYTE *src_row;
unsigned int x, y;
static void convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
- const struct wined3d_color_key *color_key)
+ const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const DWORD *src_row;
unsigned int x, y;
static void convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key(const BYTE *src, unsigned int src_pitch,
BYTE *dst, unsigned int dst_pitch, unsigned int width, unsigned int height,
- const struct wined3d_color_key *color_key)
+ const struct wined3d_palette *palette, const struct wined3d_color_key *color_key)
{
const DWORD *src_row;
unsigned int x, y;
{WINED3DFMT_B8G8R8X8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8x8_unorm_b8g8r8a8_unorm_color_key }},
{WINED3DFMT_B8G8R8A8_UNORM, {WINED3DFMT_B8G8R8A8_UNORM, convert_b8g8r8a8_unorm_b8g8r8a8_unorm_color_key }},
};
+ static const struct wined3d_color_key_conversion convert_p8 =
+ {
+ WINED3DFMT_B8G8R8A8_UNORM, convert_p8_uint_b8g8r8a8_unorm
+ };
if (need_alpha_ck && (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY))
{
FIXME("Color-keying not supported with format %s.\n", debug_d3dformat(format->id));
}
+ /* FIXME: This should check if the blitter backend can do P8 conversion,
+ * instead of checking for ARB_fragment_program. */
+ if (format->id == WINED3DFMT_P8_UINT
+ && !(texture->resource.device->adapter->gl_info.supported[ARB_FRAGMENT_PROGRAM]
+ && texture->swapchain && texture == texture->swapchain->front_buffer))
+ return &convert_p8;
+
return NULL;
}
GL_RGBA_INTEGER, GL_INT, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
EXT_TEXTURE_INTEGER, NULL},
+ {WINED3DFMT_R24_UNORM_X8_TYPELESS, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH,
+ ARB_DEPTH_TEXTURE, NULL},
/* Vendor-specific formats */
{WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0,
GL_RED, GL_UNSIGNED_BYTE, 0,
struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info,
struct wined3d_gl_info *gl_info, BOOL srgb_write_supported, BOOL srgb_format)
{
- GLint count, multisample_types[8];
+ GLint count, multisample_types[MAX_MULTISAMPLE_TYPES];
unsigned int i, max_log2;
GLenum target;
count = 0;
GL_EXTCALL(glGetInternalformativ(target, format->glInternal,
GL_NUM_SAMPLE_COUNTS, 1, &count));
- if (count > ARRAY_SIZE(multisample_types))
- FIXME("Unexpectedly high number of multisample types %d.\n", count);
- count = min(count, ARRAY_SIZE(multisample_types));
+ count = min(count, MAX_MULTISAMPLE_TYPES);
GL_EXTCALL(glGetInternalformativ(target, format->glInternal,
GL_SAMPLES, count, multisample_types));
checkGLcall("query sample counts");
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
- if (!gl_info->supported[APPLE_YCBCR_422] && (gl_info->supported[ARB_FRAGMENT_PROGRAM]
- || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER])))
+ if (!gl_info->supported[APPLE_YCBCR_422] && gl_info->supported[ARB_FRAGMENT_PROGRAM]
+ && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
{
idx = get_format_idx(WINED3DFMT_YUY2);
gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
}
else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM]
- && (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER])))
+ || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]))
{
idx = get_format_idx(WINED3DFMT_YUY2);
gl_info->formats[idx].glInternal = 0;
gl_info->formats[idx].glInternal = 0;
}
- if (gl_info->supported[ARB_FRAGMENT_PROGRAM]
- || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
{
idx = get_format_idx(WINED3DFMT_YV12);
format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE);
}
- if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER])
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
{
idx = get_format_idx(WINED3DFMT_P8_UINT);
gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
+ D3DSTATE_TO_STR(WINED3D_RS_DEPTHCLIP);
#undef D3DSTATE_TO_STR
default:
FIXME("Unrecognized %u render state!\n", state);
return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
if (STATE_IS_MATERIAL(state))
return "STATE_MATERIAL";
- if (STATE_IS_RASTERIZER(state))
- return "STATE_RASTERIZER";
+ if (STATE_IS_FRONTFACE(state))
+ return "STATE_FRONTFACE";
if (STATE_IS_POINTSPRITECOORDORIGIN(state))
return "STATE_POINTSPRITECOORDORIGIN";
if (STATE_IS_BASEVERTEXINDEX(state))
if (context->last_was_rhw)
{
/* Transform D3D RHW coordinates to OpenGL clip coordinates. */
- float x = state->viewports[0].x;
- float y = state->viewports[0].y;
- float w = state->viewports[0].width;
- float h = state->viewports[0].height;
+ float x = state->viewport.x;
+ float y = state->viewport.y;
+ float w = state->viewport.width;
+ float h = state->viewport.height;
float x_scale = 2.0f / w;
float x_offset = (center_offset - (2.0f * x) - w) / w;
float y_scale = flip ? 2.0f / h : 2.0f / -h;
else
{
float y_scale = flip ? -1.0f : 1.0f;
- float x_offset = center_offset / state->viewports[0].width;
+ float x_offset = center_offset / state->viewport.width;
float y_offset = flip
- ? center_offset / state->viewports[0].height
- : -center_offset / state->viewports[0].height;
+ ? center_offset / state->viewport.height
+ : -center_offset / state->viewport.height;
float z_scale = clip_control ? 1.0f : 2.0f;
float z_offset = clip_control ? 0.0f : -1.0f;
const struct wined3d_matrix projection =
b.d = state->render_states[WINED3D_RS_POINTSCALE_B];
c.d = state->render_states[WINED3D_RS_POINTSCALE_C];
- /* Always use first viewport, this path does not apply to d3d10/11 multiple viewports case. */
if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
{
- float scale_factor = state->viewports[0].height * state->viewports[0].height;
+ float scale_factor = state->viewport.height * state->viewport.height;
out_att[0] = a.f / scale_factor;
out_att[1] = b.f / scale_factor;
settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
- settings->op[i].tmp_dst = 0;
+ settings->op[i].dst = resultreg;
settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D;
- settings->op[i].projected = WINED3D_PROJECTION_NONE;
+ settings->op[i].projected = proj_none;
i++;
break;
}
{
ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
- settings->op[i].projected = WINED3D_PROJECTION_COUNT3;
+ settings->op[i].projected = proj_count3;
else if (ttff & WINED3D_TTFF_PROJECTED)
- settings->op[i].projected = WINED3D_PROJECTION_COUNT4;
+ settings->op[i].projected = proj_count4;
else
- settings->op[i].projected = WINED3D_PROJECTION_NONE;
+ settings->op[i].projected = proj_none;
}
else
{
- settings->op[i].projected = WINED3D_PROJECTION_NONE;
+ settings->op[i].projected = proj_none;
}
settings->op[i].cop = cop;
settings->op[i].aarg0 = aarg0;
settings->op[i].aarg1 = aarg1;
settings->op[i].aarg2 = aarg2;
- settings->op[i].tmp_dst = state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP;
+
+ if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
+ settings->op[i].dst = tempreg;
+ else
+ settings->op[i].dst = resultreg;
}
/* Clear unsupported stages */
{
switch (texture->target)
{
+ case GL_TEXTURE_1D:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ 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)");
+ }
+ 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_glEnable(GL_TEXTURE_1D);
+ checkGLcall("glEnable(GL_TEXTURE_1D)");
+ break;
case GL_TEXTURE_2D:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+ checkGLcall("glDisable(GL_TEXTURE_1D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
checkGLcall("glEnable(GL_TEXTURE_2D)");
break;
case GL_TEXTURE_RECTANGLE_ARB:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+ checkGLcall("glDisable(GL_TEXTURE_1D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
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_1D);
+ checkGLcall("glDisable(GL_TEXTURE_1D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
checkGLcall("glEnable(GL_TEXTURE_3D)");
break;
case GL_TEXTURE_CUBE_MAP_ARB:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+ checkGLcall("glDisable(GL_TEXTURE_1D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
}
else
{
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_1D);
+ checkGLcall("glDisable(GL_TEXTURE_1D)");
gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
checkGLcall("glEnable(GL_TEXTURE_2D)");
gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
{GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_RECTANGLE},
{GL_TEXTURE_3D, 0, GL_TEXTURE_3D},
+ {GL_TEXTURE_1D, 0, GL_TEXTURE_1D},
+ {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
+ {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D},
+ {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
+
{GL_TEXTURE_2D, 0, GL_TEXTURE_2D},
{GL_TEXTURE_2D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
{GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_2D},
{GL_TEXTURE_2D_MULTISAMPLE, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
{GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_2D_MULTISAMPLE},
{GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
-
- {GL_TEXTURE_1D, 0, GL_TEXTURE_1D},
- {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
- {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D},
- {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
};
unsigned int i;
debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id));
}
}
+#if defined(STAGING_CSMT)
wined3d_resource_release(resource);
+#endif /* STAGING_CSMT */
}
static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view,
wined3d_resource_incref(view->resource = resource);
+#if defined(STAGING_CSMT)
wined3d_resource_acquire(resource);
+#endif /* STAGING_CSMT */
wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view);
return WINED3D_OK;
desc, texture, view->format);
}
}
+#if defined(STAGING_CSMT)
wined3d_resource_release(resource);
+#endif /* STAGING_CSMT */
}
static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view,
wined3d_resource_incref(view->resource = resource);
+#if defined(STAGING_CSMT)
wined3d_resource_acquire(resource);
+#endif /* STAGING_CSMT */
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view);
return WINED3D_OK;
@ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long)
@ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr)
@ cdecl wined3d_device_copy_resource(ptr ptr ptr)
-@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr long)
+@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr)
@ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr)
@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
@ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_get_light(ptr long ptr)
@ cdecl wined3d_device_get_light_enable(ptr long ptr)
@ cdecl wined3d_device_get_material(ptr ptr)
-@ cdecl wined3d_device_get_max_frame_latency(ptr)
@ cdecl wined3d_device_get_npatch_mode(ptr)
@ cdecl wined3d_device_get_pixel_shader(ptr)
@ cdecl wined3d_device_get_predication(ptr ptr)
@ cdecl wined3d_device_get_render_state(ptr long)
@ cdecl wined3d_device_get_rendertarget_view(ptr long)
@ cdecl wined3d_device_get_sampler_state(ptr long long)
-@ cdecl wined3d_device_get_scissor_rects(ptr ptr ptr)
+@ cdecl wined3d_device_get_scissor_rect(ptr ptr)
@ cdecl wined3d_device_get_software_vertex_processing(ptr)
@ cdecl wined3d_device_get_stream_output(ptr long ptr)
@ cdecl wined3d_device_get_stream_source(ptr long ptr ptr ptr)
@ cdecl wined3d_device_get_unordered_access_view(ptr long)
@ cdecl wined3d_device_get_vertex_declaration(ptr)
@ cdecl wined3d_device_get_vertex_shader(ptr)
-@ cdecl wined3d_device_get_viewports(ptr ptr ptr)
+@ cdecl wined3d_device_get_viewport(ptr ptr)
@ cdecl wined3d_device_get_vs_cb(ptr long)
@ cdecl wined3d_device_get_vs_consts_b(ptr long long ptr)
@ cdecl wined3d_device_get_vs_consts_f(ptr long long ptr)
@ cdecl wined3d_device_set_light(ptr long ptr)
@ cdecl wined3d_device_set_light_enable(ptr long long)
@ cdecl wined3d_device_set_material(ptr ptr)
-@ cdecl wined3d_device_set_max_frame_latency(ptr long)
@ cdecl wined3d_device_set_multithreaded(ptr)
@ cdecl wined3d_device_set_npatch_mode(ptr float)
@ cdecl wined3d_device_set_pixel_shader(ptr ptr)
@ cdecl wined3d_device_set_render_state(ptr long long)
@ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long)
@ cdecl wined3d_device_set_sampler_state(ptr long long long)
-@ cdecl wined3d_device_set_scissor_rects(ptr long ptr)
+@ cdecl wined3d_device_set_scissor_rect(ptr ptr)
@ cdecl wined3d_device_set_software_vertex_processing(ptr long)
@ cdecl wined3d_device_set_stream_output(ptr long ptr long)
@ cdecl wined3d_device_set_stream_source(ptr long ptr long long)
@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long)
@ cdecl wined3d_device_set_vertex_declaration(ptr ptr)
@ cdecl wined3d_device_set_vertex_shader(ptr ptr)
-@ cdecl wined3d_device_set_viewports(ptr long ptr)
+@ cdecl wined3d_device_set_viewport(ptr ptr)
@ cdecl wined3d_device_set_vs_cb(ptr long ptr)
@ cdecl wined3d_device_set_vs_consts_b(ptr long long ptr)
@ cdecl wined3d_device_set_vs_consts_f(ptr long long ptr)
@ cdecl wined3d_device_show_cursor(ptr long)
@ cdecl wined3d_device_uninit_3d(ptr)
@ cdecl wined3d_device_uninit_gdi(ptr)
-@ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long long)
+@ cdecl wined3d_device_update_sub_resource(ptr ptr long ptr ptr long long)
@ cdecl wined3d_device_update_texture(ptr ptr ptr)
@ cdecl wined3d_device_validate_device(ptr ptr)
@ cdecl wined3d_stateblock_decref(ptr)
@ cdecl wined3d_stateblock_incref(ptr)
+@ cdecl wined3d_strictdrawing_set(long)
+
@ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr)
@ cdecl wined3d_swapchain_decref(ptr)
@ cdecl wined3d_swapchain_get_back_buffer(ptr long)
ARB_POINT_PARAMETERS,
ARB_POINT_SPRITE,
ARB_PROVOKING_VERTEX,
- ARB_SAMPLE_SHADING,
ARB_SAMPLER_OBJECTS,
ARB_SEAMLESS_CUBE_MAP,
ARB_SHADER_ATOMIC_COUNTERS,
ARB_SHADER_IMAGE_LOAD_STORE,
ARB_SHADER_IMAGE_SIZE,
ARB_SHADER_STORAGE_BUFFER_OBJECT,
- ARB_SHADER_TEXTURE_IMAGE_SAMPLES,
ARB_SHADER_TEXTURE_LOD,
ARB_SHADING_LANGUAGE_100,
ARB_SHADING_LANGUAGE_420PACK,
ARB_TRANSFORM_FEEDBACK3,
ARB_UNIFORM_BUFFER_OBJECT,
ARB_VERTEX_ARRAY_BGRA,
+ ARB_VERTEX_BLEND,
ARB_VERTEX_BUFFER_OBJECT,
ARB_VERTEX_PROGRAM,
ARB_VERTEX_SHADER,
{
TRUE, /* Multithreaded CS by default. */
FALSE, /* explicit_gl_version */
- MAKEDWORD_VERSION(4, 4), /* Default to OpenGL 4.4 */
+ MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */
TRUE, /* Use of GLSL enabled by default */
ORM_FBO, /* Use FBOs to do offscreen rendering */
PCI_VENDOR_NONE,/* PCI Vendor ID */
NULL, /* No wine logo by default */
TRUE, /* Prefer multisample textures to multisample renderbuffers. */
~0u, /* Don't force a specific sample count by default. */
+ FALSE, /* No strict draw ordering. */
FALSE, /* Don't range check relative addressing indices in float constants. */
~0U, /* No VS shader model limit by default. */
~0U, /* No HS shader model limit by default. */
if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count))
ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n",
wined3d_settings.sample_count);
+ if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size)
+ && !strcmp(buffer,"enabled"))
+ {
+ ERR_(winediag)("\"StrictDrawOrdering\" is deprecated, please use \"csmt\" instead.\n");
+ TRACE("Enforcing strict draw ordering.\n");
+ wined3d_settings.strict_draw_ordering = TRUE;
+ }
if (!get_config_key(hkey, appkey, "CheckFloatConstants", buffer, size)
&& !strcmp(buffer, "enabled"))
{
wined3d_wndproc_mutex_unlock();
}
+void CDECL wined3d_strictdrawing_set(int value)
+{
+ wined3d_settings.strict_draw_ordering = value;
+}
+
/* At process attach */
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
{
#define MAX_TGSM_REGISTERS 8192
#define MAX_VERTEX_BLENDS 4
#define MAX_VERTEX_INDEX_BLENDS 9
+#define MAX_MULTISAMPLE_TYPES 8
#define MAX_RENDER_TARGETS 8
struct min_lookup
char *logo;
unsigned int multisample_textures;
unsigned int sample_count;
+ BOOL strict_draw_ordering;
BOOL check_float_constants;
unsigned int max_sm_vs;
unsigned int max_sm_hs;
WINED3DSPR_GSINSTID,
WINED3DSPR_DEPTHOUTGE,
WINED3DSPR_DEPTHOUTLE,
- WINED3DSPR_RASTERIZER,
};
enum wined3d_data_type
#define WINED3DSI_SAMPLE_INFO_UINT 0x1
#define WINED3DSI_SAMPLER_COMPARISON_MODE 0x1
-#define WINED3DSI_PRECISE_X 0x100
-#define WINED3DSI_PRECISE_Y 0x200
-#define WINED3DSI_PRECISE_Z 0x400
-#define WINED3DSI_PRECISE_W 0x800
-#define WINED3DSI_PRECISE_XYZW (WINED3DSI_PRECISE_X | WINED3DSI_PRECISE_Y \
- | WINED3DSI_PRECISE_Z | WINED3DSI_PRECISE_W)
-#define WINED3DSI_PRECISE_SHIFT 8
-
enum wined3d_shader_rel_op
{
WINED3D_SHADER_REL_OP_GT = 1,
WINED3D_SHADER_TYPE_COMPUTE = WINED3D_SHADER_TYPE_GRAPHICS_COUNT,
WINED3D_SHADER_TYPE_COUNT,
- WINED3D_SHADER_TYPE_INVALID = WINED3D_SHADER_TYPE_COUNT,
};
struct wined3d_shader_version
DWORD point_size : 1;
DWORD vocp : 1;
DWORD input_rel_addressing : 1;
- DWORD viewport_array : 1;
- DWORD sample_mask : 1;
- DWORD padding : 14;
+ DWORD padding : 16;
DWORD rt_mask; /* Used render targets, 32 max. */
extern const struct wined3d_shader_frontend sm1_shader_frontend DECLSPEC_HIDDEN;
extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN;
-enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code,
- size_t byte_code_size) DECLSPEC_HIDDEN;
-
typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
#define WINED3D_SHADER_CAP_VS_CLIPPING 0x00000001
WINED3D_GL_RES_TYPE_COUNT = 7,
};
-enum wined3d_vertex_processing_mode
-{
- WINED3D_VP_MODE_FF,
- WINED3D_VP_MODE_SHADER,
- WINED3D_VP_MODE_NONE,
+enum vertexprocessing_mode {
+ fixedfunction,
+ vertexshader,
+ pretransformed
};
#define WINED3D_CONST_NUM_UNUSED ~0U
struct ps_compile_args
{
struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];
- enum wined3d_vertex_processing_mode vp_mode;
+ enum vertexprocessing_mode vp_mode;
enum wined3d_ffp_ps_fog_mode fog;
WORD tex_transform; /* ps 1.0-1.3, 4 textures */
WORD tex_types; /* ps 1.0 - 1.4, 6 textures */
struct gs_compile_args
{
unsigned int output_count;
- enum wined3d_primitive_type primitive_type;
DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE];
};
#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIP_DISTANCES))
#define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL)
-#define STATE_RASTERIZER (STATE_MATERIAL + 1)
-#define STATE_IS_RASTERIZER(a) ((a) == STATE_RASTERIZER)
+#define STATE_FRONTFACE (STATE_MATERIAL + 1)
+#define STATE_IS_FRONTFACE(a) ((a) == STATE_FRONTFACE)
-#define STATE_POINTSPRITECOORDORIGIN (STATE_RASTERIZER + 1)
+#define STATE_POINTSPRITECOORDORIGIN (STATE_FRONTFACE + 1)
#define STATE_IS_POINTSPRITECOORDORIGIN(a) ((a) == STATE_POINTSPRITECOORDORIGIN)
#define STATE_BASEVERTEXINDEX (STATE_POINTSPRITECOORDORIGIN + 1)
DWORD last_was_vshader : 1;
DWORD last_was_normal : 1;
DWORD namedArraysLoaded : 1;
- DWORD last_was_ffp_blit : 1;
+ DWORD numberedArraysLoaded : 1;
DWORD last_was_blit : 1;
DWORD last_was_ckey : 1;
DWORD fog_coord : 1;
DWORD current : 1;
DWORD destroyed : 1;
DWORD valid : 1;
-
DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */
DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */
DWORD fixed_function_usage_map : 8; /* MAX_TEXTURES, 8 */
DWORD rebind_fbo : 1;
DWORD needs_set : 1;
DWORD hdc_is_private : 1;
-
DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */
DWORD update_shader_resource_bindings : 1;
DWORD update_compute_shader_resource_bindings : 1;
DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
DWORD last_was_dual_blend : 1;
DWORD padding : 8;
-
DWORD constant_update_mask;
- DWORD numbered_array_mask;
+ DWORD numbered_array_mask;
GLenum tracking_parm; /* Which source is tracking current colour */
GLenum untracked_materials[2];
UINT blit_w, blit_h;
struct wined3d_fence *buffer_fences[MAX_ATTRIBS];
unsigned int buffer_fence_count;
- GLuint blit_vbo;
-
DWORD tex_unit_map[MAX_COMBINED_SAMPLERS];
DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS];
GLfloat fog_coord_value;
GLfloat color[4], fogstart, fogend, fogcolor[4];
GLuint dummy_arbfp_prog;
-
- unsigned int viewport_count;
- unsigned int scissor_rect_count;
};
struct wined3d_fb_state
const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
+struct wined3d_surface;
+
enum wined3d_blit_op
{
WINED3D_BLIT_OP_COLOR_BLIT,
unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects,
const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil);
DWORD (*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, const struct wined3d_color_key *colour_key,
- enum wined3d_texture_filter_type filter);
+ 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);
};
void wined3d_arbfp_blitter_create(struct wined3d_blitter **next,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_ffp_blitter_create(struct wined3d_blitter **next,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
-struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next,
- const struct wined3d_device *device) DECLSPEC_HIDDEN;
void wined3d_raw_blitter_create(struct wined3d_blitter **next,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN;
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) DECLSPEC_HIDDEN;
-void context_apply_ffp_blit_state(struct wined3d_context *context,
- const struct wined3d_device *device) DECLSPEC_HIDDEN;
+ struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN;
void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info,
unsigned int unit) DECLSPEC_HIDDEN;
void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) DECLSPEC_HIDDEN;
const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN;
void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
-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) DECLSPEC_HIDDEN;
-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) DECLSPEC_HIDDEN;
void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN;
void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN;
void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
-void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
- GLuint *current_bo, const struct wined3d_state *state) DECLSPEC_HIDDEN;
void *context_map_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data,
size_t size, GLenum binding, DWORD flags) DECLSPEC_HIDDEN;
struct wined3d_context *context_reacquire(const struct wined3d_device *device,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
-void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
-void context_restore(struct wined3d_context *context, struct wined3d_texture *texture,
- unsigned int sub_resource_idx) DECLSPEC_HIDDEN;
+void context_resource_released(const struct wined3d_device *device,
+ struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
+void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN;
BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void context_state_fb(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
-void context_texture_update(struct wined3d_context *context, const struct wined3d_texture *texture) DECLSPEC_HIDDEN;
-void context_unload_tex_coords(const struct wined3d_context *context) DECLSPEC_HIDDEN;
+void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void context_unmap_bo_address(struct wined3d_context *context,
const struct wined3d_bo_address *data, GLenum binding) DECLSPEC_HIDDEN;
-void context_update_stream_sources(struct wined3d_context *context,
- const struct wined3d_state *state) DECLSPEC_HIDDEN;
/*****************************************************************************
* Internal representation of a light
CARD_NVIDIA_GEFORCE_GTX980 = 0x13c0,
CARD_NVIDIA_GEFORCE_GTX980TI = 0x17c8,
CARD_NVIDIA_GEFORCE_GTX1050 = 0x1c81,
- CARD_NVIDIA_GEFORCE_GTX1050TI = 0x1c82,
CARD_NVIDIA_GEFORCE_GTX1060 = 0x1c03,
CARD_NVIDIA_GEFORCE_GTX1070 = 0x1b81,
CARD_NVIDIA_GEFORCE_GTX1080 = 0x1b80,
CARD_NVIDIA_GEFORCE_GTX1080TI = 0x1b06,
CARD_NVIDIA_TITANX_PASCAL = 0x1b00,
- CARD_NVIDIA_TITANV = 0x1d81,
CARD_VMWARE_SVGA3D = 0x0405,
UINT texture3d_size;
float pointsize_max;
float pointsize_min;
+ UINT blends;
UINT anisotropy;
float shininess;
UINT samples;
void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext) DECLSPEC_HIDDEN;
-enum wined3d_projection_type
+enum projection_types
{
- WINED3D_PROJECTION_NONE = 0,
- WINED3D_PROJECTION_COUNT3 = 1,
- WINED3D_PROJECTION_COUNT4 = 2
+ proj_none = 0,
+ proj_count3 = 1,
+ proj_count4 = 2
+};
+
+enum dst_arg
+{
+ resultreg = 0,
+ tempreg = 1
};
/*****************************************************************************
struct color_fixup_desc color_fixup;
unsigned tex_type : 3;
- unsigned tmp_dst : 1;
+ unsigned dst : 1;
unsigned projected : 2;
unsigned padding : 10;
};
struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1];
struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES];
struct wined3d_material material;
- struct wined3d_viewport viewports[WINED3D_MAX_VIEWPORTS];
- unsigned int viewport_count;
- RECT scissor_rects[WINED3D_MAX_VIEWPORTS];
- unsigned int scissor_rect_count;
+ struct wined3d_viewport viewport;
+ RECT scissor_rect;
/* Light hashmap. Collisions are handled using linked lists. */
#define LIGHTMAP_SIZE 43
struct wined3d_dummy_textures
{
- GLuint tex_1d;
GLuint tex_2d;
+ GLuint tex_1d;
GLuint tex_rect;
GLuint tex_3d;
GLuint tex_cube;
GLuint tex_cube_array;
- GLuint tex_1d_array;
GLuint tex_2d_array;
+ GLuint tex_1d_array;
GLuint tex_buffer;
GLuint tex_2d_ms;
GLuint tex_2d_ms_array;
};
+#if defined(STAGING_CSMT)
+struct wined3d_gl_bo
+{
+ GLuint name;
+ GLenum usage;
+ GLenum type_hint;
+ UINT size;
+};
+
+#endif /* STAGING_CSMT */
#define WINED3D_UNMAPPED_STAGE ~0u
/* Multithreaded flag. Removed from the public header to signal that
APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];
struct wined3d_blitter *blitter;
+ BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
BYTE bCursorVisible : 1;
BYTE d3d_initialized : 1;
BYTE inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */
BYTE softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */
BYTE filter_messages : 1;
- BYTE padding : 3;
+ BYTE padding : 2;
unsigned char surface_alignment; /* Line Alignment of surfaces */
struct wined3d_rendertarget_view *back_buffer_view;
struct wined3d_swapchain **swapchains;
UINT swapchain_count;
- unsigned int max_frame_latency;
struct list resources; /* a linked list to track resources created by the device */
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
+#if defined(STAGING_CSMT)
+struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage,
+ GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo,
+ const struct wined3d_context *context) DECLSPEC_HIDDEN;
+#endif /* STAGING_CSMT */
static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
{
GLuint name;
};
-struct wined3d_blt_info
-{
- GLenum bind_target;
- struct wined3d_vec3 texcoords[4];
-};
-
struct wined3d_texture_ops
{
+ void (*texture_upload_data)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ const struct wined3d_context *context, const struct wined3d_box *box,
+ const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch);
BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, DWORD location);
+ void (*texture_prepare_texture)(struct wined3d_texture *texture,
+ struct wined3d_context *context, BOOL srgb);
+ void (*texture_cleanup_sub_resources)(struct wined3d_texture *texture);
};
#define WINED3D_TEXTURE_COND_NP2 0x00000001
{
struct list entry;
struct list overlays;
- struct wined3d_texture *dst_texture;
- unsigned int dst_sub_resource_idx;
+ struct wined3d_surface *dst;
RECT src_rect;
RECT dst_rect;
} *overlay_info;
- struct wined3d_dc_info
- {
- HBITMAP bitmap;
- HDC dc;
- } *dc_info;
-
- struct list renderbuffers;
- const struct wined3d_renderbuffer_entry *current_renderbuffer;
-
struct wined3d_texture_sub_resource
{
void *parent;
const struct wined3d_parent_ops *parent_ops;
+ union
+ {
+ struct wined3d_surface *surface;
+ } u;
unsigned int offset;
unsigned int size;
unsigned int map_count;
DWORD locations;
+#if !defined(STAGING_CSMT)
GLuint buffer_object;
+#else /* STAGING_CSMT */
+ struct wined3d_gl_bo *buffer;
+#endif /* STAGING_CSMT */
} sub_resources[1];
};
return max(1, texture->pow2_height >> level);
}
-static inline void wined3d_texture_get_level_box(const struct wined3d_texture *texture,
- unsigned int level, struct wined3d_box *box)
-{
- wined3d_box_set(box, 0, 0,
- wined3d_texture_get_level_width(texture, level),
- wined3d_texture_get_level_height(texture, level),
- 0, wined3d_texture_get_level_depth(texture, level));
-}
-
-HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- const struct wined3d_box *dst_box, struct wined3d_texture *src_texture,
- unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags,
- const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
-void texture2d_get_blt_info(const struct wined3d_texture *texture, unsigned int sub_resource_idx,
- const RECT *rect, struct wined3d_blt_info *info) DECLSPEC_HIDDEN;
-BOOL texture2d_load_drawable(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context) DECLSPEC_HIDDEN;
-void texture2d_load_fb_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN;
-BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, DWORD dst_location) DECLSPEC_HIDDEN;
-BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, DWORD dst_location) DECLSPEC_HIDDEN;
-BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
-
void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture,
const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context) DECLSPEC_HIDDEN;
void wined3d_texture_bind(struct wined3d_texture *texture,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_texture(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
-void wined3d_texture_set_compatible_renderbuffer(struct wined3d_texture *texture,
- unsigned int level, const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN;
void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
-void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture,
- HWND window, RECT *rect) DECLSPEC_HIDDEN;
void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
- struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
- const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch,
- unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb) DECLSPEC_HIDDEN;
-void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
- unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture,
- unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN;
+ const struct wined3d_context *context, const struct wined3d_box *box,
+ const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) DECLSPEC_HIDDEN;
void wined3d_texture_validate_location(struct wined3d_texture *texture,
unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
} key;
};
+struct wined3d_surface
+{
+ struct wined3d_texture *container;
+
+ unsigned int texture_level;
+ unsigned int texture_layer;
+
+ /* For GetDC */
+ HBITMAP bitmap;
+ HDC dc;
+
+ struct list renderbuffers;
+ const struct wined3d_renderbuffer_entry *current_renderbuffer;
+};
+
+static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
+{
+ return surface->texture_layer * surface->container->level_count + surface->texture_level;
+}
+
+static inline struct wined3d_texture_sub_resource *surface_get_sub_resource(struct wined3d_surface *surface)
+{
+ return &surface->container->sub_resources[surface_get_sub_resource_idx(surface)];
+}
+
+HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
+ const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
+ struct wined3d_context *context) DECLSPEC_HIDDEN;
+BOOL surface_load_location(struct wined3d_surface *surface,
+ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
+void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
+ const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
+void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
+void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point,
+ BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
+
+void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect,
+ enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
+
struct wined3d_sampler
{
struct wine_rb_entry entry;
struct wined3d_cs_ops
{
+#if defined(STAGING_CSMT)
BOOL (*check_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id);
+#endif /* STAGING_CSMT */
void *(*require_space)(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id);
void (*submit)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id);
void (*finish)(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id);
void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN;
void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
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) DECLSPEC_HIDDEN;
+ const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) DECLSPEC_HIDDEN;
UINT sampler_idx, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx,
enum wined3d_sampler_state state, DWORD value) DECLSPEC_HIDDEN;
-void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type,
struct wined3d_shader *shader) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx,
unsigned int initial_count) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs,
struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN;
-void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count, const struct wined3d_viewport *viewports) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;
void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource,
unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch,
struct wined3d_view_desc desc;
};
+static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface(
+ const struct wined3d_rendertarget_view *view)
+{
+ struct wined3d_texture *texture;
+
+ if (!view || view->resource->type != WINED3D_RTYPE_TEXTURE_2D)
+ return NULL;
+
+ texture = texture_from_resource(view->resource);
+
+ return texture->sub_resources[view->sub_resource_idx].u.surface;
+}
+
void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view,
const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN;
void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view,
const struct wined3d_format *ds_format;
struct wined3d_palette *palette;
RECT front_buffer_update;
- unsigned int swap_interval;
- unsigned int max_frame_latency;
LONG prev_time, frames; /* Performance tracking */
};
void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN;
-void wined3d_swapchain_set_swap_interval(struct wined3d_swapchain *swapchain,
- unsigned int swap_interval) DECLSPEC_HIDDEN;
struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
-void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain,
- const struct wined3d_device *device) DECLSPEC_HIDDEN;
+void swapchain_update_swap_interval(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
/*****************************************************************************
* Utility function prototypes
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN;
-enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type) DECLSPEC_HIDDEN;
/* Math utils */
void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
/* oPos */
return FALSE;
- case WINED3DSPR_CONSTBOOL: /* b# */
case WINED3DSPR_DEPTHOUT: /* oDepth */
case WINED3DSPR_DEPTHOUTGE:
case WINED3DSPR_DEPTHOUTLE:
+ case WINED3DSPR_CONSTBOOL: /* b# */
case WINED3DSPR_LOOP: /* aL */
case WINED3DSPR_PREDICATE: /* p0 */
case WINED3DSPR_PRIMID: /* primID */
- case WINED3DSPR_SAMPLEMASK: /* oMask */
return TRUE;
case WINED3DSPR_MISCTYPE:
}
static inline void shader_get_position_fixup(const struct wined3d_context *context,
- const struct wined3d_state *state, unsigned int fixup_count, float *position_fixup)
+ const struct wined3d_state *state, float *position_fixup)
{
float center_offset;
- unsigned int i;
if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER)
center_offset = 63.0f / 64.0f;
else
center_offset = -1.0f / 64.0f;
- for (i = 0; i < fixup_count; ++i)
- {
- position_fixup[4 * i ] = 1.0f;
- position_fixup[4 * i + 1] = 1.0f;
- position_fixup[4 * i + 2] = center_offset / state->viewports[i].width;
- position_fixup[4 * i + 3] = -center_offset / state->viewports[i].height;
+ position_fixup[0] = 1.0f;
+ position_fixup[1] = 1.0f;
+ position_fixup[2] = center_offset / state->viewport.width;
+ position_fixup[3] = -center_offset / state->viewport.height;
- if (context->render_offscreen)
- {
- position_fixup[4 * i + 1] *= -1.0f;
- position_fixup[4 * i + 3] *= -1.0f;
- }
+ if (context->render_offscreen)
+ {
+ position_fixup[1] *= -1.0f;
+ position_fixup[3] *= -1.0f;
}
}
struct wined3d_color_key_conversion
{
enum wined3d_format_id dst_format;
- void (*convert)(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch,
- unsigned int width, unsigned int height, const struct wined3d_color_key *colour_key);
+ void (*convert)(const BYTE *src, unsigned int src_pitch, BYTE *dst, unsigned int dst_pitch, unsigned int width,
+ unsigned int height, const struct wined3d_palette *palette, const struct wined3d_color_key *color_key);
};
struct wined3d_format
}
}
+static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context)
+{
+ struct wined3d_texture *texture = context->current_rt.texture;
+
+ if (!texture)
+ return NULL;
+ return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
+}
+
static inline void wined3d_from_cs(const struct wined3d_cs *cs)
{
if (cs->thread)
The following libraries are shared with Wine.
dll/directx/wine/amstream # Synced to WineStaging-3.9
-dll/directx/wine/d3d8 # Synced to WineStaging-3.9
-dll/directx/wine/d3d9 # Synced to WineStaging-3.9
-dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-4.0
+dll/directx/wine/d3d8 # Synced to WineStaging-3.3
+dll/directx/wine/d3d9 # Synced to WineStaging-3.3
+dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-3.3
dll/directx/wine/d3drm # Synced to WineStaging-4.0
dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0
dll/directx/wine/d3dxof # Synced to WineStaging-3.17
-dll/directx/wine/ddraw # Synced to WineStaging-3.9
+dll/directx/wine/ddraw # Synced to WineStaging-3.3
dll/directx/wine/devenum # Synced to WineStaging-3.9
dll/directx/wine/dinput # Synced to WineStaging-4.0
dll/directx/wine/dinput8 # Synced to WineStaging-3.3
dll/directx/wine/msdmo # Synced to WineStaging-3.17
dll/directx/wine/qedit # Synced to WineStaging-3.17
dll/directx/wine/quartz # Synced to WineStaging-3.9
-dll/directx/wine/wined3d # Synced to WineStaging-3.9
+dll/directx/wine/wined3d # Synced to WineStaging-3.3
dll/win32/activeds # Synced to WineStaging-3.3
dll/win32/actxprxy # Synced to WineStaging-3.3
WINED3D_RS_SRCBLENDALPHA = 207,
WINED3D_RS_DESTBLENDALPHA = 208,
WINED3D_RS_BLENDOPALPHA = 209,
- WINED3D_RS_DEPTHBIASCLAMP = 210,
- WINED3D_RS_COLORWRITEENABLE4 = 211,
- WINED3D_RS_COLORWRITEENABLE5 = 212,
- WINED3D_RS_COLORWRITEENABLE6 = 213,
- WINED3D_RS_COLORWRITEENABLE7 = 214,
+ WINED3D_RS_DEPTHCLIP = 210,
+ WINED3D_RS_DEPTHBIASCLAMP = 211,
+ WINED3D_RS_COLORWRITEENABLE4 = 212,
+ WINED3D_RS_COLORWRITEENABLE5 = 213,
+ WINED3D_RS_COLORWRITEENABLE6 = 214,
+ WINED3D_RS_COLORWRITEENABLE7 = 215,
};
#define WINEHIGHEST_RENDER_STATE WINED3D_RS_COLORWRITEENABLE7
WINED3D_SWAP_EFFECT_OVERLAY,
};
-enum wined3d_swap_interval
-{
- WINED3D_SWAP_INTERVAL_IMMEDIATE = 0,
- WINED3D_SWAP_INTERVAL_ONE = 1,
- WINED3D_SWAP_INTERVAL_TWO = 2,
- WINED3D_SWAP_INTERVAL_THREE = 3,
- WINED3D_SWAP_INTERVAL_FOUR = 4,
- WINED3D_SWAP_INTERVAL_DEFAULT = ~0u,
-};
-
enum wined3d_sampler_state
{
WINED3D_SAMP_ADDRESS_U = 1,
WINED3D_TSS_ALPHA_ARG0 = 15,
WINED3D_TSS_RESULT_ARG = 16,
WINED3D_TSS_CONSTANT = 17,
- WINED3D_TSS_INVALID = ~0u,
+ WINED3D_TSS_INVALID = ~0U,
};
#define WINED3D_HIGHEST_TEXTURE_STATE WINED3D_TSS_CONSTANT
#define WINED3DPRESENT_RATE_DEFAULT 0x00000000
+#define WINED3DPRESENT_INTERVAL_DEFAULT 0x00000000
+#define WINED3DPRESENT_INTERVAL_ONE 0x00000001
+#define WINED3DPRESENT_INTERVAL_TWO 0x00000002
+#define WINED3DPRESENT_INTERVAL_THREE 0x00000004
+#define WINED3DPRESENT_INTERVAL_FOUR 0x00000008
+#define WINED3DPRESENT_INTERVAL_IMMEDIATE 0x80000000
+
#define WINED3DCLIPPLANE0 (1u << 0)
#define WINED3DCLIPPLANE1 (1u << 1)
#define WINED3DCLIPPLANE2 (1u << 2)
#define WINED3D_NO_PRIMITIVE_RESTART 0x00000800
#define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000
#define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000
+#define WINED3D_REQUEST_D3D10 0x00004000
+#define WINED3D_LIMIT_VIEWPORT 0x00008000
#define WINED3D_RESZ_CODE 0x7fa05000
#define WINED3D_VIEW_TEXTURE_CUBE 0x00000008
#define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010
-#define WINED3D_MAX_VIEWPORTS 16
-
struct wined3d_display_mode
{
UINT width;
struct wined3d_swapchain_desc
{
- unsigned int backbuffer_width;
- unsigned int backbuffer_height;
+ UINT backbuffer_width;
+ UINT backbuffer_height;
enum wined3d_format_id backbuffer_format;
- unsigned int backbuffer_count;
+ UINT backbuffer_count;
DWORD backbuffer_usage;
enum wined3d_multisample_type multisample_type;
DWORD multisample_quality;
BOOL enable_auto_depth_stencil;
enum wined3d_format_id auto_depth_stencil_format;
DWORD flags;
- unsigned int refresh_rate;
+ UINT refresh_rate;
+ UINT swap_interval;
BOOL auto_restore_display_mode;
};
DWORD Caps;
DWORD Caps2;
DWORD Caps3;
+ DWORD PresentationIntervals;
DWORD CursorCaps;
DWORD DevCaps;
struct wined3d_rasterizer_state_desc
{
BOOL front_ccw;
- BOOL depth_clip;
};
struct wined3d_sampler_desc
void (__cdecl *wined3d_device_created)(struct wined3d_device_parent *device_parent, struct wined3d_device *device);
void (__cdecl *mode_changed)(struct wined3d_device_parent *device_parent);
void (__cdecl *activate)(struct wined3d_device_parent *device_parent, BOOL activate);
- HRESULT (__cdecl *texture_sub_resource_created)(struct wined3d_device_parent *device_parent,
- enum wined3d_resource_type type, struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *texture, unsigned int sub_resource_idx,
+ void **parent, const struct wined3d_parent_ops **parent_ops);
+ HRESULT (__cdecl *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);
HRESULT (__cdecl *create_swapchain_texture)(struct wined3d_device_parent *device_parent, void *parent,
const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture);
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);
void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device,
struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav);
HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
UINT light_idx, struct wined3d_light *light);
HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable);
void __cdecl wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material);
-unsigned int __cdecl wined3d_device_get_max_frame_latency(const struct wined3d_device *device);
float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device);
struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device);
struct wined3d_query * __cdecl wined3d_device_get_predication(struct wined3d_device *device, BOOL *value);
unsigned int view_idx);
DWORD __cdecl wined3d_device_get_sampler_state(const struct wined3d_device *device,
UINT sampler_idx, enum wined3d_sampler_state state);
-void __cdecl wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count,
- RECT *rect);
+void __cdecl wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect);
BOOL __cdecl wined3d_device_get_software_vertex_processing(const struct wined3d_device *device);
struct wined3d_buffer * __cdecl wined3d_device_get_stream_output(struct wined3d_device *device,
UINT idx, UINT *offset);
const struct wined3d_device *device, unsigned int idx);
struct wined3d_vertex_declaration * __cdecl wined3d_device_get_vertex_declaration(const struct wined3d_device *device);
struct wined3d_shader * __cdecl wined3d_device_get_vertex_shader(const struct wined3d_device *device);
-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);
struct wined3d_buffer * __cdecl wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx);
HRESULT __cdecl wined3d_device_get_vs_consts_b(const struct wined3d_device *device,
unsigned int start_idx, unsigned int count, BOOL *constants);
UINT light_idx, const struct wined3d_light *light);
HRESULT __cdecl wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable);
void __cdecl wined3d_device_set_material(struct wined3d_device *device, const struct wined3d_material *material);
-void __cdecl wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int max_frame_latency);
void __cdecl wined3d_device_set_multithreaded(struct wined3d_device *device);
HRESULT __cdecl wined3d_device_set_npatch_mode(struct wined3d_device *device, float segments);
void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader);
unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport);
void __cdecl wined3d_device_set_sampler_state(struct wined3d_device *device,
UINT sampler_idx, enum wined3d_sampler_state state, DWORD value);
-void __cdecl wined3d_device_set_scissor_rects(struct wined3d_device *device,
- unsigned int rect_count, const RECT *rect);
+void __cdecl wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect);
void __cdecl wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software);
void __cdecl wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx,
struct wined3d_buffer *buffer, UINT offset);
void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device,
struct wined3d_vertex_declaration *declaration);
void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader);
-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);
void __cdecl wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer);
HRESULT __cdecl wined3d_device_set_vs_consts_b(struct wined3d_device *device,
unsigned int start_idx, unsigned int count, const BOOL *constants);
HRESULT __cdecl wined3d_device_uninit_gdi(struct wined3d_device *device);
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);
HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device,
struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture);
HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes);
HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
struct wined3d_raster_status *raster_status);
ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain);
-HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RECT *src_rect,
- const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags);
+HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD swap_interval, DWORD flags);
HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count,
unsigned int width, unsigned int height, enum wined3d_format_id format_id,
enum wined3d_multisample_type multisample_type, unsigned int multisample_quality);