LONG device_state;
/* Avoids recursion with nested ReleaseRef to 0 */
BOOL inDestruction;
+
+ /* The d3d8 API supports only one implicit swapchain (no D3DCREATE_ADAPTERGROUP_DEVICE,
+ * no GetSwapchain, GetBackBuffer doesn't accept a swapchain number). */
+ struct d3d8_swapchain *implicit_swapchain;
};
HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter,
{
IDirect3DVolume8 IDirect3DVolume8_iface;
struct d3d8_resource resource;
- struct wined3d_volume *wined3d_volume;
+ struct wined3d_texture *wined3d_texture;
+ unsigned int sub_resource_idx;
struct d3d8_texture *texture;
};
-void volume_init(struct d3d8_volume *volume, struct d3d8_texture *texture,
- struct wined3d_volume *wined3d_volume, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void volume_init(struct d3d8_volume *volume, struct wined3d_texture *wined3d_texture,
+ unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
struct d3d8_swapchain
{
{
IDirect3DSurface8 IDirect3DSurface8_iface;
struct d3d8_resource resource;
- struct wined3d_surface *wined3d_surface;
+ struct wined3d_texture *wined3d_texture;
+ unsigned int sub_resource_idx;
struct list rtv_entry;
struct wined3d_rendertarget_view *wined3d_rtv;
IDirect3DDevice8 *parent_device;
};
struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8_surface *surface) DECLSPEC_HIDDEN;
-void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
- struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void surface_init(struct d3d8_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+ const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
struct d3d8_vertexbuffer
present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
}
-static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
+static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
const D3DPRESENT_PARAMETERS *present_parameters)
{
+ if (!present_parameters->SwapEffect || present_parameters->SwapEffect > D3DSWAPEFFECT_COPY_VSYNC)
+ {
+ WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect);
+ return FALSE;
+ }
+ if (present_parameters->BackBufferCount > 3
+ || ((present_parameters->SwapEffect == D3DSWAPEFFECT_COPY
+ || present_parameters->SwapEffect == D3DSWAPEFFECT_COPY_VSYNC)
+ && present_parameters->BackBufferCount > 1))
+ {
+ WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
+ return FALSE;
+ }
+
swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval;
swapchain_desc->auto_restore_display_mode = TRUE;
+
+ return TRUE;
}
/* Handle table functions */
wined3d_mutex_lock();
hr = wined3d_device_set_cursor_properties(device->wined3d_device,
- hotspot_x, hotspot_y, bitmap_impl->wined3d_surface);
+ hotspot_x, hotspot_y, bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
}
wined3d_mutex_unlock();
- wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
+ if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters))
+ return D3DERR_INVALIDCALL;
if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
*swapchain = &object->IDirect3DSwapChain8_iface;
present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
WARN("App not active, returning D3DERR_DEVICELOST.\n");
return D3DERR_DEVICELOST;
}
+ if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters))
+ return D3DERR_INVALIDCALL;
wined3d_mutex_lock();
device->index_buffer_size = 0;
}
- wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
NULL, reset_enum_callback, TRUE)))
{
const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
{
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
- HRESULT hr;
TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region);
- if (device->device_state != D3D8_DEVICE_STATE_OK)
- return D3DERR_DEVICELOST;
-
- wined3d_mutex_lock();
- hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
- dst_window_override, dirty_region, 0);
- wined3d_mutex_unlock();
-
- return hr;
+ /* Fraps does not hook IDirect3DDevice8::Present regardless of the hotpatch
+ * attribute. It only hooks IDirect3DSwapChain8::Present. Yet it properly
+ * shows a framerate on Windows in applications that only call the device
+ * method, like e.g. the dx8 sdk samples. The conclusion is that native
+ * calls the swapchain's public method from the device. */
+ return IDirect3DSwapChain8_Present(&device->implicit_swapchain->IDirect3DSwapChain8_iface,
+ src_rect, dst_rect, dst_window_override, dirty_region);
}
static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface,
UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer)
{
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
- struct wined3d_surface *wined3d_surface = NULL;
+ struct wined3d_swapchain *wined3d_swapchain;
+ struct wined3d_resource *wined3d_resource;
+ struct wined3d_texture *wined3d_texture;
struct d3d8_surface *surface_impl;
- HRESULT hr;
TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
iface, backbuffer_idx, backbuffer_type, backbuffer);
+ /* backbuffer_type is ignored by native. */
+
+ /* No need to check for backbuffer == NULL, Windows crashes in that case. */
wined3d_mutex_lock();
- hr = wined3d_device_get_back_buffer(device->wined3d_device, 0, backbuffer_idx,
- (enum wined3d_backbuffer_type)backbuffer_type, &wined3d_surface);
- if (SUCCEEDED(hr) && wined3d_surface && backbuffer)
+
+ wined3d_swapchain = device->implicit_swapchain->wined3d_swapchain;
+ if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(wined3d_swapchain, backbuffer_idx)))
{
- surface_impl = wined3d_surface_get_parent(wined3d_surface);
- *backbuffer = &surface_impl->IDirect3DSurface8_iface;
- IDirect3DSurface8_AddRef(*backbuffer);
+ wined3d_mutex_unlock();
+ *backbuffer = NULL;
+ return D3DERR_INVALIDCALL;
}
- wined3d_mutex_unlock();
- return hr;
+ wined3d_resource = wined3d_texture_get_sub_resource(wined3d_texture, 0);
+ surface_impl = wined3d_resource_get_parent(wined3d_resource);
+ *backbuffer = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*backbuffer);
+
+ wined3d_mutex_unlock();
+ return D3D_OK;
}
static HRESULT WINAPI d3d8_device_GetRasterStatus(IDirect3DDevice8 *iface, D3DRASTER_STATUS *raster_status)
* destination texture is in WINED3D_POOL_DEFAULT. */
wined3d_mutex_lock();
- wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
+ wined3d_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
{
src_w = wined3d_desc.width;
src_h = wined3d_desc.height;
- wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
+ wined3d_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
{
if (!rect_count && !src_rects && !dst_points)
{
RECT rect = {0, 0, src_w, src_h};
- wined3d_surface_blt(dst->wined3d_surface, &rect,
- src->wined3d_surface, &rect, 0, NULL, WINED3D_TEXF_POINT);
+ wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &rect,
+ src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT);
}
else
{
RECT dst_rect = {dst_points[i].x, dst_points[i].y,
dst_points[i].x + w, dst_points[i].y + h};
- wined3d_surface_blt(dst->wined3d_surface, &dst_rect,
- src->wined3d_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+ wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect,
+ src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
}
}
else
UINT h = src_rects[i].bottom - src_rects[i].top;
RECT dst_rect = {0, 0, w, h};
- wined3d_surface_blt(dst->wined3d_surface, &dst_rect,
- src->wined3d_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+ wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect,
+ src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
}
}
}
}
wined3d_mutex_lock();
- hr = wined3d_device_get_front_buffer_data(device->wined3d_device, 0, dst_impl->wined3d_surface);
+ hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain->wined3d_swapchain,
+ dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
return D3DERR_NOTFOUND;
}
original_surface = wined3d_rendertarget_view_get_sub_resource_parent(original_rtv);
- wined3d_resource = wined3d_surface_get_resource(original_surface->wined3d_surface);
+ wined3d_resource = wined3d_texture_get_sub_resource(original_surface->wined3d_texture, original_surface->sub_resource_idx);
}
else
- wined3d_resource = wined3d_surface_get_resource(rt_impl->wined3d_surface);
+ wined3d_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx);
wined3d_resource_get_desc(wined3d_resource, &rt_desc);
- wined3d_resource = wined3d_surface_get_resource(ds_impl->wined3d_surface);
+ wined3d_resource = wined3d_texture_get_sub_resource(ds_impl->wined3d_texture, ds_impl->sub_resource_idx);
wined3d_resource_get_desc(wined3d_resource, &ds_desc);
if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height)
if (ds_desc.multisample_type != rt_desc.multisample_type
|| ds_desc.multisample_quality != rt_desc.multisample_quality)
{
- WARN("Multisample settings do not match, returing D3DERR_INVALIDCALL\n");
+ WARN("Multisample settings do not match, returning D3DERR_INVALIDCALL\n");
wined3d_mutex_unlock();
return D3DERR_INVALIDCALL;
}
static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
- void *container_parent, struct wined3d_surface *surface, void **parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *surface, void **parent,
const struct wined3d_parent_ops **parent_ops)
{
struct d3d8_surface *d3d_surface;
- TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
- device_parent, container_parent, surface, parent, parent_ops);
+ TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, surface %p, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, surface, parent, parent_ops);
if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
return E_OUTOFMEMORY;
- surface_init(d3d_surface, container_parent, surface, parent_ops);
+ surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
*parent = d3d_surface;
TRACE("Created surface %p.\n", d3d_surface);
}
static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
- void *container_parent, struct wined3d_volume *volume, void **parent,
- const struct wined3d_parent_ops **parent_ops)
+ 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, container_parent %p, volume %p, parent %p, parent_ops %p.\n",
- device_parent, container_parent, volume, parent, 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);
if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume))))
return E_OUTOFMEMORY;
- volume_init(d3d_volume, container_parent, volume, parent_ops);
+ volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
*parent = d3d_volume;
TRACE("Created volume %p.\n", d3d_volume);
return D3D_OK;
}
-static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
+static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
{
struct d3d8_device *device = device_from_device_parent(device_parent);
- struct wined3d_resource_desc texture_desc;
struct d3d8_surface *d3d_surface;
- struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
- device_parent, container_parent, desc, surface);
+ TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
+ device_parent, container_parent, desc, texture);
- texture_desc = *desc;
- texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
- if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1,
- WINED3D_SURFACE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
+ if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1,
+ WINED3D_SURFACE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
- wined3d_surface_incref(*surface);
- wined3d_texture_decref(texture);
-
- d3d_surface = wined3d_surface_get_parent(*surface);
+ d3d_surface = wined3d_resource_get_parent(wined3d_texture_get_sub_resource(*texture, 0));
d3d_surface->parent_device = &device->IDirect3DDevice8_iface;
return hr;
device_parent_activate,
device_parent_surface_created,
device_parent_volume_created,
- device_parent_create_swapchain_surface,
+ device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
{
struct wined3d_swapchain_desc swapchain_desc;
+ struct wined3d_swapchain *wined3d_swapchain;
HRESULT hr;
device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
if (flags & D3DCREATE_MULTITHREADED)
wined3d_device_set_multithreaded(device->wined3d_device);
- wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, parameters);
+ if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, parameters))
+ {
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ return D3DERR_INVALIDCALL;
+ }
hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc);
if (FAILED(hr))
goto err;
}
+ wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
+ device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain);
+
device->d3d_parent = &parent->IDirect3D8_iface;
IDirect3D8_AddRef(device->d3d_parent);
static HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFIID riid, void **out)
{
- TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualGUID(riid, &IID_IDirect3DSurface8)
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
- wined3d_surface_incref(surface->wined3d_surface);
+ wined3d_texture_incref(surface->wined3d_texture);
wined3d_mutex_unlock();
}
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
- wined3d_surface_decref(surface->wined3d_surface);
+ wined3d_texture_decref(surface->wined3d_texture);
wined3d_mutex_unlock();
if (parent_device)
{
struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
struct wined3d_resource_desc wined3d_desc;
- struct wined3d_resource *wined3d_resource;
+ struct wined3d_resource *sub_resource;
TRACE("iface %p, desc %p.\n", iface, desc);
wined3d_mutex_lock();
- wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
- wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
wined3d_mutex_unlock();
desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
{
struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ struct wined3d_box box;
struct wined3d_map_desc map_desc;
HRESULT hr;
return D3DERR_INVALIDCALL;
}
+ box.left = rect->left;
+ box.top = rect->top;
+ box.right = rect->right;
+ box.bottom = rect->bottom;
+ box.front = 0;
+ box.back = 1;
}
- hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx,
+ &map_desc, rect ? &box : NULL, flags);
wined3d_mutex_unlock();
if (SUCCEEDED(hr))
TRACE("iface %p.\n", iface);
wined3d_mutex_lock();
- hr = wined3d_surface_unmap(surface->wined3d_surface);
+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
wined3d_mutex_unlock();
switch(hr)
surface_wined3d_object_destroyed,
};
-void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
- struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
+void surface_init(struct d3d8_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+ const struct wined3d_parent_ops **parent_ops)
{
IDirect3DBaseTexture8 *texture;
surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
d3d8_resource_init(&surface->resource);
surface->resource.refcount = 0;
- surface->wined3d_surface = wined3d_surface;
list_init(&surface->rtv_entry);
- surface->container = container_parent;
+ surface->container = wined3d_texture_get_parent(wined3d_texture);
+ surface->wined3d_texture = wined3d_texture;
+ surface->sub_resource_idx = sub_resource_idx;
- if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
+ if (surface->container && SUCCEEDED(IUnknown_QueryInterface(surface->container,
&IID_IDirect3DBaseTexture8, (void **)&texture)))
{
surface->texture = unsafe_impl_from_IDirect3DBaseTexture8(texture);
if (surface->wined3d_rtv)
return surface->wined3d_rtv;
- if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(surface->wined3d_surface,
- surface, &d3d8_view_wined3d_parent_ops, &surface->wined3d_rtv)))
+ if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture,
+ surface->sub_resource_idx, surface, &d3d8_view_wined3d_parent_ops, &surface->wined3d_rtv)))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
return NULL;
UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer)
{
struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
- struct wined3d_surface *wined3d_surface = NULL;
+ struct wined3d_resource *wined3d_resource;
+ struct wined3d_texture *wined3d_texture;
struct d3d8_surface *surface_impl;
HRESULT hr = D3D_OK;
TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
iface, backbuffer_idx, backbuffer_type, backbuffer);
+ /* backbuffer_type is ignored by native. */
+
+ if (!backbuffer)
+ {
+ WARN("The output pointer is NULL, returning D3DERR_INVALIDCALL.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
wined3d_mutex_lock();
- if ((wined3d_surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain,
- backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type)))
+ if ((wined3d_texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx)))
{
- surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ wined3d_resource = wined3d_texture_get_sub_resource(wined3d_texture, 0);
+ surface_impl = wined3d_resource_get_parent(wined3d_resource);
*backbuffer = &surface_impl->IDirect3DSurface8_iface;
IDirect3DSurface8_AddRef(*backbuffer);
}
else
{
+ /* Do not set *backbuffer = NULL, see tests/device.c, test_swapchain(). */
hr = D3DERR_INVALIDCALL;
}
wined3d_mutex_unlock();
WORD stream = 0;
int offset = 0;
- TRACE("d3d8_elements %p, wined3d_elements %p\n", d3d8_elements, wined3d_elements);
+ TRACE("d3d8_elements %p, d3d8_elements_size %p, wined3d_elements %p\n", d3d8_elements, d3d8_elements_size, wined3d_elements);
/* 128 should be enough for anyone... */
*wined3d_elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * sizeof(**wined3d_elements));
static HRESULT WINAPI d3d8_volume_QueryInterface(IDirect3DVolume8 *iface, REFIID riid, void **out)
{
- TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualGUID(riid, &IID_IDirect3DVolume8)
|| IsEqualGUID(riid, &IID_IUnknown))
{
struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
struct wined3d_resource_desc wined3d_desc;
- struct wined3d_resource *wined3d_resource;
+ struct wined3d_resource *sub_resource;
TRACE("iface %p, desc %p.\n", iface, desc);
wined3d_mutex_lock();
- wined3d_resource = wined3d_volume_get_resource(volume->wined3d_volume);
- wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ sub_resource = wined3d_texture_get_sub_resource(volume->wined3d_texture, volume->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
wined3d_mutex_unlock();
desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
iface, locked_box, box, flags);
wined3d_mutex_lock();
- hr = wined3d_volume_map(volume->wined3d_volume, &map_desc, (const struct wined3d_box *)box, flags);
+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx,
+ &map_desc, (const struct wined3d_box *)box, flags);
wined3d_mutex_unlock();
locked_box->RowPitch = map_desc.row_pitch;
TRACE("iface %p.\n", iface);
wined3d_mutex_lock();
- hr = wined3d_volume_unmap(volume->wined3d_volume);
+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
volume_wined3d_object_destroyed,
};
-void volume_init(struct d3d8_volume *volume, struct d3d8_texture *texture,
- struct wined3d_volume *wined3d_volume, const struct wined3d_parent_ops **parent_ops)
+void volume_init(struct d3d8_volume *volume, struct wined3d_texture *wined3d_texture,
+ unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops)
{
volume->IDirect3DVolume8_iface.lpVtbl = &d3d8_volume_vtbl;
d3d8_resource_init(&volume->resource);
volume->resource.refcount = 0;
- volume->wined3d_volume = wined3d_volume;
- volume->texture = texture;
+ volume->texture = wined3d_texture_get_parent(wined3d_texture);
+ volume->wined3d_texture = wined3d_texture;
+ volume->sub_resource_idx = sub_resource_idx;
*parent_ops = &d3d8_volume_wined3d_parent_ops;
}
LONG device_state;
BOOL in_destruction;
BOOL in_scene;
+
+ UINT implicit_swapchain_count;
+ struct d3d9_swapchain **implicit_swapchains;
};
HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d,
{
IDirect3DVolume9 IDirect3DVolume9_iface;
struct d3d9_resource resource;
- struct wined3d_volume *wined3d_volume;
+ struct wined3d_texture *wined3d_texture;
+ unsigned int sub_resource_idx;
struct d3d9_texture *texture;
};
-void volume_init(struct d3d9_volume *volume, struct d3d9_texture *texture,
- struct wined3d_volume *wined3d_volume, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void volume_init(struct d3d9_volume *volume, struct wined3d_texture *wined3d_texture,
+ unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
struct d3d9_swapchain
{
{
IDirect3DSurface9 IDirect3DSurface9_iface;
struct d3d9_resource resource;
+ struct wined3d_texture *wined3d_texture;
+ unsigned int sub_resource_idx;
struct wined3d_surface *wined3d_surface;
struct list rtv_entry;
struct wined3d_rendertarget_view *wined3d_rtv;
};
struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN;
-void surface_init(struct d3d9_surface *surface, IUnknown *container_parent,
+void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN;
present_parameters->PresentationInterval = swapchain_desc->swap_interval;
}
-static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
- const D3DPRESENT_PARAMETERS *present_parameters)
+static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
+ const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended)
{
+ D3DSWAPEFFECT highest_swapeffect = extended ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_COPY;
+ UINT highest_bb_count = extended ? 30 : 3;
+
+ if (!present_parameters->SwapEffect || present_parameters->SwapEffect > highest_swapeffect)
+ {
+ WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect);
+ return FALSE;
+ }
+ if (present_parameters->BackBufferCount > highest_bb_count
+ || (present_parameters->SwapEffect == D3DSWAPEFFECT_COPY
+ && present_parameters->BackBufferCount > 1))
+ {
+ WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
+ return FALSE;
+ }
+
swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
swapchain_desc->swap_interval = present_parameters->PresentationInterval;
swapchain_desc->auto_restore_display_mode = TRUE;
+
+ return TRUE;
}
static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out)
if (device->index_buffer)
wined3d_buffer_decref(device->index_buffer);
+ HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
+
wined3d_device_uninit_3d(device->wined3d_device);
wined3d_device_release_focus_window(device->wined3d_device);
wined3d_device_decref(device->wined3d_device);
wined3d_mutex_lock();
hr = wined3d_device_set_cursor_properties(device->wined3d_device,
- hotspot_x, hotspot_y, bitmap_impl->wined3d_surface);
+ hotspot_x, hotspot_y, bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
}
wined3d_mutex_unlock();
- wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
+ if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters,
+ device->d3d_parent->extended))
+ return D3DERR_INVALIDCALL;
if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
*swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface;
present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
UINT swapchain_idx, IDirect3DSwapChain9 **swapchain)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- struct wined3d_swapchain *wined3d_swapchain;
- struct d3d9_swapchain *swapchain_impl;
HRESULT hr;
TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain);
wined3d_mutex_lock();
- if ((wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, swapchain_idx)))
+ if (swapchain_idx < device->implicit_swapchain_count)
{
- swapchain_impl = wined3d_swapchain_get_parent(wined3d_swapchain);
- *swapchain = (IDirect3DSwapChain9 *)&swapchain_impl->IDirect3DSwapChain9Ex_iface;
- IDirect3DSwapChain9Ex_AddRef(*swapchain);
- hr = D3D_OK;
+ *swapchain = (IDirect3DSwapChain9 *)&device->implicit_swapchains[swapchain_idx]->IDirect3DSwapChain9Ex_iface;
+ IDirect3DSwapChain9Ex_AddRef(*swapchain);
+ hr = D3D_OK;
}
else
{
return D3D_OK;
}
+static HRESULT d3d9_device_get_swapchains(struct d3d9_device *device)
+{
+ UINT i, new_swapchain_count = wined3d_device_get_swapchain_count(device->wined3d_device);
+ struct wined3d_swapchain *wined3d_swapchain;
+
+ if (!(device->implicit_swapchains = HeapAlloc(GetProcessHeap(), 0,
+ new_swapchain_count * sizeof(*device->implicit_swapchains))))
+ return E_OUTOFMEMORY;
+
+ for (i = 0; i < new_swapchain_count; ++i)
+ {
+ wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i);
+ device->implicit_swapchains[i] = wined3d_swapchain_get_parent(wined3d_swapchain);
+ }
+ device->implicit_swapchain_count = new_swapchain_count;
+
+ return D3D_OK;
+}
+
static HRESULT d3d9_device_reset(struct d3d9_device *device,
D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
{
wined3d_mode.scanline_ordering = mode->ScanLineOrdering;
}
+ if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters,
+ device->d3d_parent->extended))
+ return D3DERR_INVALIDCALL;
+
wined3d_mutex_lock();
if (device->vertex_buffer)
device->index_buffer_size = 0;
}
- wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
mode ? &wined3d_mode : NULL, reset_enum_callback, !device->d3d_parent->extended)))
{
- struct wined3d_swapchain *wined3d_swapchain;
+ HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
- wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
- wined3d_swapchain_get_desc(wined3d_swapchain, &swapchain_desc);
- present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width;
- present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height;
- present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc.backbuffer_format);
- present_parameters->BackBufferCount = swapchain_desc.backbuffer_count;
+ if (FAILED(hr = d3d9_device_get_swapchains(device)))
+ {
+ device->device_state = D3D9_DEVICE_STATE_NOT_RESET;
+ }
+ else
+ {
+ 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;
+ present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc.backbuffer_format);
+ present_parameters->BackBufferCount = swapchain_desc.backbuffer_count;
- device->device_state = D3D9_DEVICE_STATE_OK;
+ device->device_state = D3D9_DEVICE_STATE_OK;
+ }
}
else if (!device->d3d_parent->extended)
{
const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ UINT i;
HRESULT hr;
TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
return device->d3d_parent->extended ? S_PRESENT_OCCLUDED : D3DERR_DEVICELOST;
wined3d_mutex_lock();
- hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
- dst_window_override, dirty_region, 0);
+ for (i = 0; i < device->implicit_swapchain_count; ++i)
+ {
+ hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, src_rect,
+ dst_rect, dst_window_override, dirty_region, 0);
+ if (FAILED(hr))
+ {
+ wined3d_mutex_unlock();
+ return hr;
+ }
+ }
wined3d_mutex_unlock();
- return hr;
+ return D3D_OK;
}
static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT swapchain,
UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
- struct wined3d_surface *wined3d_surface = NULL;
- struct d3d9_surface *surface_impl;
HRESULT hr;
TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
iface, swapchain, backbuffer_idx, backbuffer_type, backbuffer);
+ /* backbuffer_type is ignored by native. */
+
+ /* No need to check for backbuffer == NULL, Windows crashes in that case. */
+ *backbuffer = NULL;
+
wined3d_mutex_lock();
- hr = wined3d_device_get_back_buffer(device->wined3d_device, swapchain,
- backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type, &wined3d_surface);
- if (SUCCEEDED(hr) && wined3d_surface && backbuffer)
+ if (swapchain >= device->implicit_swapchain_count)
{
- surface_impl = wined3d_surface_get_parent(wined3d_surface);
- *backbuffer = &surface_impl->IDirect3DSurface9_iface;
- IDirect3DSurface9_AddRef(*backbuffer);
+ wined3d_mutex_unlock();
+ WARN("Swapchain index %u is out of range, returning D3DERR_INVALIDCALL.\n", swapchain);
+ return D3DERR_INVALIDCALL;
}
+
+ hr = IDirect3DSwapChain9Ex_GetBackBuffer(&device->implicit_swapchains[swapchain]->IDirect3DSwapChain9Ex_iface,
+ backbuffer_idx, backbuffer_type, backbuffer);
wined3d_mutex_unlock();
return hr;
}
+
static HRESULT WINAPI d3d9_device_GetRasterStatus(IDirect3DDevice9Ex *iface,
UINT swapchain, D3DRASTER_STATUS *raster_status)
{
{
struct d3d9_surface *rt_impl = unsafe_impl_from_IDirect3DSurface9(render_target);
struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *sub_resource;
HRESULT hr;
TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, render_target, dst_surface);
wined3d_mutex_lock();
- hr = wined3d_surface_get_render_target_data(dst_impl->wined3d_surface, rt_impl->wined3d_surface);
+ sub_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+
+ /* TODO: Check surface sizes, pools, etc. */
+ if (wined3d_desc.multisample_type)
+ hr = D3DERR_INVALIDCALL;
+ else
+ hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, NULL,
+ rt_impl->wined3d_texture, rt_impl->sub_resource_idx, NULL, 0, NULL, WINED3D_TEXF_POINT);
wined3d_mutex_unlock();
return hr;
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface);
- HRESULT hr;
+ HRESULT hr = D3DERR_INVALIDCALL;
TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, swapchain, dst_surface);
wined3d_mutex_lock();
- hr = wined3d_device_get_front_buffer_data(device->wined3d_device, swapchain, dst_impl->wined3d_surface);
+ if (swapchain < device->implicit_swapchain_count)
+ hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchains[swapchain]->wined3d_swapchain,
+ dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
HRESULT hr = D3DERR_INVALIDCALL;
struct wined3d_resource_desc src_desc, dst_desc;
- struct wined3d_resource *wined3d_resource;
+ struct wined3d_resource *sub_resource;
TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
iface, src_surface, src_rect, dst_surface, dst_rect, filter);
wined3d_mutex_lock();
- wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
- wined3d_resource_get_desc(wined3d_resource, &dst_desc);
+ sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &dst_desc);
- wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
- wined3d_resource_get_desc(wined3d_resource, &src_desc);
+ sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &src_desc);
if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
{
}
}
- hr = wined3d_surface_blt(dst->wined3d_surface, dst_rect, src->wined3d_surface, src_rect, 0, NULL, filter);
+ hr = wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, dst_rect,
+ src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter);
if (hr == WINEDDERR_INVALIDRECT)
hr = D3DERR_INVALIDCALL;
wined3d_mutex_lock();
- wined3d_resource = wined3d_surface_get_resource(surface_impl->wined3d_surface);
+ if (!(wined3d_resource = wined3d_texture_get_sub_resource(surface_impl->wined3d_texture, surface_impl->sub_resource_idx)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
wined3d_resource_get_desc(wined3d_resource, &desc);
if (desc.pool != WINED3D_POOL_DEFAULT)
const RGNDATA *dirty_region, DWORD flags)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ UINT i;
HRESULT hr;
TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
return S_PRESENT_OCCLUDED;
wined3d_mutex_lock();
- hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
- dst_window_override, dirty_region, flags);
+ for (i = 0; i < device->implicit_swapchain_count; ++i)
+ {
+ if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, src_rect,
+ dst_rect, dst_window_override, dirty_region, flags)))
+ {
+ wined3d_mutex_unlock();
+ return hr;
+ }
+ }
wined3d_mutex_unlock();
- return hr;
+ return D3D_OK;
}
static HRESULT WINAPI d3d9_device_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
struct wined3d_swapchain_desc swapchain_desc;
- struct wined3d_swapchain *swapchain;
TRACE("iface %p, dst_window %p.\n", iface, dst_window);
wined3d_mutex_lock();
- swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
- wined3d_swapchain_get_desc(swapchain, &swapchain_desc);
+ wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc);
wined3d_mutex_unlock();
if (swapchain_desc.windowed)
}
static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
- void *container_parent, struct wined3d_surface *surface, void **parent,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *surface, void **parent,
const struct wined3d_parent_ops **parent_ops)
{
struct d3d9_surface *d3d_surface;
- TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
- device_parent, container_parent, surface, parent, parent_ops);
+ TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, surface %p, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, surface, parent, parent_ops);
if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
return E_OUTOFMEMORY;
- surface_init(d3d_surface, container_parent, surface, parent_ops);
+ surface_init(d3d_surface, wined3d_texture, sub_resource_idx, surface, parent_ops);
*parent = d3d_surface;
TRACE("Created surface %p.\n", d3d_surface);
}
static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
- void *container_parent, struct wined3d_volume *volume, void **parent,
- const struct wined3d_parent_ops **parent_ops)
+ 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, container_parent %p, volume %p, parent %p, parent_ops %p.\n",
- device_parent, container_parent, volume, parent, 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);
if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume))))
return E_OUTOFMEMORY;
- volume_init(d3d_volume, container_parent, volume, parent_ops);
+ volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
*parent = d3d_volume;
TRACE("Created volume %p.\n", d3d_volume);
return D3D_OK;
}
-static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
+static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
{
struct d3d9_device *device = device_from_device_parent(device_parent);
- struct wined3d_resource_desc texture_desc;
struct d3d9_surface *d3d_surface;
- struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
- device_parent, container_parent, desc, surface);
+ TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
+ device_parent, container_parent, desc, texture);
if (container_parent == device_parent)
container_parent = &device->IDirect3DDevice9Ex_iface;
- texture_desc = *desc;
- texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
- if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1,
- WINED3D_SURFACE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
+ if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1,
+ WINED3D_SURFACE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
- wined3d_surface_incref(*surface);
- wined3d_texture_decref(texture);
-
- d3d_surface = wined3d_surface_get_parent(*surface);
+ d3d_surface = wined3d_resource_get_parent(wined3d_texture_get_sub_resource(*texture, 0));
d3d_surface->parent_device = &device->IDirect3DDevice9Ex_iface;
return hr;
device_parent_activate,
device_parent_surface_created,
device_parent_volume_created,
- device_parent_create_swapchain_surface,
+ device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
if (!swapchain_desc)
{
ERR("Failed to allocate wined3d parameters.\n");
+ wined3d_device_release_focus_window(device->wined3d_device);
wined3d_device_decref(device->wined3d_device);
wined3d_mutex_unlock();
return E_OUTOFMEMORY;
for (i = 0; i < count; ++i)
{
- wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], ¶meters[i]);
+ if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], ¶meters[i],
+ parent->extended))
+ {
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ HeapFree(GetProcessHeap(), 0, swapchain_desc);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
}
hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc);
return hr;
}
- wined3d_mutex_unlock();
+ if (FAILED(hr = d3d9_device_get_swapchains(device)))
+ {
+ wined3d_device_uninit_3d(device->wined3d_device);
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ return E_OUTOFMEMORY;
+ }
for (i = 0; i < count; ++i)
{
present_parameters_from_wined3d_swapchain_desc(¶meters[i], &swapchain_desc[i]);
}
+
+ wined3d_mutex_unlock();
+
HeapFree(GetProcessHeap(), 0, swapchain_desc);
/* Initialize the converted declaration array. This creates a valid pointer
{
ERR("Failed to allocate FVF vertex declaration map memory.\n");
wined3d_mutex_lock();
+ HeapFree(GetProcessHeap(), 0, device->implicit_swapchains);
wined3d_device_uninit_3d(device->wined3d_device);
wined3d_device_release_focus_window(device->wined3d_device);
wined3d_device_decref(device->wined3d_device);
static HRESULT WINAPI d3d9_query_QueryInterface(IDirect3DQuery9 *iface, REFIID riid, void **out)
{
- TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualGUID(riid, &IID_IDirect3DQuery9)
|| IsEqualGUID(riid, &IID_IUnknown))
TRACE("iface %p.\n", iface);
wined3d_mutex_lock();
- wined3d_surface_preload(surface->wined3d_surface);
+ wined3d_texture_preload(surface->wined3d_texture);
wined3d_mutex_unlock();
}
{
struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
struct wined3d_resource_desc wined3d_desc;
- struct wined3d_resource *wined3d_resource;
+ struct wined3d_resource *sub_resource;
TRACE("iface %p, desc %p.\n", iface, desc);
wined3d_mutex_lock();
- wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
- wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
wined3d_mutex_unlock();
desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
{
struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ struct wined3d_box box;
struct wined3d_map_desc map_desc;
HRESULT hr;
TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n",
iface, locked_rect, wine_dbgstr_rect(rect), flags);
+ if (rect)
+ {
+ box.left = rect->left;
+ box.top = rect->top;
+ box.right = rect->right;
+ box.bottom = rect->bottom;
+ box.front = 0;
+ box.back = 1;
+ }
+
wined3d_mutex_lock();
- hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx,
+ &map_desc, rect ? &box : NULL, flags);
wined3d_mutex_unlock();
if (SUCCEEDED(hr))
TRACE("iface %p.\n", iface);
wined3d_mutex_lock();
- hr = wined3d_surface_unmap(surface->wined3d_surface);
+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
wined3d_mutex_unlock();
switch(hr)
}
wined3d_mutex_lock();
- hr = wined3d_surface_getdc(surface->wined3d_surface, dc);
+ hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
wined3d_mutex_unlock();
return hr;
TRACE("iface %p, dc %p.\n", iface, dc);
wined3d_mutex_lock();
- hr = wined3d_surface_releasedc(surface->wined3d_surface, dc);
+ hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
wined3d_mutex_unlock();
switch (hr)
surface_wined3d_object_destroyed,
};
-void surface_init(struct d3d9_surface *surface, IUnknown *container_parent,
+void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
{
struct wined3d_resource_desc desc;
surface->resource.refcount = 0;
surface->wined3d_surface = wined3d_surface;
list_init(&surface->rtv_entry);
- surface->container = container_parent;
+ surface->container = wined3d_texture_get_parent(wined3d_texture);
+ surface->wined3d_texture = wined3d_texture;
+ surface->sub_resource_idx = sub_resource_idx;
- if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
+ if (surface->container && SUCCEEDED(IUnknown_QueryInterface(surface->container,
&IID_IDirect3DBaseTexture9, (void **)&texture)))
{
surface->texture = unsafe_impl_from_IDirect3DBaseTexture9(texture);
IDirect3DBaseTexture9_Release(texture);
}
- wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &desc);
+ wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &desc);
switch (d3dformat_from_wined3dformat(desc.format))
{
case D3DFMT_A8R8G8B8:
if (surface->wined3d_rtv)
return surface->wined3d_rtv;
- if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(surface->wined3d_surface,
- surface, &d3d9_view_wined3d_parent_ops, &surface->wined3d_rtv)))
+ if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture,
+ surface->sub_resource_idx, surface, &d3d9_view_wined3d_parent_ops, &surface->wined3d_rtv)))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
return NULL;
TRACE("iface %p, surface %p.\n", iface, surface);
wined3d_mutex_lock();
- hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, dst->wined3d_surface);
+ hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, dst->wined3d_texture, dst->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer)
{
struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
- struct wined3d_surface *wined3d_surface = NULL;
+ struct wined3d_resource *wined3d_resource;
+ struct wined3d_texture *wined3d_texture;
struct d3d9_surface *surface_impl;
HRESULT hr = D3D_OK;
TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
iface, backbuffer_idx, backbuffer_type, backbuffer);
+ /* backbuffer_type is ignored by native. */
+
+ if (!backbuffer)
+ {
+ WARN("The output pointer is NULL, returning D3DERR_INVALIDCALL.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
wined3d_mutex_lock();
- if ((wined3d_surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain,
- backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type)))
+ if ((wined3d_texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx)))
{
- surface_impl = wined3d_surface_get_parent(wined3d_surface);
- *backbuffer = &surface_impl->IDirect3DSurface9_iface;
- IDirect3DSurface9_AddRef(*backbuffer);
+ wined3d_resource = wined3d_texture_get_sub_resource(wined3d_texture, 0);
+ surface_impl = wined3d_resource_get_parent(wined3d_resource);
+ *backbuffer = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*backbuffer);
}
else
{
+ /* Do not set *backbuffer = NULL, see tests/device.c, test_swapchain(). */
hr = D3DERR_INVALIDCALL;
}
wined3d_mutex_unlock();
{
if (!iface)
return NULL;
- assert(iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
- || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
- || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl);
+
+ if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
+ && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
+ && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
+ {
+ WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
+ return NULL;
+ }
+
return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
}
UINT count = 1;
UINT i;
- TRACE("d3d9_elements %p, wined3d_elements %p\n", d3d9_elements, wined3d_elements);
+ TRACE("d3d9_elements %p, wined3d_elements %p, element_count %p\n", d3d9_elements, wined3d_elements, element_count);
element = d3d9_elements;
while (element++->Stream != 0xff && count++ < 128);
{
struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
struct wined3d_resource_desc wined3d_desc;
- struct wined3d_resource *wined3d_resource;
+ struct wined3d_resource *sub_resource;
TRACE("iface %p, desc %p.\n", iface, desc);
wined3d_mutex_lock();
- wined3d_resource = wined3d_volume_get_resource(volume->wined3d_volume);
- wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ sub_resource = wined3d_texture_get_sub_resource(volume->wined3d_texture, volume->sub_resource_idx);
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
wined3d_mutex_unlock();
desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
iface, locked_box, box, flags);
wined3d_mutex_lock();
- hr = wined3d_volume_map(volume->wined3d_volume, &map_desc, (const struct wined3d_box *)box, flags);
+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx,
+ &map_desc, (const struct wined3d_box *)box, flags);
wined3d_mutex_unlock();
locked_box->RowPitch = map_desc.row_pitch;
TRACE("iface %p.\n", iface);
wined3d_mutex_lock();
- hr = wined3d_volume_unmap(volume->wined3d_volume);
+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
volume_wined3d_object_destroyed,
};
-void volume_init(struct d3d9_volume *volume, struct d3d9_texture *texture,
- struct wined3d_volume *wined3d_volume, const struct wined3d_parent_ops **parent_ops)
+void volume_init(struct d3d9_volume *volume, struct wined3d_texture *wined3d_texture,
+ unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops)
{
volume->IDirect3DVolume9_iface.lpVtbl = &d3d9_volume_vtbl;
d3d9_resource_init(&volume->resource);
volume->resource.refcount = 0;
- volume->wined3d_volume = wined3d_volume;
- volume->texture = texture;
+ volume->texture = wined3d_texture_get_parent(wined3d_texture);
+ volume->wined3d_texture = wined3d_texture;
+ volume->sub_resource_idx = sub_resource_idx;
*parent_ops = &d3d9_volume_wined3d_parent_ops;
}
return DD_OK;
}
+HRESULT CALLBACK enum_zbuffer(DDPIXELFORMAT *format, void *ctx)
+{
+ DDCAPS *caps = ctx;
+
+ switch (format->u1.dwZBufferBitDepth)
+ {
+ case 8:
+ caps->dwZBufferBitDepths |= DDBD_8;
+ break;
+ case 16:
+ caps->dwZBufferBitDepths |= DDBD_16;
+ break;
+ case 24:
+ caps->dwZBufferBitDepths |= DDBD_24;
+ break;
+ case 32:
+ caps->dwZBufferBitDepths |= DDBD_32;
+ break;
+ }
+ return D3DENUMRET_OK;
+}
+
/*****************************************************************************
* IDirectDraw7::GetCaps
*
caps.dwCaps |= DDCAPS_ALIGNSTRIDE;
caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT;
+ IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps);
+
if(DriverCaps)
{
DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps);
{
IDirectDrawSurface7 *surface;
DDSURFACEDESC2 testdesc;
+ HRESULT hr;
if (match_flags != DDENUMSURFACES_MATCH)
return DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS;
memcpy(&testdesc, DDSD, sizeof(testdesc));
-
if (!(testdesc.dwFlags & DDSD_WIDTH))
{
testdesc.dwFlags |= DDSD_WIDTH;
testdesc.dwWidth = 512;
}
-
if (!(testdesc.dwFlags & DDSD_HEIGHT))
{
testdesc.dwFlags |= DDSD_HEIGHT;
testdesc.dwHeight = 512;
}
- if (IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL) == DD_OK)
+ hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL);
+ if (SUCCEEDED(hr))
{
surf = unsafe_impl_from_IDirectDrawSurface7(surface);
Callback(NULL, &surf->surface_desc, Context);
IDirectDrawSurface7_Release(surface);
}
else
- FIXME("Failed to create surface!\n");
+ ERR("Failed to create surface, hr %#x.\n", hr);
}
else if (Flags & DDENUMSURFACES_DOESEXIST)
{
+ BOOL all, nomatch;
DDSURFACEDESC2 desc;
struct list *entry, *entry2;
- BOOL nomatch, all;
/* a combination of match flags is not allowed */
if (match_flags != 0 &&
TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device);
wined3d_mutex_lock();
- if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL)))
+ if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, target, (IUnknown *)surface, 7, &object, NULL)))
{
*device = &object->IDirect3DDevice7_iface;
}
return CLASS_E_NOAGGREGATION;
wined3d_mutex_lock();
- if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL)))
+ if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL)))
{
*device = &device_impl->IDirect3DDevice3_iface;
}
iface, debugstr_guid(riid), surface, device);
wined3d_mutex_lock();
- if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL)))
+ if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL)))
{
*device = &device_impl->IDirect3DDevice2_iface;
}
ddraw2_GetAvailableVidMem,
};
-static const struct IDirectDrawVtbl ddraw1_vtbl =
+static struct IDirectDrawVtbl ddraw1_vtbl =
{
/* IUnknown */
ddraw1_QueryInterface,
}
static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
- void *container_parent, struct wined3d_surface *surface,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *surface,
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, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
- device_parent, container_parent, surface, parent, parent_ops);
+ TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, surface %p, parent %p, parent_ops %p.\n",
+ device_parent, wined3d_texture, sub_resource_idx, surface, parent, parent_ops);
/* We have a swapchain or wined3d internal texture. */
- if (!container_parent || container_parent == 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 DDERR_OUTOFVIDEOMEMORY;
}
- ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops);
+ ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture_get_parent(wined3d_texture), surface, parent_ops);
*parent = ddraw_surface;
list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry);
}
static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
- void *container_parent, struct wined3d_volume *volume,
+ struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
void **parent, const struct wined3d_parent_ops **parent_ops)
{
- TRACE("device_parent %p, container_parent %p, volume %p, parent %p, parent_ops %p.\n",
- device_parent, container_parent, volume, parent, 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;
ddraw_frontbuffer_destroyed,
};
-static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
- void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
+static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
{
struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
- struct wined3d_resource_desc texture_desc;
- struct wined3d_texture *texture;
HRESULT hr;
- TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
- device_parent, container_parent, desc, surface);
+ TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
+ device_parent, container_parent, desc, texture);
if (ddraw->wined3d_frontbuffer)
{
return E_FAIL;
}
- texture_desc = *desc;
- texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
- if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &texture_desc, 1,
- WINED3D_SURFACE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, &texture)))
+ if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1,
+ WINED3D_SURFACE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
- ddraw->wined3d_frontbuffer = *surface;
- wined3d_surface_incref(*surface);
- wined3d_texture_decref(texture);
+ ddraw->wined3d_frontbuffer = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(*texture, 0));
return hr;
}
device_parent_activate,
device_parent_surface_created,
device_parent_volume_created,
- device_parent_create_swapchain_surface,
+ device_parent_create_swapchain_texture,
device_parent_create_swapchain,
};
/* Surface description, for GetAttachedSurface */
DDSURFACEDESC2 surface_desc;
- /* Misc things */
- UINT mipmap_level;
-
/* Clipper objects */
struct ddraw_clipper *clipper;
struct ddraw_palette *palette;
IUnknown IUnknown_inner;
LONG ref;
UINT version;
+ BOOL hw;
IUnknown *outer_unknown;
struct wined3d_device *wined3d_device;
D3DMATRIXHANDLE world, proj, view;
};
-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface,
+HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
UINT version, struct d3d_device **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN;
enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) DECLSPEC_HIDDEN;
return DDERR_INVALIDCAPS;
}
- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+ if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
WARN("Surface %p is not in video memory.\n", target_impl);
wined3d_mutex_unlock();
return DDERR_INVALIDPIXELFORMAT;
}
- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+ if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
WARN("Surface %p is not in video memory.\n", target_impl);
IDirectDrawSurface4_AddRef(target);
return DDERR_INVALIDPIXELFORMAT;
}
- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+ if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
WARN("Surface %p is not in video memory.\n", target_impl);
IDirectDrawSurface_AddRef(target);
return WINED3D_ZB_TRUE;
}
-static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
+static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, BOOL hw,
struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown)
{
static const D3DMATRIX ident =
device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl;
device->ref = 1;
device->version = version;
+ device->hw = hw;
if (outer_unknown)
device->outer_unknown = outer_unknown;
return D3D_OK;
}
-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface,
+HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
UINT version, struct d3d_device **device, IUnknown *outer_unknown)
{
struct d3d_device *object;
+ BOOL hw = TRUE;
HRESULT hr;
- TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
- ddraw, target, version, device, outer_unknown);
+ TRACE("ddraw %p, guid %s, target %p, version %u, device %p, outer_unknown %p.\n",
+ ddraw, debugstr_guid(guid), target, version, device, outer_unknown);
+
+ if (IsEqualGUID(guid, &IID_IDirect3DRGBDevice))
+ hw = FALSE;
if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
|| (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
return DDERR_NOPALETTEATTACHED;
}
- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
+ if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
return DDERR_OUTOFMEMORY;
}
- if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown)))
+ if (FAILED(hr = d3d_device_init(object, ddraw, hw, target, rt_iface, version, outer_unknown)))
{
WARN("Failed to initialize device, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
};
/* Enumeration callback for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */
-static HRESULT CALLBACK enum_callback(GUID *guid, char *description, char *driver_name,
+static BOOL CALLBACK enum_callback(GUID *guid, char *description, char *driver_name,
void *context, HMONITOR monitor)
{
const struct callback_info *info = context;
{
HRESULT hr;
- if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface,
+ if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface,
1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface)))
{
This->device1 = NULL;
*/
TRACE("(%p): Returning surface %p\n", This, surf);
- TRACE("(%p): mipmapcount=%d\n", This, surf->mipmap_level);
*Surface = &surf->IDirectDrawSurface7_iface;
ddraw_surface7_AddRef(*Surface);
wined3d_mutex_unlock();
static HRESULT surface_lock(struct ddraw_surface *This,
RECT *Rect, DDSURFACEDESC2 *DDSD, DWORD Flags, HANDLE h)
{
+ struct wined3d_box box;
struct wined3d_map_desc map_desc;
HRESULT hr = DD_OK;
wined3d_mutex_unlock();
return DDERR_INVALIDPARAMS;
}
+ box.left = Rect->left;
+ box.top = Rect->top;
+ box.right = Rect->right;
+ box.bottom = Rect->bottom;
+ box.front = 0;
+ box.back = 1;
}
if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
hr = ddraw_surface_update_frontbuffer(This, Rect, TRUE);
if (SUCCEEDED(hr))
- hr = wined3d_surface_map(This->wined3d_surface, &map_desc, Rect, Flags);
+ hr = wined3d_surface_map(This->wined3d_surface, &map_desc, Rect ? &box : NULL, Flags);
if (FAILED(hr))
{
wined3d_mutex_unlock();
*****************************************************************************/
static HRESULT WINAPI ddraw_surface7_GetBltStatus(IDirectDrawSurface7 *iface, DWORD Flags)
{
- struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
- HRESULT hr;
-
TRACE("iface %p, flags %#x.\n", iface, Flags);
- wined3d_mutex_lock();
- hr = wined3d_surface_get_blt_status(surface->wined3d_surface, Flags);
- wined3d_mutex_unlock();
- switch(hr)
+ switch (Flags)
{
- case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS;
- default: return hr;
+ case WINEDDGBS_CANBLT:
+ case WINEDDGBS_ISBLTDONE:
+ return DD_OK;
+
+ default:
+ return DDERR_INVALIDPARAMS;
}
}
*****************************************************************************/
static HRESULT WINAPI ddraw_surface7_GetFlipStatus(IDirectDrawSurface7 *iface, DWORD Flags)
{
- struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
- HRESULT hr;
-
TRACE("iface %p, flags %#x.\n", iface, Flags);
- wined3d_mutex_lock();
- hr = wined3d_surface_get_flip_status(surface->wined3d_surface, Flags);
- wined3d_mutex_unlock();
+ /* XXX: DDERR_INVALIDSURFACETYPE */
- switch(hr)
+ switch (Flags)
{
- case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS;
- default: return hr;
+ case WINEDDGFS_CANFLIP:
+ case WINEDDGFS_ISFLIPDONE:
+ return DD_OK;
+
+ default:
+ return DDERR_INVALIDPARAMS;
}
}
DDCOLORKEY fixed_color_key;
HRESULT hr = WINED3D_OK;
+ if (flags & DDCKEY_COLORSPACE)
+ {
+ if (color_key && color_key->dwColorSpaceLowValue != color_key->dwColorSpaceHighValue)
+ {
+ WARN("Range color keys are not supported, returning DDERR_NOCOLORKEYHW.\n");
+ return DDERR_NOCOLORKEYHW;
+ }
+ flags &= ~DDCKEY_COLORSPACE;
+ }
+
wined3d_mutex_lock();
if (color_key)
{
- fixed_color_key = *color_key;
- /* Handle case where dwColorSpaceHighValue < dwColorSpaceLowValue */
- if (fixed_color_key.dwColorSpaceHighValue < fixed_color_key.dwColorSpaceLowValue)
- fixed_color_key.dwColorSpaceHighValue = fixed_color_key.dwColorSpaceLowValue;
-
+ fixed_color_key.dwColorSpaceLowValue = fixed_color_key.dwColorSpaceHighValue = color_key->dwColorSpaceLowValue;
switch (flags & ~DDCKEY_COLORSPACE)
{
case DDCKEY_DESTBLT:
{
DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc;
- TRACE("Copying surface %p to surface %p (mipmap level %d).\n",
- src_surface, dst_surface, src_surface->mipmap_level);
+ TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface);
if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat,
&dst_surface->surface_desc.u4.ddpfPixelFormat))
ddraw_surface2_PageUnlock,
};
-static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
+static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
{
/* IUnknown */
ddraw_surface1_QueryInterface,
if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
{
- wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM;
+ /*
+ * The ddraw RGB device allows to use system memory surfaces as rendering target.
+ * This does not cause problems because the RGB device does software rasterization
+ * though it will fail with hardware accelerated ddraw. In order to be partially
+ * compatible with games requesting explicitly the RGB device, we ignore the
+ * specified location and try to create rendering targets in video memory if
+ * possible.
+ */
+ if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
+ SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
+ WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_RENDERTARGET,
+ WINED3D_RTYPE_SURFACE, wined3d_desc.format)))
+ {
+ FIXME("Application wants to create rendering target in system memory, using video memory instead\n");
+ wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET;
+ }
+ else
+ wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM;
}
else
{
}
}
+ if (((desc->dwFlags & DDSD_CKDESTOVERLAY)
+ && desc->u3.ddckCKDestOverlay.dwColorSpaceLowValue != desc->u3.ddckCKDestOverlay.dwColorSpaceHighValue)
+ || ((desc->dwFlags & DDSD_CKDESTBLT)
+ && desc->ddckCKDestBlt.dwColorSpaceLowValue != desc->ddckCKDestBlt.dwColorSpaceHighValue)
+ || ((desc->dwFlags & DDSD_CKSRCOVERLAY)
+ && desc->ddckCKSrcOverlay.dwColorSpaceLowValue != desc->ddckCKSrcOverlay.dwColorSpaceHighValue)
+ || ((desc->dwFlags & DDSD_CKSRCBLT)
+ && desc->ddckCKSrcBlt.dwColorSpaceLowValue != desc->ddckCKSrcBlt.dwColorSpaceHighValue))
+ {
+ WARN("Range color keys not supported, returning DDERR_NOCOLORKEYHW.\n");
+ HeapFree(GetProcessHeap(), 0, texture);
+ return DDERR_NOCOLORKEYHW;
+ }
+
if (desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY))
wined3d_desc.usage |= WINED3DUSAGE_OVERLAY;
DDSURFACEDESC2 *desc = &surface->surface_desc;
struct wined3d_resource_desc wined3d_desc;
unsigned int version = texture->version;
- UINT row_pitch, slice_pitch;
- struct wined3d_resource *resource = wined3d_surface_get_resource(wined3d_surface);
-
- wined3d_resource_get_pitch(resource, &row_pitch, &slice_pitch);
surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl;
surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl;
}
*desc = texture->surface_desc;
- wined3d_resource_get_desc(resource, &wined3d_desc);
+ wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &wined3d_desc);
desc->dwWidth = wined3d_desc.width;
desc->dwHeight = wined3d_desc.height;
surface->first_attached = surface;
if (desc->dwFlags & DDSD_LPSURFACE)
desc->u1.dwLinearSize = ~0u;
else
- {
- desc->u1.dwLinearSize = row_pitch * ((desc->dwHeight + 3) / 4);
- }
+ desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
desc->dwFlags |= DDSD_LINEARSIZE;
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
}
else
{
if (!(desc->dwFlags & DDSD_LPSURFACE))
- desc->u1.lPitch = row_pitch;
+ desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
desc->dwFlags |= DDSD_PITCH;
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
}
{
DWORD idx = i >> 5;
DWORD shift = i & 0x1f;
- if(reg_maps->constf[idx] & (1 << shift)) highest_constf = i;
+ if (reg_maps->constf[idx] & (1u << shift))
+ highest_constf = i;
}
if(use_nv_clip(gl_info) && ctx->target_version >= NV2)
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
max_constantsF, max_constantsF - 1);
- } else {
- for(i = 0; i < max_constantsF; i++) {
+ }
+ else
+ {
+ for (i = 0; i < max_constantsF; ++i)
+ {
DWORD idx, mask;
idx = i >> 5;
- mask = 1 << (i & 0x1f);
+ mask = 1u << (i & 0x1fu);
if (!shader_constant_is_local(shader, i) && (reg_maps->constf[idx] & mask))
{
shader_addline(buffer, "PARAM C%d = program.env[%d];\n",i, i);
}
else
{
- if (ctx->cur_vs_args->super.swizzle_map & (1 << reg->idx[0].offset))
+ if (ctx->cur_vs_args->super.swizzle_map & (1u << reg->idx[0].offset))
*is_color = TRUE;
sprintf(register_name, "vertex.attrib[%u]", reg->idx[0].offset);
}
device = shader->device;
gl_info = &device->adapter->gl_info;
- if (pshader && priv->cur_ps_args->super.np2_fixup & (1 << sampler_idx)
+ if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx)
&& gl_info->supported[ARB_TEXTURE_RECTANGLE])
tex_type = "RECT";
else
tex_type = "2D";
if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
- if (priv->cur_np2fixup_info->super.active & (1 << sampler_idx))
+ if (priv->cur_np2fixup_info->super.active & (1u << sampler_idx))
{
if (flags) FIXME("Only ordinary sampling from NP2 textures is supported.\n");
else np2_fixup = TRUE;
shader_arb_get_dst_param(ins, dst, reg_dest);
/* 1.0-1.4: Use destination register number as texture code.
- 2.0+: Use provided sampler number as texure code. */
+ 2.0+: Use provided sampler number as texture code. */
if (shader_version < WINED3D_SHADER_VERSION(2,0))
reg_sampler_code = dst->reg.idx[0].offset;
else
for (i = 0; i < gl_info->limits.clipplanes; ++i)
{
- if (args->clip.boolclip.clipplane_mask & (1 << i))
+ if (args->clip.boolclip.clipplane_mask & (1u << i))
{
shader_addline(buffer, "DP4 TA.%c, TMP_OUT, state.clip[%u].plane;\n",
component[cur_clip++], i);
i, compiled->bumpenvmatconst[bump_const].const_num);
compiled->numbumpenvmatconsts = bump_const + 1;
- if (!(reg_maps->luminanceparams & (1 << i))) continue;
+ if (!(reg_maps->luminanceparams & (1u << i)))
+ continue;
compiled->luminanceconst[bump_const].const_num = next_local++;
shader_addline(buffer, "PARAM luminance%d = program.local[%d];\n",
for(i = 0; i < MAX_CONST_I; i++)
{
compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
- if (reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
+ if (reg_maps->integer_constants & (1u << i) && priv_ctx.target_version >= NV2)
{
const DWORD *control_values = find_loop_control_values(shader, i);
fixup->offset = next_local;
fixup->super.active = 0;
- for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
- if (!(map & (1 << i))) continue;
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (!(map & (1u << i)))
+ continue;
- if (fixup->offset + (cur_fixup_sampler >> 1) < max_lconsts) {
- fixup->super.active |= (1 << i);
+ if (fixup->offset + (cur_fixup_sampler >> 1) < max_lconsts)
+ {
+ fixup->super.active |= (1u << i);
fixup->super.idx[i] = cur_fixup_sampler++;
- } else {
+ }
+ else
+ {
FIXME("No free constant found to load NP2 fixup data into shader. "
"Sampling from this texture will probably look wrong.\n");
break;
for(i = 0; i < MAX_CONST_I; i++)
{
compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
- if(reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
+ if (reg_maps->integer_constants & (1u << i) && priv_ctx.target_version >= NV2)
{
const DWORD *control_values = find_loop_control_values(shader, i);
const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE);
for(i = 0; i < MAX_REG_TEXCRD; i++)
{
- if (reg_maps->texcoord_mask[i] && reg_maps->texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL)
+ if (reg_maps->u.texcoord_mask[i] && reg_maps->u.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL)
shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one);
}
}
int i;
WORD int_skip;
- find_ps_compile_args(state, shader, context->stream_info.position_transformed, &args->super, gl_info);
+ find_ps_compile_args(state, shader, context->stream_info.position_transformed, &args->super, context);
/* This forces all local boolean constants to 1 to make them stateblock independent */
args->bools = shader->reg_maps.local_bool_consts;
for(i = 0; i < MAX_CONST_B; i++)
{
if (state->ps_consts_b[i])
- args->bools |= ( 1 << i);
+ args->bools |= ( 1u << i);
}
/* Only enable the clip plane emulation KIL if at least one clipplane is enabled. The KIL instruction
return;
}
- for(i = 0; i < MAX_CONST_I; i++)
+ for (i = 0; i < MAX_CONST_I; ++i)
{
- if(int_skip & (1 << i))
+ if (int_skip & (1u << i))
{
args->loop_ctrl[i][0] = 0;
args->loop_ctrl[i][1] = 0;
int i;
WORD int_skip;
- find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super);
+ find_vs_compile_args(state, shader, context->stream_info.swizzle_map, &args->super, d3d_info);
args->clip.boolclip_compare = 0;
if (use_ps(state))
for(i = 0; i < MAX_CONST_B; i++)
{
if (state->vs_consts_b[i])
- args->clip.boolclip.bools |= ( 1 << i);
+ args->clip.boolclip.bools |= (1u << i);
}
args->vertex.samplers[0] = context->tex_unit_map[MAX_FRAGMENT_SAMPLERS + 0];
for(i = 0; i < MAX_CONST_I; i++)
{
- if(int_skip & (1 << i))
+ if (int_skip & (1u << i))
{
args->loop_ctrl[i][0] = 0;
args->loop_ctrl[i][1] = 0;
priv->last_vs_color_unclamp = FALSE;
}
- context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
- | (1 << WINED3D_SHADER_TYPE_VERTEX)
- | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
+ context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
+ | (1u << WINED3D_SHADER_TYPE_VERTEX)
+ | (1u << WINED3D_SHADER_TYPE_GEOMETRY);
}
/* Context activation is done by the caller. */
caps->ps_1x_max_value = 0.0f;
}
+ caps->varying_count = 0;
caps->wined3d_caps = WINED3D_SHADER_CAP_SRGB_WRITE;
if (use_nv_clip(gl_info))
caps->wined3d_caps |= WINED3D_SHADER_CAP_VS_CLIPPING;
BOOL vshader = shader_is_vshader_version(reg_maps->shader_version.type);
const struct wined3d_shader_lconst *constant;
WORD bools = 0;
- WORD flag = (1 << idx);
+ WORD flag = (1u << idx);
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
if (reg_maps->local_bool_consts & flag)
/* Integer constants can either be a local constant, or they can be stored in the shader
* type specific compile args. */
- if (reg_maps->local_int_consts & (1 << idx))
+ if (reg_maps->local_int_consts & (1u << idx))
{
const struct wined3d_shader_lconst *constant;
/* ARB_fragment_program fixed function pipeline replacement definitions */
#define ARB_FFP_CONST_TFACTOR 0
-#define ARB_FFP_CONST_COLOR_KEY ((ARB_FFP_CONST_TFACTOR) + 1)
-#define ARB_FFP_CONST_SPECULAR_ENABLE ((ARB_FFP_CONST_COLOR_KEY) + 1)
+#define ARB_FFP_CONST_COLOR_KEY_LOW ((ARB_FFP_CONST_TFACTOR) + 1)
+#define ARB_FFP_CONST_COLOR_KEY_HIGH ((ARB_FFP_CONST_COLOR_KEY_LOW) + 1)
+#define ARB_FFP_CONST_SPECULAR_ENABLE ((ARB_FFP_CONST_COLOR_KEY_HIGH) + 1)
#define ARB_FFP_CONST_CONSTANT(i) ((ARB_FFP_CONST_SPECULAR_ENABLE) + 1 + i)
#define ARB_FFP_CONST_BUMPMAT(i) ((ARB_FFP_CONST_CONSTANT(7)) + 1 + i)
#define ARB_FFP_CONST_LUMINANCE(i) ((ARB_FFP_CONST_BUMPMAT(7)) + 1 + i)
caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8);
}
+static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return GL_EXT_EMUL_ARB_MULTITEXTURE | GL_EXT_EMUL_EXT_FOG_COORD;
+}
+
static void state_texfactor_arbfp(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
{
struct wined3d_device *device = context->swapchain->device;
const struct wined3d_gl_info *gl_info = context->gl_info;
- struct wined3d_color float_key;
+ struct wined3d_color float_key[2];
const struct wined3d_texture *texture = state->textures[0];
if (!texture)
return;
priv = device->shader_priv;
- priv->pshader_const_dirty[ARB_FFP_CONST_COLOR_KEY] = 1;
- priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_COLOR_KEY + 1);
+ priv->pshader_const_dirty[ARB_FFP_CONST_COLOR_KEY_LOW] = 1;
+ priv->pshader_const_dirty[ARB_FFP_CONST_COLOR_KEY_HIGH] = 1;
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_COLOR_KEY_HIGH + 1);
}
- wined3d_format_convert_color_to_float(texture->resource.format, NULL,
- texture->async.src_blt_color_key.color_space_high_value, &float_key);
- GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY, &float_key.r));
- checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY, &float_key.r)");
+ wined3d_format_get_float_color_key(texture->resource.format, &texture->async.src_blt_color_key, float_key);
+
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY_LOW, &float_key[0].r));
+ checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY_LOW, &float_key[0].r)");
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY_HIGH, &float_key[1].r));
+ checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY_HIGH, &float_key[1].r)");
}
static const char *get_argreg(struct wined3d_string_buffer *buffer, DWORD argnum, unsigned int stage, DWORD arg)
if (settings->color_key_enabled)
{
- shader_addline(&buffer, "PARAM color_key = program.env[%u];\n", ARB_FFP_CONST_COLOR_KEY);
+ shader_addline(&buffer, "PARAM color_key_low = program.env[%u];\n", ARB_FFP_CONST_COLOR_KEY_LOW);
+ shader_addline(&buffer, "PARAM color_key_high = program.env[%u];\n", ARB_FFP_CONST_COLOR_KEY_HIGH);
tex_read[0] = TRUE;
}
if (settings->color_key_enabled)
{
- shader_addline(&buffer, "SUB TMP, tex0, color_key;\n");
- shader_addline(&buffer, "DP4 TMP.b, TMP, TMP;\n");
- shader_addline(&buffer, "SGE TMP, -TMP.b, 0.0;\n");
- shader_addline(&buffer, "KIL -TMP;\n");
+ shader_addline(&buffer, "SLT TMP, tex0, color_key_low;\n"); /* below low key */
+ shader_addline(&buffer, "SGE ret, tex0, color_key_high;\n"); /* above high key */
+ shader_addline(&buffer, "ADD TMP, TMP, ret;\n"); /* or */
+ shader_addline(&buffer, "DP4 TMP.b, TMP, TMP;\n"); /* on any channel */
+ shader_addline(&buffer, "SGE TMP, -TMP.b, 0.0;\n"); /* logical not */
+ shader_addline(&buffer, "KIL -TMP;\n"); /* discard if true */
}
/* Generate the main shader */
}
else if (use_pshader)
{
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
return;
}
context->last_was_pshader = TRUE;
}
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
/* We can't link the fog states to the fragment state directly since the
{STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_arb_specularenable}, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
{0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
};
const struct fragment_pipeline arbfp_fragment_pipeline = {
arbfp_enable,
arbfp_get_caps,
+ arbfp_get_emul_mask,
arbfp_alloc,
arbfp_free,
arbfp_alloc_context_data,
};
#define ARBFP_BLIT_PARAM_SIZE 0
-#define ARBFP_BLIT_PARAM_COLOR_KEY 1
+#define ARBFP_BLIT_PARAM_COLOR_KEY_LOW 1
+#define ARBFP_BLIT_PARAM_COLOR_KEY_HIGH 2
struct arbfp_blit_priv
{
if (type->use_color_key)
{
shader_addline(&buffer, "TEMP color;\n");
- shader_addline(&buffer, "TEMP compare;\n");
- shader_addline(&buffer, "PARAM color_key = program.local[%u];\n", ARBFP_BLIT_PARAM_COLOR_KEY);
+ shader_addline(&buffer, "TEMP less, greater;\n");
+ shader_addline(&buffer, "PARAM color_key_low = program.local[%u];\n", ARBFP_BLIT_PARAM_COLOR_KEY_LOW);
+ shader_addline(&buffer, "PARAM color_key_high = program.local[%u];\n", ARBFP_BLIT_PARAM_COLOR_KEY_HIGH);
shader_addline(&buffer, "TEX color, fragment.texcoord[0], texture[0], %s;\n", tex_target);
- shader_addline(&buffer, "SUB compare, color, color_key;\n");
- shader_addline(&buffer, "DP4 compare.r, compare, compare;\n");
- shader_addline(&buffer, "SGE compare, -compare.r, 0.0;\n");
- shader_addline(&buffer, "KIL -compare;\n");
+ shader_addline(&buffer, "SLT less, color, color_key_low;\n"); /* below low key */
+ shader_addline(&buffer, "SGE greater, color, color_key_high;\n"); /* above high key */
+ shader_addline(&buffer, "ADD less, less, greater;\n"); /* or */
+ shader_addline(&buffer, "DP4 less.b, less, less;\n"); /* on any channel */
+ shader_addline(&buffer, "SGE less, -less.b, 0.0;\n"); /* logical not */
+ shader_addline(&buffer, "KIL -less;\n"); /* discard if true */
shader_addline(&buffer, "MOV result.color, color;\n");
}
else
struct wine_rb_entry *entry;
struct arbfp_blit_type type;
struct arbfp_blit_desc *desc;
- struct wined3d_color float_color_key;
+ struct wined3d_color float_color_key[2];
if (is_complex_fixup(surface->resource.format->color_fixup))
fixup = get_complex_fixup(surface->resource.format->color_fixup);
checkGLcall("glProgramLocalParameter4fvARB");
if (type.use_color_key)
{
- wined3d_format_convert_color_to_float(surface->resource.format, NULL,
- surface->container->async.src_blt_color_key.color_space_high_value, &float_color_key);
+ wined3d_format_get_float_color_key(surface->resource.format, color_key, float_color_key);
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+ ARBFP_BLIT_PARAM_COLOR_KEY_LOW, &float_color_key[0].r));
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
- ARBFP_BLIT_PARAM_COLOR_KEY, &float_color_key.r));
+ ARBFP_BLIT_PARAM_COLOR_KEY_HIGH, &float_color_key[1].r));
checkGLcall("glProgramLocalParameter4fvARB");
}
* 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. */
- surface_load_fb_texture(src_surface, FALSE);
+ surface_load_fb_texture(src_surface, FALSE, context);
src_rect.top = src_surface->resource.height - src_rect.top;
src_rect.bottom = src_surface->resource.height - src_rect.bottom;
{STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), atifs_srgbwriteenable }, WINED3D_GL_EXT_NONE },
{STATE_COLOR_KEY, { STATE_COLOR_KEY, state_nop }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE },
caps->MaxSimultaneousTextures = 6;
}
+static DWORD atifs_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return GL_EXT_EMUL_ARB_MULTITEXTURE | GL_EXT_EMUL_EXT_FOG_COORD;
+}
+
static void *atifs_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
struct atifs_private_data *priv;
const struct fragment_pipeline atifs_fragment_pipeline = {
atifs_enable,
atifs_get_caps,
+ atifs_get_emul_mask,
atifs_alloc,
atifs_free,
atifs_alloc_context_data,
/* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
* there, on nonexistent attribs the vbo is 0.
*/
- if (!(si->use_map & (1 << attrib_idx))
+ if (!(si->use_map & (1u << attrib_idx))
|| state->streams[attrib->stream_idx].buffer != This)
return FALSE;
*/
#endif /* STAGING_CSMT */
*dst_color = 0;
- *dst_color |= (src_color & 0xff00ff00); /* Alpha Green */
- *dst_color |= (src_color & 0x00ff0000) >> 16; /* Red */
- *dst_color |= (src_color & 0x000000ff) << 16; /* Blue */
+ *dst_color |= (src_color & 0xff00ff00u); /* Alpha Green */
+ *dst_color |= (src_color & 0x00ff0000u) >> 16; /* Red */
+ *dst_color |= (src_color & 0x000000ffu) << 16; /* Blue */
}
static inline void fixup_transformed_pos(float *p)
*
* Don't try to solve this by going back to always invalidating changed areas.
* This won't work if we ever want to support glMapBufferRange mapping with
- * GL_buffer_storage in the CS.
+ * GL_ARB_buffer_storage in the CS.
*
* Also keep in mind that UnLoad can destroy the VBO, so simply creating it
* on buffer creation won't work either. */
BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING;
if (flags & WINED3D_MAP_DISCARD && !swvp)
{
- buffer->ignore_discard = TRUE;
- wined3d_resource_allocate_sysmem(&buffer->resource);
- wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory);
+ if (buffer->resource.access_fence)
+ {
+ buffer->ignore_discard = TRUE;
+ wined3d_resource_allocate_sysmem(&buffer->resource);
+ wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory);
+ }
}
else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY)) && !buffer->ignore_discard)
{
return wined3d_buffer_decref(buffer_from_resource(resource));
}
+static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ struct wined3d_buffer *buffer = buffer_from_resource(resource);
+ UINT offset, size;
+
+ if (sub_resource_idx)
+ {
+ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+ return E_INVALIDARG;
+ }
+
+ if (box)
+ {
+ offset = box->left;
+ size = box->right - box->left;
+ }
+ else
+ {
+ offset = size = 0;
+ }
+
+ map_desc->row_pitch = map_desc->slice_pitch = buffer->desc.byte_width;
+ return wined3d_buffer_map(buffer, offset, size, (BYTE **)&map_desc->data, flags);
+}
+
+static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
+{
+ if (sub_resource_idx)
+ {
+ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+ return E_INVALIDARG;
+ }
+
+ wined3d_buffer_unmap(buffer_from_resource(resource));
+ return WINED3D_OK;
+}
+
#if defined(STAGING_CSMT)
static void wined3d_buffer_location_invalidated(struct wined3d_resource *resource, DWORD location)
{
ERR("Not yet implemented.\n");
}
+#endif /* STAGING_CSMT */
static const struct wined3d_resource_ops buffer_resource_ops =
{
buffer_resource_incref,
buffer_resource_decref,
buffer_unload,
+ buffer_resource_sub_resource_map,
+ buffer_resource_sub_resource_unmap,
+#if defined(STAGING_CSMT)
wined3d_buffer_location_invalidated,
wined3d_buffer_load_location,
-#else /* STAGING_CSMT */
-static const struct wined3d_resource_ops buffer_resource_ops =
-{
- buffer_resource_incref,
- buffer_resource_decref,
- buffer_unload,
#endif /* STAGING_CSMT */
};
static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device,
UINT size, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, GLenum bind_hint,
- const char *data, void *parent, const struct wined3d_parent_ops *parent_ops)
+ const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
return WINED3DERR_INVALIDCALL;
}
+ if (data && !data->data)
+ {
+ WARN("Invalid sub-resource data specified.\n");
+ return E_INVALIDARG;
+ }
+
hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format,
WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops);
if (FAILED(hr))
buffer->flags |= WINED3D_BUFFER_CREATEBO;
}
+#if defined(STAGING_CSMT)
+ buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps));
+ if (!buffer->maps)
+ {
+ ERR("Out of memory\n");
+ buffer_unload(&buffer->resource);
+ resource_cleanup(&buffer->resource);
+ return E_OUTOFMEMORY;
+ }
+ buffer->maps_size = 1;
+
+#endif /* STAGING_CSMT */
if (data)
{
BYTE *ptr;
if (FAILED(hr))
{
ERR("Failed to map buffer, hr %#x\n", hr);
+#if defined(STAGING_CSMT)
+ HeapFree(GetProcessHeap(), 0, buffer->maps);
+#endif /* STAGING_CSMT */
buffer_unload(&buffer->resource);
resource_cleanup(&buffer->resource);
return hr;
}
- memcpy(ptr, data, size);
+ memcpy(ptr, data->data, size);
wined3d_buffer_unmap(buffer);
}
+#if defined(STAGING_CSMT)
+ if (wined3d_settings.cs_multithreaded)
+ buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
+#else /* STAGING_CSMT */
buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps));
if (!buffer->maps)
{
return E_OUTOFMEMORY;
}
buffer->maps_size = 1;
-
-#if defined(STAGING_CSMT)
- if (wined3d_settings.cs_multithreaded)
- buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
-
#endif /* STAGING_CSMT */
+
return WINED3D_OK;
}
HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
- const void *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
+ const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_buffer **buffer)
{
struct wined3d_buffer *object;
HRESULT hr;
- TRACE("device %p, desc %p, data %p, parent %p, buffer %p\n", device, desc, data, parent, buffer);
+ TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p\n",
+ device, desc, data, parent, parent_ops, buffer);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
static inline DWORD context_generate_rt_mask(GLenum buffer)
{
/* Should take care of all the GL_FRONT/GL_BACK/GL_AUXi/GL_NONE... cases */
- return buffer ? (1 << 31) | buffer : 0;
+ return buffer ? (1u << 31) | buffer : 0;
}
static inline DWORD context_generate_rt_mask_from_surface(const struct wined3d_surface *target)
{
- return (1 << 31) | surface_get_gl_buffer(target);
+ return (1u << 31) | surface_get_gl_buffer(target);
}
static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
}
}
+/* 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_surface *restore)
+{
+ if (context->current_rt != restore)
+ {
+ context_release(context);
+ context = context_acquire(restore->resource.device, restore);
+ }
+
+ context_release(context);
+}
+
static void context_enter(struct wined3d_context *context)
{
TRACE("Entering context %p, level %u.\n", context, context->level + 1);
context->dirtyArray[context->numDirtyEntries++] = rep;
idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
- context->isStateDirty[idx] |= (1 << shift);
+ context->isStateDirty[idx] |= (1u << shift);
}
/* This function takes care of wined3d pixel format selection. */
BOOL auxBuffers, BOOL findCompatible)
{
int iPixelFormat=0;
- BYTE redBits, greenBits, blueBits, alphaBits, colorBits;
- BYTE depthBits=0, stencilBits=0;
unsigned int current_value;
unsigned int cfg_count = device->adapter->cfg_count;
unsigned int i;
device, hdc, debug_d3dformat(color_format->id), debug_d3dformat(ds_format->id),
auxBuffers, findCompatible);
- if (!getColorBits(color_format, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits))
- {
- ERR("Unable to get color bits for format %s (%#x)!\n",
- debug_d3dformat(color_format->id), color_format->id);
- return 0;
- }
-
- getDepthStencilBits(ds_format, &depthBits, &stencilBits);
-
current_value = 0;
for (i = 0; i < cfg_count; ++i)
{
/* In window mode we need a window drawable format and double buffering. */
if (!(cfg->windowDrawable && cfg->doubleBuffer))
continue;
- if (cfg->redSize < redBits)
+ if (cfg->redSize < color_format->red_size)
continue;
- if (cfg->greenSize < greenBits)
+ if (cfg->greenSize < color_format->green_size)
continue;
- if (cfg->blueSize < blueBits)
+ if (cfg->blueSize < color_format->blue_size)
continue;
- if (cfg->alphaSize < alphaBits)
+ if (cfg->alphaSize < color_format->alpha_size)
continue;
- if (cfg->depthSize < depthBits)
+ if (cfg->depthSize < ds_format->depth_size)
continue;
- if (stencilBits && cfg->stencilSize != stencilBits)
+ if (ds_format->stencil_size && cfg->stencilSize != ds_format->stencil_size)
continue;
/* Check multisampling support. */
if (cfg->numSamples)
value = 1;
/* We try to locate a format which matches our requirements exactly. In case of
* depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
- if (cfg->depthSize == depthBits)
+ if (cfg->depthSize == ds_format->depth_size)
value += 1;
- if (cfg->stencilSize == stencilBits)
+ if (cfg->stencilSize == ds_format->stencil_size)
value += 2;
- if (cfg->alphaSize == alphaBits)
+ if (cfg->alphaSize == color_format->alpha_size)
value += 4;
/* We like to have aux buffers in backbuffer mode */
if (auxBuffers && cfg->auxBuffers)
value += 8;
- if (cfg->redSize == redBits
- && cfg->greenSize == greenBits
- && cfg->blueSize == blueBits)
+ if (cfg->redSize == color_format->red_size
+ && cfg->greenSize == color_format->green_size
+ && cfg->blueSize == color_format->blue_size)
value += 16;
if (value > current_value)
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cAlphaBits = alphaBits;
- pfd.cColorBits = colorBits;
- pfd.cDepthBits = depthBits;
- pfd.cStencilBits = stencilBits;
+ pfd.cAlphaBits = color_format->alpha_size;
+ pfd.cColorBits = color_format->red_size + color_format->green_size
+ + color_format->blue_size + color_format->alpha_size;
+ pfd.cDepthBits = ds_format->depth_size;
+ pfd.cStencilBits = ds_format->stencil_size;
pfd.iLayerType = PFD_MAIN_PLANE;
iPixelFormat = ChoosePixelFormat(hdc, &pfd);
/* Initialize the texture unit mapping to a 1:1 mapping */
for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s)
{
- if (s < gl_info->limits.fragment_samplers)
+ if (s < gl_info->limits.combined_samplers)
{
ret->tex_unit_map[s] = s;
ret->rev_tex_unit_map[s] = s;
if (color_format->id == WINED3DFMT_P8_UINT)
color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
+ /* When "always_offscreen" is enabled, we only use the drawable for
+ * presentation blits, and don't do any rendering to it. That means we
+ * don't need depth or stencil buffers, and can mostly ignore the render
+ * target format. This wouldn't necessarily be quite correct for 10bpc
+ * display modes, but we don't currently support those.
+ * Using the same format regardless of the color/depth/stencil targets
+ * makes it much less likely that different wined3d instances will set
+ * conflicting pixel formats. */
+ if (wined3d_settings.always_offscreen)
+ {
+ color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
+ ds_format = wined3d_get_format(gl_info, WINED3DFMT_UNKNOWN);
+ }
+
/* Try to find a pixel format which matches our requirements. */
pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers, FALSE);
if (context_debug_output_enabled(gl_info))
{
- GL_EXTCALL(glDebugMessageCallbackARB(wined3d_debug_callback, ret));
+ GL_EXTCALL(glDebugMessageCallback(wined3d_debug_callback, ret));
if (TRACE_ON(d3d_synchronous))
- gl_info->gl_ops.gl.p_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
- GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE));
+ gl_info->gl_ops.gl.p_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE));
if (ERR_ON(d3d))
{
- GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR_ARB,
+ GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR,
GL_DONT_CARE, 0, NULL, GL_TRUE));
}
if (FIXME_ON(d3d))
{
- GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,
+ GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR,
GL_DONT_CARE, 0, NULL, GL_TRUE));
- GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,
+ GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR,
GL_DONT_CARE, 0, NULL, GL_TRUE));
- GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PORTABILITY_ARB,
+ GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_PORTABILITY,
GL_DONT_CARE, 0, NULL, GL_TRUE));
}
if (WARN_ON(d3d_perf))
{
- GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB,
+ GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE,
GL_DONT_CARE, 0, NULL, GL_TRUE));
}
}
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
+ if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ {
+ GLuint vao;
+
+ GL_EXTCALL(glGenVertexArrays(1, &vao));
+ GL_EXTCALL(glBindVertexArray(vao));
+ checkGLcall("creating VAO");
+ }
+
if (gl_info->supported[ARB_VERTEX_BLEND])
{
/* Direct3D always uses n-1 weights for n world matrices and uses
GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
}
device->shader_backend->shader_init_context_state(ret);
- ret->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
- | (1 << WINED3D_SHADER_TYPE_VERTEX)
- | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
+ ret->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
+ | (1u << WINED3D_SHADER_TYPE_VERTEX)
+ | (1u << WINED3D_SHADER_TYPE_GEOMETRY);
/* If this happens to be the first context for the device, dummy textures
* are not created yet. In that case, they will be created (and bound) by
static inline BOOL is_rt_mask_onscreen(DWORD rt_mask)
{
- return rt_mask & (1 << 31);
+ return rt_mask & (1u << 31);
}
static inline GLenum draw_buffer_from_rt_mask(DWORD rt_mask)
{
- return rt_mask & ~(1 << 31);
+ return rt_mask & ~(1u << 31);
}
/* Context activation is done by the caller. */
static BOOL match_depth_stencil_format(const struct wined3d_format *existing,
const struct wined3d_format *required)
{
- BYTE existing_depth, existing_stencil, required_depth, required_stencil;
-
if (existing == required)
return TRUE;
if ((existing->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
!= (required->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT))
return FALSE;
-
- getDepthStencilBits(existing, &existing_depth, &existing_stencil);
- getDepthStencilBits(required, &required_depth, &required_stencil);
-
- if(existing_depth < required_depth) return FALSE;
- /* If stencil bits are used the exact amount is required - otherwise wrapping
- * won't work correctly */
- if(required_stencil && required_stencil != existing_stencil) return FALSE;
+ if (existing->depth_size < required->depth_size)
+ return FALSE;
+ /* If stencil bits are used the exact amount is required - otherwise
+ * wrapping won't work correctly. */
+ if (required->stencil_size && required->stencil_size != existing->stencil_size)
+ return FALSE;
return TRUE;
}
-#if defined(STAGING_CSMT)
/* Context activation is done by the caller. */
-#else /* STAGING_CSMT */
-/* The caller provides a context */
-#endif /* STAGING_CSMT */
static void context_validate_onscreen_formats(struct wined3d_context *context,
const struct wined3d_rendertarget_view *depth_stencil)
{
else
return context_generate_rt_mask(context->offscreenBuffer);
#else /* STAGING_CSMT */
- surface_load_location(context->current_rt, WINED3D_LOCATION_TEXTURE_RGB);
+ surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB);
swapchain->render_to_fbo = TRUE;
swapchain_update_draw_bindings(swapchain);
context_set_render_offscreen(context, TRUE);
{
context->blit_targets[i] = wined3d_rendertarget_view_get_surface(rts[i]);
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
- rt_mask |= (1 << i);
+ rt_mask |= (1u << i);
}
while (i < context->gl_info->limits.buffers)
{
for (i = 0; i < rt_count; ++i)
{
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
- rt_mask |= (1 << i);
+ rt_mask |= (1u << i);
}
}
else
i = 0;
while (rt_mask_bits)
{
- rt_mask_bits &= ~(1 << i);
+ rt_mask_bits &= ~(1u << i);
if (!rts[i] || rts[i]->format->id == WINED3DFMT_NULL)
- rt_mask &= ~(1 << i);
+ rt_mask &= ~(1u << i);
i++;
}
DWORD i = context->rev_tex_unit_map[unit];
DWORD j = context->tex_unit_map[stage];
+ TRACE("Mapping stage %u to unit %u.\n", stage, unit);
context->tex_unit_map[stage] = unit;
if (i != WINED3D_UNMAPPED_STAGE && i != stage)
context->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE;
|| ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG1)
|| ((alpha_arg3 == WINED3DTA_TEXTURE)
&& (alpha_op == WINED3D_TOP_MULTIPLY_ADD || alpha_op == WINED3D_TOP_LERP)))
- context->fixed_function_usage_map |= (1 << i);
+ context->fixed_function_usage_map |= (1u << i);
if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
&& i < MAX_TEXTURES - 1)
- context->fixed_function_usage_map |= (1 << (i + 1));
+ context->fixed_function_usage_map |= (1u << (i + 1));
}
if (i < context->lowest_disabled_stage)
static void context_map_fixed_function_samplers(struct wined3d_context *context,
const struct wined3d_state *state)
{
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int i, tex;
WORD ffu_map;
- const struct wined3d_d3d_info *d3d_info = context->d3d_info;
context_update_fixed_function_usage_map(context, state);
+
+ if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS)
+ return;
+
ffu_map = context->fixed_function_usage_map;
if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages
static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state)
{
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_shader_resource_info *resource_info =
state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
unsigned int i;
- const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+
+ if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS)
+ return;
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
}
static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
- const struct wined3d_shader_resource_info *ps_resource_info,
- const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
+ const struct wined3d_shader_resource_info *ps_resource_info, DWORD unit)
{
DWORD current_mapping = context->rev_tex_unit_map[unit];
if (!ps_resource_info)
{
/* No pixel shader, check fixed function */
- return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping));
+ return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1u << current_mapping));
}
/* Pixel shader, check the shader's sampler map */
return !ps_resource_info[current_mapping].type;
}
- /* Used by a vertex sampler */
- return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
+ return TRUE;
}
static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
int i;
+ if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS)
+ return;
+
/* Note that we only care if a resource is used or not, not the
* resource's specific type. Otherwise we'd need to call
* shader_update_samplers() here for 1.x pixelshaders. */
DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
if (vs_resource_info[i].type)
{
- if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
- {
- /* Already mapped somewhere */
- continue;
- }
-
while (start >= 0)
{
- if (context_unit_free_for_vs(context, ps_resource_info, vs_resource_info, start))
+ if (context_unit_free_for_vs(context, ps_resource_info, start))
{
- context_map_stage(context, vsampler_idx, start);
- context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
+ if (context->tex_unit_map[vsampler_idx] != start)
+ {
+ context_map_stage(context, vsampler_idx, start);
+ context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
+ }
--start;
break;
--start;
}
+ if (context->tex_unit_map[vsampler_idx] == WINED3D_UNMAPPED_STAGE)
+ WARN("Couldn't find a free texture unit for vertex sampler %u.\n", i);
}
}
}
{
BOOL vs = use_vs(state);
BOOL ps = use_ps(state);
- /*
- * Rules are:
- * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but
- * that would be really messy and require shader recompilation
- * -> When the mapping of a stage is changed, sampler and ALL texture stage states have
- * to be reset. Because of that try to work with a 1:1 mapping as much as possible
- */
+
+ /* Try to go for a 1:1 mapping of the samplers when possible. Pixel shaders
+ * need a 1:1 map at the moment.
+ * When the mapping of a stage is changed, sampler and ALL texture stage
+ * states have to be reset. */
+
if (ps)
context_map_psamplers(context, state);
else
if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
&& element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
{
- stream_info->swizzle_map |= 1 << idx;
+ stream_info->swizzle_map |= 1u << idx;
}
- stream_info->use_map |= 1 << idx;
+ stream_info->use_map |= 1u << idx;
}
}
}
}
else
{
- WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
+ WORD slow_mask = -!d3d_info->ffp_generic_attributes & (1u << WINED3D_FFP_PSIZE);
slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
- & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
+ & ((1u << WINED3D_FFP_DIFFUSE) | (1u << WINED3D_FFP_SPECULAR));
if (((stream_info->position_transformed && !d3d_info->xyzrhw)
|| (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
}
}
+static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state)
+{
+ struct wined3d_shader_sampler_map_entry *entry;
+ struct wined3d_shader_resource_view *view;
+ struct wined3d_shader *shader;
+ unsigned int i, j;
+
+ for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
+ {
+ if (!(shader = state->shader[i]))
+ continue;
+
+ for (j = 0; j < WINED3D_MAX_CBS; ++j)
+ {
+ if (state->cb[i][j])
+ buffer_internal_preload(state->cb[i][j], context, state);
+ }
+
+ for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
+ {
+ entry = &shader->reg_maps.sampler_map.entries[j];
+
+ if (!(view = state->shader_resource_view[i][entry->resource_idx]))
+ {
+ WARN("No resource view bound at index %u, %u.\n", i, entry->resource_idx);
+ continue;
+ }
+
+ if (view->resource->type == WINED3D_RTYPE_BUFFER)
+ buffer_internal_preload(buffer_from_resource(view->resource), context, state);
+ else
+ wined3d_texture_load(wined3d_texture_from_resource(view->resource), context, FALSE);
+ }
+ }
+}
+
static void context_bind_shader_resources(struct wined3d_context *context, const struct wined3d_state *state)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
}
texture = wined3d_texture_from_resource(view->resource);
- wined3d_texture_load(texture, context, FALSE);
context_active_texture(context, gl_info, shader_types[i].base_idx + entry->bind_idx);
wined3d_texture_bind(texture, context, FALSE);
const struct StateEntry *state_table = context->state_table;
const struct wined3d_fb_state *fb = state->fb;
#endif /* STAGING_CSMT */
- unsigned int i, j;
+ unsigned int i;
WORD map;
if (!context_validate_rt_config(context->gl_info->limits.buffers,
* updating a resource location. */
context_update_tex_unit_map(context, state);
context_preload_textures(context, state);
+ context_load_shader_resources(context, state);
/* TODO: Right now the dependency on the vertex shader is necessary
* since context_stream_info_from_declaration depends on the reg_maps of
* the current VS but maybe it's possible to relax the coupling in some
buffer_get_sysmem(state->index_buffer, context);
}
- for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
- {
- for (j = 0; j < WINED3D_MAX_CBS; ++j)
- {
- if (state->cb[i][j])
- buffer_internal_preload(state->cb[i][j], context, state);
- }
- }
-
for (i = 0; i < context->numDirtyEntries; ++i)
{
DWORD rep = context->dirtyArray[i];
DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
- context->isStateDirty[idx] &= ~(1 << shift);
+ context->isStateDirty[idx] &= ~(1u << shift);
state_table[rep].apply(context, state, rep);
}
WINED3D_CS_OP_DELETE_GL_CONTEXTS,
WINED3D_CS_OP_GETDC,
WINED3D_CS_OP_RELEASEDC,
+ WINED3D_CS_OP_SAMPLER_DESTROY,
+ WINED3D_CS_OP_UPDATE_SUB_RESOURCE,
WINED3D_CS_OP_STOP,
};
struct wined3d_surface *surface;
};
+struct wined3d_cs_sampler_destroy
+{
+ enum wined3d_cs_op opcode;
+ struct wined3d_sampler *sampler;
+};
+
+struct wined3d_cs_update_sub_resource
+{
+ enum wined3d_cs_op opcode;
+ struct wined3d_resource *resource;
+ unsigned int sub_resource_idx, row_pitch, depth_pitch;
+ const struct wined3d_box *box;
+ const void *data;
+};
+
static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size)
{
LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1);
if (op->flags & WINED3DCLEAR_TARGET)
{
- for (i = 0; i < sizeof(cs->state.fb.render_targets) / sizeof(*cs->state.fb.render_targets); i++)
+ for (i = 0; i < device->adapter->gl_info.limits.buffers; i++)
{
if (cs->state.fb.render_targets[i])
wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource);
if (flags & WINED3DCLEAR_TARGET)
{
- for (i = 0; i < sizeof(state->fb.render_targets) / sizeof(*state->fb.render_targets); i++)
+ for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++)
{
if (state->fb.render_targets[i])
wined3d_resource_inc_fence(state->fb.render_targets[i]->resource);
if (cs->state.textures[i])
wined3d_resource_dec_fence(&cs->state.textures[i]->resource);
}
- for (i = 0; i < sizeof(cs->state.fb.render_targets) / sizeof(*cs->state.fb.render_targets); i++)
+ for (i = 0; i < gl_info->limits.buffers; i++)
{
if (cs->state.fb.render_targets[i] && wined3d_cs_colorwrite_enabled(&cs->state, i))
wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource);
if (state->textures[i])
wined3d_resource_inc_fence(&state->textures[i]->resource);
}
- for (i = 0; i < sizeof(state->fb.render_targets) / sizeof(*state->fb.render_targets); i++)
+ for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++)
{
if (state->fb.render_targets[i] && wined3d_cs_colorwrite_enabled(state, i))
wined3d_resource_inc_fence(state->fb.render_targets[i]->resource);
surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
if (prev_surface == cs->onscreen_depth_stencil)
{
- wined3d_surface_decref(cs->onscreen_depth_stencil);
+ wined3d_texture_decref(cs->onscreen_depth_stencil->container);
cs->onscreen_depth_stencil = NULL;
}
}
device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
}
- else if (prev && prev->format->depth_size != op->view->format->depth_size)
+ else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT)
+ != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT))
{
device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
}
if (op->set)
{
- switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
+ switch (op->flags)
{
case WINED3D_CKEY_DST_BLT:
texture->async.dst_blt_color_key = op->color_key;
}
else
{
- switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
+ switch (op->flags)
{
case WINED3D_CKEY_DST_BLT:
texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT;
object->OriginalIndex = light_idx;
}
- object->OriginalParms = op->light.OriginalParms;
- memcpy(&object->position, &op->light.position, sizeof(object->position));
- memcpy(&object->direction, &op->light.direction, sizeof(object->direction));
- object->exponent = op->light.exponent;
- object->cutoff = op->light.cutoff;
-
/* Update the live definitions if the light is currently assigned a glIndex. */
if (object->glIndex != -1)
{
device_invalidate_state(cs->device, STATE_ACTIVELIGHT(object->glIndex));
}
+ object->OriginalParms = op->light.OriginalParms;
+ object->position = op->light.position;
+ object->direction = op->light.direction;
+ object->exponent = op->light.exponent;
+ object->cutoff = op->light.cutoff;
+
return sizeof(*op);
}
cs->ops->finish(cs);
}
+static UINT wined3d_cs_exec_sampler_destroy(struct wined3d_cs *cs, const void *data)
+{
+ const struct wined3d_cs_sampler_destroy *op = data;
+
+ wined3d_sampler_destroy(op->sampler);
+
+ return sizeof(*op);
+}
+
+void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler)
+{
+ struct wined3d_cs_sampler_destroy *op;
+
+ op = cs->ops->require_space(cs, sizeof(*op));
+ op->opcode = WINED3D_CS_OP_SAMPLER_DESTROY;
+ op->sampler = sampler;
+
+ cs->ops->submit(cs, sizeof(*op));
+}
+
+static UINT wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data)
+{
+ const struct wined3d_cs_update_sub_resource *op = data;
+
+ struct wined3d_resource *sub_resource;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_const_bo_address addr;
+ struct wined3d_context *context;
+ struct wined3d_texture *texture;
+ struct wined3d_surface *surface;
+ POINT dst_point;
+ RECT src_rect;
+
+ texture = wined3d_texture_from_resource(op->resource);
+ sub_resource = wined3d_texture_get_sub_resource(texture, op->sub_resource_idx);
+ surface = surface_from_resource(sub_resource);
+
+ src_rect.left = 0;
+ src_rect.top = 0;
+ if (op->box)
+ {
+ src_rect.right = op->box->right - op->box->left;
+ src_rect.bottom = op->box->bottom - op->box->top;
+ dst_point.x = op->box->left;
+ dst_point.y = op->box->top;
+ }
+ else
+ {
+ src_rect.right = sub_resource->width;
+ src_rect.bottom = sub_resource->height;
+ dst_point.x = 0;
+ dst_point.y = 0;
+ }
+
+ addr.buffer_object = 0;
+ addr.addr = op->data;
+
+ context = context_acquire(cs->device, NULL);
+ gl_info = context->gl_info;
+
+ /* Only load the surface for partial updates. */
+ if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width
+ && src_rect.bottom == sub_resource->height)
+ wined3d_texture_prepare_texture(texture, context, FALSE);
+ else
+ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+
+ wined3d_surface_upload_data(surface, gl_info, op->resource->format,
+ &src_rect, op->row_pitch, &dst_point, FALSE, &addr);
+
+ context_release(context);
+
+ wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB);
+
+ return sizeof(*op);
+}
+
+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,
+ unsigned int depth_pitch)
+{
+ struct wined3d_cs_update_sub_resource *op;
+
+ op = cs->ops->require_space(cs, sizeof(*op));
+ op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
+ op->resource = resource;
+ op->sub_resource_idx = sub_resource_idx;
+ op->box = box;
+ op->data = data;
+ op->row_pitch = row_pitch;
+ op->depth_pitch = depth_pitch;
+
+ cs->ops->submit(cs, sizeof(*op));
+ /* The data pointer may go away, need to wait until the data is read. Copying the data may be faster.
+ * Don't forget to copy box as well in this case. */
+ cs->ops->finish(cs);
+}
+
static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
{
/* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop,
surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
if (prev_surface == device->onscreen_depth_stencil)
{
- wined3d_surface_decref(device->onscreen_depth_stencil);
+ wined3d_texture_decref(device->onscreen_depth_stencil->container);
device->onscreen_depth_stencil = NULL;
}
}
device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
}
- else if (prev && prev->format->depth_size != op->view->format->depth_size)
+ else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT)
+ != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT))
{
device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
}
if (op->set)
{
- switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
+ switch (op->flags)
{
case WINED3D_CKEY_DST_BLT:
texture->async.dst_blt_color_key = op->color_key;
}
else
{
- switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
+ switch (op->flags)
{
case WINED3D_CKEY_DST_BLT:
texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT;
/* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts,
/* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc,
/* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc,
+ /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy,
+ /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource,
};
static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio)
surface_modify_ds_location(cs->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB,
cs->onscreen_depth_stencil->ds_current_size.cx,
cs->onscreen_depth_stencil->ds_current_size.cy);
- wined3d_surface_decref(cs->onscreen_depth_stencil);
+ wined3d_texture_decref(cs->onscreen_depth_stencil->container);
}
cs->onscreen_depth_stencil = depth_stencil;
- wined3d_surface_incref(cs->onscreen_depth_stencil);
+ wined3d_texture_incref(cs->onscreen_depth_stencil->container);
}
static inline void poll_queries(struct wined3d_cs *cs)
surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB,
device->onscreen_depth_stencil->ds_current_size.cx,
device->onscreen_depth_stencil->ds_current_size.cy);
- wined3d_surface_decref(device->onscreen_depth_stencil);
+ wined3d_texture_decref(device->onscreen_depth_stencil->container);
}
device->onscreen_depth_stencil = depth_stencil;
- wined3d_surface_incref(device->onscreen_depth_stencil);
+ wined3d_texture_incref(device->onscreen_depth_stencil->container);
}
#endif /* STAGING_CSMT */
unsigned int i;
RECT ds_rect;
-#if defined(STAGING_CSMT)
context = context_acquire(device, target);
if (!context->valid)
{
}
gl_info = context->gl_info;
-#endif /* STAGING_CSMT */
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
* drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
* for the cleared parts, and the untouched parts.
if (rt)
#if defined(STAGING_CSMT)
wined3d_resource_load_location(&rt->resource, context, rt->container->resource.draw_binding);
- }
- }
#else /* STAGING_CSMT */
- surface_load_location(rt, rt->container->resource.draw_binding);
+ surface_load_location(rt, context, rt->container->resource.draw_binding);
+#endif /* STAGING_CSMT */
}
}
- context = context_acquire(device, target);
- if (!context->valid)
- {
- context_release(context);
- WARN("Invalid context, skipping clear.\n");
- return;
- }
- gl_info = context->gl_info;
-#endif /* STAGING_CSMT */
-
if (target)
{
render_offscreen = context->render_offscreen;
{
surface = device->cs->onscreen_depth_stencil;
device->cs->onscreen_depth_stencil = NULL;
- wined3d_surface_decref(surface);
+ wined3d_texture_decref(surface->container);
}
state_unbind_resources(&device->state);
wined3d_cs_emit_evict_resource(device->cs, resource);
}
+ wine_rb_clear(&device->samplers, device_free_sampler, NULL);
+
+ /* FIXME: Is this in the right place??? */
wined3d_cs_emit_delete_opengl_contexts(device->cs, device->swapchains[0]);
#else /* STAGING_CSMT */
{
surface = device->onscreen_depth_stencil;
device->onscreen_depth_stencil = NULL;
- wined3d_surface_decref(surface);
+ wined3d_texture_decref(surface->container);
}
if (device->fb.depth_stencil)
return NULL;
}
- *offset = device->state.stream_output[idx].offset;
+ if (offset)
+ *offset = device->state.stream_output[idx].offset;
return device->state.stream_output[idx].buffer;
}
prev_buffer = stream->buffer;
if (device->recording)
- device->recording->changed.streamSource |= 1 << stream_idx;
+ device->recording->changed.streamSource |= 1u << stream_idx;
if (prev_buffer == buffer
&& stream->stride == stride
{
stream->stride = stride;
stream->offset = offset;
+ wined3d_buffer_incref(buffer);
}
- if (buffer)
- wined3d_buffer_incref(buffer);
if (!device->recording)
wined3d_cs_emit_set_stream_source(device->cs, stream_idx, buffer, offset, stride);
if (prev_buffer)
stream->frequency = divider & 0x7fffff;
if (device->recording)
- device->recording->changed.streamFreq |= 1 << stream_idx;
+ device->recording->changed.streamFreq |= 1u << stream_idx;
else if (stream->frequency != old_freq || stream->flags != old_flags)
wined3d_cs_emit_set_stream_source_freq(device->cs, stream_idx, stream->frequency, stream->flags);
if (device->recording)
{
TRACE("Recording... not performing anything.\n");
- device->recording->changed.transform[d3dts >> 5] |= 1 << (d3dts & 0x1f);
+ device->recording->changed.transform[d3dts >> 5] |= 1u << (d3dts & 0x1f);
device->update_state->transforms[d3dts] = *matrix;
return;
}
}
if (device->recording)
- device->recording->changed.clipplane |= 1 << plane_idx;
+ device->recording->changed.clipplane |= 1u << plane_idx;
if (!memcmp(&device->update_state->clip_planes[plane_idx], plane, sizeof(*plane)))
{
if (device->recording)
{
TRACE("Recording... not performing anything.\n");
- device->recording->changed.renderState[state >> 5] |= 1 << (state & 0x1f);
+ device->recording->changed.renderState[state >> 5] |= 1u << (state & 0x1f);
return;
}
if (device->recording)
{
TRACE("Recording... not performing anything.\n");
- device->recording->changed.samplerState[sampler_idx] |= 1 << state;
+ device->recording->changed.samplerState[sampler_idx] |= 1u << state;
return;
}
if (device->recording)
{
for (i = start_register; i < count + start_register; ++i)
- device->recording->changed.vertexShaderConstantsB |= (1 << i);
+ device->recording->changed.vertexShaderConstantsB |= (1u << i);
}
else
{
if (device->recording)
{
for (i = start_register; i < count + start_register; ++i)
- device->recording->changed.vertexShaderConstantsI |= (1 << i);
+ device->recording->changed.vertexShaderConstantsI |= (1u << i);
}
else
{
if (device->recording)
{
for (i = start_register; i < count + start_register; ++i)
- device->recording->changed.pixelShaderConstantsB |= (1 << i);
+ device->recording->changed.pixelShaderConstantsB |= (1u << i);
}
else
{
if (device->recording)
{
for (i = start_register; i < count + start_register; ++i)
- device->recording->changed.pixelShaderConstantsI |= (1 << i);
+ device->recording->changed.pixelShaderConstantsI |= (1u << i);
}
else
{
DWORD numTextures;
HRESULT hr;
- if (stream_info->use_map & (1 << WINED3D_FFP_NORMAL))
+ if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL))
{
WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
}
- if (!(stream_info->use_map & (1 << WINED3D_FFP_POSITION)))
+ if (!(stream_info->use_map & (1u << WINED3D_FFP_POSITION)))
{
ERR("Source has no position mask\n");
return WINED3DERR_INVALIDCALL;
{
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE];
const DWORD *color_d = (const DWORD *)(element->data.addr + i * element->stride);
- if (!(stream_info->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE)))
{
static BOOL warned = FALSE;
/* What's the color value in the feedback buffer? */
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR];
const DWORD *color_s = (const DWORD *)(element->data.addr + i * element->stride);
- if (!(stream_info->use_map & (1 << WINED3D_FFP_SPECULAR)))
+ if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR)))
{
static BOOL warned = FALSE;
{
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index];
const float *tex_coord = (const float *)(element->data.addr + i * element->stride);
- if (!(stream_info->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + tex_index))))
+ if (!(stream_info->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + tex_index))))
{
ERR("No source texture, but destination requests one\n");
dest_ptr += GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
if (device->recording)
{
TRACE("Recording... not performing anything.\n");
- device->recording->changed.textureState[stage] |= 1 << state;
+ device->recording->changed.textureState[stage] |= 1u << state;
return;
}
}
if (device->recording)
- device->recording->changed.textures |= 1 << stage;
+ device->recording->changed.textures |= 1u << stage;
prev = device->update_state->textures[stage];
TRACE("Previous texture %p.\n", prev);
return device->state.textures[stage];
}
-HRESULT CDECL wined3d_device_get_back_buffer(const struct wined3d_device *device, UINT swapchain_idx,
- UINT backbuffer_idx, enum wined3d_backbuffer_type backbuffer_type, struct wined3d_surface **backbuffer)
-{
- struct wined3d_swapchain *swapchain;
-
- TRACE("device %p, swapchain_idx %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
- device, swapchain_idx, backbuffer_idx, backbuffer_type, backbuffer);
-
- if (!(swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
- return WINED3DERR_INVALIDCALL;
-
- if (!(*backbuffer = wined3d_swapchain_get_back_buffer(swapchain, backbuffer_idx, backbuffer_type)))
- return WINED3DERR_INVALIDCALL;
- return WINED3D_OK;
-}
-
HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
{
TRACE("device %p, caps %p.\n", device, caps);
return WINED3D_OK;
}
-HRESULT CDECL wined3d_device_present(const struct wined3d_device *device, const RECT *src_rect,
- const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags)
-{
- UINT i;
-
- TRACE("device %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
- device, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
- dst_window_override, dirty_region, flags);
-
- for (i = 0; i < device->swapchain_count; ++i)
- {
- wined3d_swapchain_present(device->swapchains[i], src_rect,
- dst_rect, dst_window_override, dirty_region, flags);
- }
-
- return WINED3D_OK;
-}
-
HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count,
const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
{
/* Only a prepare, since we're uploading the entire volume. */
wined3d_texture_prepare_texture(dst_volume->container, context, FALSE);
wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE);
+
wined3d_resource_get_memory(&src_volume->resource, src_volume->resource.map_binding, &data);
wined3d_volume_upload_data(dst_volume, context, wined3d_const_bo_address(&data));
wined3d_resource_invalidate_location(&dst_volume->resource, ~WINED3D_LOCATION_TEXTURE_RGB);
WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
+ if (dst_texture->resource.format != src_texture->resource.format)
+ {
+ WARN("Formats do not match, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
/* Verify that the source and destination textures are the same type. */
type = src_texture->resource.type;
return WINED3D_OK;
}
-HRESULT CDECL wined3d_device_get_front_buffer_data(const struct wined3d_device *device,
- UINT swapchain_idx, struct wined3d_surface *dst_surface)
-{
- struct wined3d_swapchain *swapchain;
-
- TRACE("device %p, swapchain_idx %u, dst_surface %p.\n", device, swapchain_idx, dst_surface);
-
- if (!(swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
- return WINED3DERR_INVALIDCALL;
-
- return wined3d_swapchain_get_front_buffer_data(swapchain, dst_surface);
-}
-
HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes)
{
const struct wined3d_state *state = &device->state;
return 0.0f;
}
+/* FIXME: Callers should probably use wined3d_device_update_sub_resource()
+ * instead. */
HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device,
struct wined3d_surface *src_surface, const RECT *src_rect,
struct wined3d_surface *dst_surface, const POINT *dst_point)
return WINED3DERR_INVALIDCALL;
}
- if ((src_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align(src_surface, src_rect))
+ if ((src_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+ && !surface_check_block_align_rect(src_surface, src_rect))
{
WARN("Source rectangle not block-aligned.\n");
return WINED3DERR_INVALIDCALL;
}
SetRect(&dst_rect, dst_point->x, dst_point->y, dst_point->x + update_w, dst_point->y + update_h);
- if ((dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align(dst_surface, &dst_rect))
+ if ((dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+ && !surface_check_block_align_rect(dst_surface, &dst_rect))
{
WARN("Destination rectangle not block-aligned.\n");
return WINED3DERR_INVALIDCALL;
}
}
+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)
+{
+ struct wined3d_surface *dst_surface, *src_surface;
+ struct wined3d_texture *dst_texture, *src_texture;
+ struct wined3d_resource *tmp;
+ RECT dst_rect, src_rect;
+ HRESULT hr;
+
+ 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 %p.\n",
+ device, dst_resource, dst_sub_resource_idx, dst_x, dst_y, dst_z,
+ src_resource, src_sub_resource_idx, src_box);
+
+ if (src_resource == dst_resource && src_sub_resource_idx == dst_sub_resource_idx)
+ {
+ WARN("Source and destination are the same sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (src_resource->type != dst_resource->type)
+ {
+ WARN("Resource types (%s / %s) don't match.\n",
+ debug_d3dresourcetype(dst_resource->type),
+ debug_d3dresourcetype(src_resource->type));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (src_resource->format->id != dst_resource->format->id)
+ {
+ WARN("Resource formats (%s / %s) don't match.\n",
+ debug_d3dformat(dst_resource->format->id),
+ debug_d3dformat(src_resource->format->id));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (dst_resource->type != WINED3D_RTYPE_TEXTURE)
+ {
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ dst_texture = wined3d_texture_from_resource(dst_resource);
+ if (!(tmp = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx)))
+ {
+ WARN("Invalid dst_sub_resource_idx %u.\n", dst_sub_resource_idx);
+ return WINED3DERR_INVALIDCALL;
+ }
+ dst_surface = surface_from_resource(tmp);
+
+ src_texture = wined3d_texture_from_resource(src_resource);
+ if (!(tmp = wined3d_texture_get_sub_resource(src_texture, src_sub_resource_idx)))
+ {
+ WARN("Invalid src_sub_resource_idx %u.\n", src_sub_resource_idx);
+ return WINED3DERR_INVALIDCALL;
+ }
+ src_surface = surface_from_resource(tmp);
+
+ dst_rect.left = dst_x;
+ dst_rect.top = dst_y;
+ dst_rect.right = dst_x + (src_box->right - src_box->left);
+ dst_rect.bottom = dst_y + (src_box->bottom - src_box->top);
+
+ src_rect.left = src_box->left;
+ src_rect.top = src_box->top;
+ src_rect.right = src_box->right;
+ src_rect.bottom = src_box->bottom;
+
+ if (FAILED(hr = wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
+ ERR("Failed to blit, hr %#x.\n", hr);
+
+ return hr;
+}
+
+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)
+{
+ struct wined3d_resource *sub_resource;
+#if defined(STAGING_CSMT)
+ struct wined3d_texture *texture;
+#else /* STAGING_CSMT */
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_const_bo_address addr;
+ struct wined3d_context *context;
+ struct wined3d_texture *texture;
+ struct wined3d_surface *surface;
+ POINT dst_point;
+ RECT src_rect;
+#endif /* STAGING_CSMT */
+
+ TRACE("device %p, resource %p, sub_resource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u.\n",
+ device, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
+
+ if (resource->type != WINED3D_RTYPE_TEXTURE)
+ {
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
+ return;
+ }
+
+ texture = wined3d_texture_from_resource(resource);
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+ {
+ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+ return;
+ }
+#if defined(STAGING_CSMT)
+
+#else /* STAGING_CSMT */
+ surface = surface_from_resource(sub_resource);
+
+ src_rect.left = 0;
+ src_rect.top = 0;
+#endif /* STAGING_CSMT */
+ if (box)
+ {
+ if (box->left >= box->right || box->right > sub_resource->width
+ || box->top >= box->bottom || box->bottom > sub_resource->height)
+ {
+ WARN("Invalid box (%u, %u, %u)->(%u, %u, %u) specified.\n",
+ box->left, box->top, box->front, box->right, box->bottom, box->back);
+ return;
+ }
+#if defined(STAGING_CSMT)
+ }
+
+ wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
+#else /* STAGING_CSMT */
+
+ src_rect.right = box->right - box->left;
+ src_rect.bottom = box->bottom - box->top;
+ dst_point.x = box->left;
+ dst_point.y = box->top;
+ }
+ else
+ {
+ src_rect.right = sub_resource->width;
+ src_rect.bottom = sub_resource->height;
+ dst_point.x = 0;
+ dst_point.y = 0;
+ }
+
+ addr.buffer_object = 0;
+ addr.addr = data;
+
+ context = context_acquire(resource->device, NULL);
+ gl_info = context->gl_info;
+
+ /* Only load the surface for partial updates. */
+ if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width
+ && src_rect.bottom == sub_resource->height)
+ wined3d_texture_prepare_texture(texture, context, FALSE);
+ else
+ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+
+ wined3d_surface_upload_data(surface, gl_info, resource->format,
+ &src_rect, row_pitch, &dst_point, FALSE, &addr);
+
+ context_release(context);
+
+ surface_validate_location(surface, WINED3D_LOCATION_TEXTURE_RGB);
+ surface_invalidate_location(surface, ~WINED3D_LOCATION_TEXTURE_RGB);
+#endif /* STAGING_CSMT */
+}
+
HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, const struct wined3d_color *color)
{
wined3d_cs_emit_set_depth_stencil_view(device->cs, view);
if (prev)
wined3d_rendertarget_view_decref(prev);
-}
-
-HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device,
- UINT x_hotspot, UINT y_hotspot, struct wined3d_surface *cursor_image)
-{
- TRACE("device %p, x_hotspot %u, y_hotspot %u, cursor_image %p.\n",
- device, x_hotspot, y_hotspot, cursor_image);
#else /* STAGING_CSMT */
struct wined3d_rendertarget_view *prev;
}
return texture;
+#endif /* STAGING_CSMT */
}
HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device,
- UINT x_hotspot, UINT y_hotspot, struct wined3d_surface *cursor_image)
+ UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx)
{
- TRACE("device %p, x_hotspot %u, y_hotspot %u, cursor_image %p.\n",
- device, x_hotspot, y_hotspot, cursor_image);
+ struct wined3d_display_mode mode;
+ struct wined3d_map_desc map_desc;
+ struct wined3d_resource *sub_resource;
+ struct wined3d_surface *cursor_image;
+ HRESULT hr;
+
+ TRACE("device %p, x_hotspot %u, y_hotspot %u, texture %p, sub_resource_idx %u.\n",
+ device, x_hotspot, y_hotspot, texture, sub_resource_idx);
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))
+ || sub_resource->type != WINED3D_RTYPE_SURFACE)
+ return WINED3DERR_INVALIDCALL;
+
+ cursor_image = surface_from_resource(sub_resource);
+#if !defined(STAGING_CSMT)
if (device->cursor_texture)
{
wined3d_texture_decref(device->cursor_texture);
device->cursor_texture = NULL;
}
-#endif /* STAGING_CSMT */
- if (cursor_image)
+#endif /* STAGING_CSMT */
+ if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM)
{
- struct wined3d_display_mode mode;
- struct wined3d_map_desc map_desc;
- HRESULT hr;
-
- /* MSDN: Cursor must be A8R8G8B8 */
- if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM)
- {
- WARN("surface %p has an invalid format.\n", cursor_image);
- return WINED3DERR_INVALIDCALL;
- }
+ WARN("Surface %p has an invalid format %s.\n",
+ cursor_image, debug_d3dformat(cursor_image->resource.format->id));
+ return WINED3DERR_INVALIDCALL;
+ }
- if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode, NULL)))
- {
- ERR("Failed to get display mode, hr %#x.\n", hr);
- return WINED3DERR_INVALIDCALL;
- }
+ if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode, NULL)))
+ {
+ ERR("Failed to get display mode, hr %#x.\n", hr);
+ return WINED3DERR_INVALIDCALL;
+ }
- /* MSDN: Cursor must be smaller than the display mode */
- if (cursor_image->resource.width > mode.width || cursor_image->resource.height > mode.height)
- {
- WARN("Surface %p dimensions are %ux%u, but screen dimensions are %ux%u.\n",
- cursor_image, cursor_image->resource.width, cursor_image->resource.height,
- mode.width, mode.height);
- return WINED3DERR_INVALIDCALL;
- }
+ if (cursor_image->resource.width > mode.width || cursor_image->resource.height > mode.height)
+ {
+ WARN("Surface %p dimensions are %ux%u, but screen dimensions are %ux%u.\n",
+ cursor_image, cursor_image->resource.width, cursor_image->resource.height,
+ mode.width, mode.height);
+ return WINED3DERR_INVALIDCALL;
+ }
- /* TODO: MSDN: Cursor sizes must be a power of 2 */
+ /* TODO: MSDN: Cursor sizes must be a power of 2 */
- /* Do not store the surface's pointer because the application may
- * release it after setting the cursor image. Windows doesn't
- * addref the set surface, so we can't do this either without
- * creating circular refcount dependencies. */
-#if defined(STAGING_CSMT)
- device->cursorWidth = cursor_image->resource.width;
- device->cursorHeight = cursor_image->resource.height;
-#else /* STAGING_CSMT */
- if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image)))
- {
- ERR("Failed to create cursor texture.\n");
- return WINED3DERR_INVALIDCALL;
- }
+ /* Do not store the surface's pointer because the application may
+ * release it after setting the cursor image. Windows doesn't
+ * addref the set surface, so we can't do this either without
+ * creating circular refcount dependencies. */
+#if !defined(STAGING_CSMT)
+ if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image)))
+ {
+ ERR("Failed to create cursor texture.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
#endif /* STAGING_CSMT */
- device->cursorWidth = cursor_image->resource.width;
- device->cursorHeight = cursor_image->resource.height;
+ if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32)
+ {
+ UINT mask_size = cursor_image->resource.width * cursor_image->resource.height / 8;
+ ICONINFO cursor_info;
+ DWORD *mask_bits;
+ HCURSOR cursor;
- if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32)
- {
- UINT mask_size = cursor_image->resource.width * cursor_image->resource.height / 8;
- ICONINFO cursorInfo;
- DWORD *maskBits;
- HCURSOR cursor;
-
- /* 32-bit user32 cursors ignore the alpha channel if it's all
- * zeroes, and use the mask instead. Fill the mask with all ones
- * to ensure we still get a fully transparent cursor. */
- maskBits = HeapAlloc(GetProcessHeap(), 0, mask_size);
- memset(maskBits, 0xff, mask_size);
- wined3d_surface_map(cursor_image, &map_desc, NULL,
- WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY);
- TRACE("width: %u height: %u.\n", cursor_image->resource.width, cursor_image->resource.height);
-
- cursorInfo.fIcon = FALSE;
- cursorInfo.xHotspot = x_hotspot;
- cursorInfo.yHotspot = y_hotspot;
- cursorInfo.hbmMask = CreateBitmap(cursor_image->resource.width, cursor_image->resource.height,
- 1, 1, maskBits);
- cursorInfo.hbmColor = CreateBitmap(cursor_image->resource.width, cursor_image->resource.height,
- 1, 32, map_desc.data);
- wined3d_surface_unmap(cursor_image);
- /* Create our cursor and clean up. */
- cursor = CreateIconIndirect(&cursorInfo);
- if (cursorInfo.hbmMask) DeleteObject(cursorInfo.hbmMask);
- if (cursorInfo.hbmColor) DeleteObject(cursorInfo.hbmColor);
- if (device->hardwareCursor) DestroyCursor(device->hardwareCursor);
- device->hardwareCursor = cursor;
- if (device->bCursorVisible) SetCursor( cursor );
- HeapFree(GetProcessHeap(), 0, maskBits);
- }
+ /* 32-bit user32 cursors ignore the alpha channel if it's all
+ * zeroes, and use the mask instead. Fill the mask with all ones
+ * to ensure we still get a fully transparent cursor. */
+ if (!(mask_bits = HeapAlloc(GetProcessHeap(), 0, mask_size)))
+ return E_OUTOFMEMORY;
+ memset(mask_bits, 0xff, mask_size);
+
+ wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY);
+ cursor_info.fIcon = FALSE;
+ cursor_info.xHotspot = x_hotspot;
+ cursor_info.yHotspot = y_hotspot;
+ cursor_info.hbmMask = CreateBitmap(cursor_image->resource.width,
+ cursor_image->resource.height, 1, 1, mask_bits);
+ cursor_info.hbmColor = CreateBitmap(cursor_image->resource.width,
+ cursor_image->resource.height, 1, 32, map_desc.data);
+ wined3d_surface_unmap(cursor_image);
+
+ /* Create our cursor and clean up. */
+ cursor = CreateIconIndirect(&cursor_info);
+ if (cursor_info.hbmMask)
+ DeleteObject(cursor_info.hbmMask);
+ if (cursor_info.hbmColor)
+ DeleteObject(cursor_info.hbmColor);
+ if (device->hardwareCursor)
+ DestroyCursor(device->hardwareCursor);
+ device->hardwareCursor = cursor;
+ if (device->bCursorVisible)
+ SetCursor(cursor);
+
+ HeapFree(GetProcessHeap(), 0, mask_bits);
}
+ TRACE("New cursor dimensions are %ux%u.\n", cursor_image->resource.width, cursor_image->resource.height);
+ device->cursorWidth = cursor_image->resource.width;
+ device->cursorHeight = cursor_image->resource.height;
device->xHotSpot = x_hotspot;
device->yHotSpot = y_hotspot;
+
return WINED3D_OK;
}
context = context_acquire(device, NULL);
gl_info = context->gl_info;
-
- wine_rb_clear(&device->samplers, device_free_sampler, NULL);
#else /* STAGING_CSMT */
resource->resource_ops->resource_unload(resource);
}
const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
wined3d_device_reset_cb callback, BOOL reset_state)
{
- enum wined3d_format_id backbuffer_format = swapchain_desc->backbuffer_format;
struct wined3d_resource *resource, *cursor;
struct wined3d_swapchain *swapchain;
struct wined3d_display_mode m;
BOOL DisplayModeChanged;
- BOOL update_desc = FALSE;
- UINT backbuffer_width = swapchain_desc->backbuffer_width;
- UINT backbuffer_height = swapchain_desc->backbuffer_height;
HRESULT hr = WINED3D_OK;
unsigned int i;
- TRACE("device %p, swapchain_desc %p, mode %p, callback %p.\n", device, swapchain_desc, mode, callback);
+ TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n",
+ device, swapchain_desc, mode, callback, reset_state);
+
#if defined(STAGING_CSMT)
wined3d_cs_emit_glfinish(device->cs);
device->cs->ops->finish(device->cs);
-#endif /* STAGING_CSMT */
+#endif /* STAGING_CSMT */
if (!(swapchain = wined3d_device_get_swapchain(device, 0)))
{
ERR("Failed to get the first implicit swapchain.\n");
if (device->cs->onscreen_depth_stencil)
{
- wined3d_surface_decref(device->cs->onscreen_depth_stencil);
+ wined3d_texture_decref(device->cs->onscreen_depth_stencil->container);
device->cs->onscreen_depth_stencil = NULL;
#else /* STAGING_CSMT */
if (device->onscreen_depth_stencil)
{
- wined3d_surface_decref(device->onscreen_depth_stencil);
+ wined3d_texture_decref(device->onscreen_depth_stencil->container);
device->onscreen_depth_stencil = NULL;
#endif /* STAGING_CSMT */
}
device->cs->ops->finish(device->cs);
#endif /* STAGING_CSMT */
- /* Is it necessary to recreate the gl context? Actually every setting can be changed
- * on an existing gl context, so there's no real need for recreation.
- *
- * TODO: Figure out how Reset influences resources in D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEMORY and D3DPOOL_MANAGED
- *
- * TODO: Figure out what happens to explicit swapchains, or if we have more than one implicit swapchain
- */
TRACE("New params:\n");
TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width);
TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height);
swapchain->desc.swap_interval = swapchain_desc->swap_interval;
swapchain->desc.auto_restore_display_mode = swapchain_desc->auto_restore_display_mode;
- /* What to do about these? */
- if (swapchain_desc->backbuffer_count
- && swapchain_desc->backbuffer_count != swapchain->desc.backbuffer_count)
- FIXME("Cannot change the back buffer count yet.\n");
-
if (swapchain_desc->device_window
&& swapchain_desc->device_window != swapchain->desc.device_window)
{
m.refresh_rate = swapchain_desc->refresh_rate;
m.format_id = swapchain_desc->backbuffer_format;
m.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
- }
-
- if (!backbuffer_width || !backbuffer_height)
- {
- /* The application is requesting that either the swapchain width or
- * height be set to the corresponding dimension in the window's
- * client rect. */
-
- RECT client_rect;
- if (!swapchain_desc->windowed)
- return WINED3DERR_INVALIDCALL;
-
- if (!GetClientRect(swapchain->device_window, &client_rect))
- {
- ERR("Failed to get client rect, last error %#x.\n", GetLastError());
- return WINED3DERR_INVALIDCALL;
- }
-
- if (!backbuffer_width)
- backbuffer_width = client_rect.right;
-
- if (!backbuffer_height)
- backbuffer_height = client_rect.bottom;
- }
-
- if (backbuffer_width != swapchain->desc.backbuffer_width
- || backbuffer_height != swapchain->desc.backbuffer_height)
- {
- if (!swapchain_desc->windowed)
+ if ((m.width != swapchain->desc.backbuffer_width
+ || m.height != swapchain->desc.backbuffer_height))
DisplayModeChanged = TRUE;
-
- swapchain->desc.backbuffer_width = backbuffer_width;
- swapchain->desc.backbuffer_height = backbuffer_height;
- update_desc = TRUE;
- }
-
- if (backbuffer_format == WINED3DFMT_UNKNOWN)
- {
- if (!swapchain_desc->windowed)
- return WINED3DERR_INVALIDCALL;
- backbuffer_format = swapchain->original_mode.format_id;
- }
-
- if (backbuffer_format != swapchain->desc.backbuffer_format)
- {
- swapchain->desc.backbuffer_format = backbuffer_format;
- update_desc = TRUE;
- }
-
- if (swapchain_desc->multisample_type != swapchain->desc.multisample_type
- || swapchain_desc->multisample_quality != swapchain->desc.multisample_quality)
- {
- swapchain->desc.multisample_type = swapchain_desc->multisample_type;
- swapchain->desc.multisample_quality = swapchain_desc->multisample_quality;
- update_desc = TRUE;
- }
-
- if (update_desc)
- {
- UINT i;
-
- if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
- swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
- swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
- return hr;
-
- for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
- {
- if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width,
- swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
- swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
- return hr;
- }
- }
-
-#if !defined(STAGING_CSMT)
- if (device->auto_depth_stencil_view)
- {
- wined3d_rendertarget_view_decref(device->auto_depth_stencil_view);
- device->auto_depth_stencil_view = NULL;
- }
-#endif /* STAGING_CSMT */
- if (swapchain->desc.enable_auto_depth_stencil)
- {
- struct wined3d_resource_desc surface_desc;
- struct wined3d_surface *surface;
-
- TRACE("Creating the depth stencil buffer\n");
-
- surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
- surface_desc.format = swapchain->desc.auto_depth_stencil_format;
- surface_desc.multisample_type = swapchain->desc.multisample_type;
- surface_desc.multisample_quality = swapchain->desc.multisample_quality;
- surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
- surface_desc.pool = WINED3D_POOL_DEFAULT;
- surface_desc.width = swapchain->desc.backbuffer_width;
- surface_desc.height = swapchain->desc.backbuffer_height;
- surface_desc.depth = 1;
- surface_desc.size = 0;
-
- if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
- device->device_parent, &surface_desc, &surface)))
- {
- ERR("Failed to create the auto depth/stencil surface, hr %#x.\n", hr);
- return WINED3DERR_INVALIDCALL;
- }
-
- hr = wined3d_rendertarget_view_create_from_surface(surface,
- NULL, &wined3d_null_parent_ops, &device->auto_depth_stencil_view);
- wined3d_surface_decref(surface);
- if (FAILED(hr))
- {
- ERR("Failed to create rendertarget view, hr %#x.\n", hr);
- return hr;
- }
-
- wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view);
- }
-
-#if !defined(STAGING_CSMT)
- if (device->back_buffer_view)
- {
- wined3d_rendertarget_view_decref(device->back_buffer_view);
- device->back_buffer_view = NULL;
- }
-#endif /* STAGING_CSMT */
- if (swapchain->desc.backbuffer_count && FAILED(hr = wined3d_rendertarget_view_create_from_surface(
- surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)),
- NULL, &wined3d_null_parent_ops, &device->back_buffer_view)))
- {
- ERR("Failed to create rendertarget view, hr %#x.\n", hr);
- return hr;
}
if (!swapchain_desc->windowed != !swapchain->desc.windowed
device->exStyle = exStyle;
}
+ if (FAILED(hr = wined3d_swapchain_resize_buffers(swapchain, swapchain_desc->backbuffer_count,
+ swapchain_desc->backbuffer_width, swapchain_desc->backbuffer_height, swapchain_desc->backbuffer_format,
+ swapchain_desc->multisample_type, swapchain_desc->multisample_quality)))
+ return hr;
+
+#if !defined(STAGING_CSMT)
+ if (device->auto_depth_stencil_view)
+ {
+ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view);
+ device->auto_depth_stencil_view = NULL;
+ }
+#endif /* STAGING_CSMT */
+ if (swapchain->desc.enable_auto_depth_stencil)
+ {
+ struct wined3d_resource_desc texture_desc;
+ struct wined3d_texture *texture;
+ struct wined3d_rendertarget_view_desc view_desc;
+
+ TRACE("Creating the depth stencil buffer\n");
+
+ texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ texture_desc.format = swapchain->desc.auto_depth_stencil_format;
+ texture_desc.multisample_type = swapchain->desc.multisample_type;
+ texture_desc.multisample_quality = swapchain->desc.multisample_quality;
+ texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
+ texture_desc.pool = WINED3D_POOL_DEFAULT;
+ texture_desc.width = swapchain->desc.backbuffer_width;
+ texture_desc.height = swapchain->desc.backbuffer_height;
+ texture_desc.depth = 1;
+ texture_desc.size = 0;
+
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
+ device->device_parent, &texture_desc, &texture)))
+ {
+ ERR("Failed to create the auto depth/stencil surface, hr %#x.\n", hr);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ view_desc.format_id = texture->resource.format->id;
+ view_desc.u.texture.level_idx = 0;
+ view_desc.u.texture.layer_idx = 0;
+ view_desc.u.texture.layer_count = 1;
+ hr = wined3d_rendertarget_view_create(&view_desc, &texture->resource,
+ NULL, &wined3d_null_parent_ops, &device->auto_depth_stencil_view);
+ wined3d_texture_decref(texture);
+ if (FAILED(hr))
+ {
+ ERR("Failed to create rendertarget view, hr %#x.\n", hr);
+ return hr;
+ }
+
+ wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view);
+ }
+
+#if !defined(STAGING_CSMT)
+ if (device->back_buffer_view)
+ {
+ wined3d_rendertarget_view_decref(device->back_buffer_view);
+ device->back_buffer_view = NULL;
+ }
+#endif /* STAGING_CSMT */
+ if (swapchain->desc.backbuffer_count && FAILED(hr = wined3d_rendertarget_view_create_from_surface(
+ surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)),
+ NULL, &wined3d_null_parent_ops, &device->back_buffer_view)))
+ {
+ ERR("Failed to create rendertarget view, hr %#x.\n", hr);
+ return hr;
+ }
+
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
if (reset_state)
wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
}
- swapchain_update_render_to_fbo(swapchain);
- swapchain_update_draw_bindings(swapchain);
-
if (reset_state && device->d3d_initialized)
hr = create_primary_opengl_context(device, swapchain);
context->dirtyArray[context->numDirtyEntries++] = rep;
idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
- context->isStateDirty[idx] |= (1 << shift);
+ context->isStateDirty[idx] |= (1u << shift);
}
}
gl_info = context->gl_info;
GL_EXTCALL(glGenBuffers(1, &ret->name));
- if (type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ 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_ARB_draw_buffers", ARB_DRAW_BUFFERS },
{"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX },
{"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED },
+ {"GL_ARB_ES2_compatibility", ARB_ES2_COMPATIBILITY },
{"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM },
{"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER },
{"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT },
GL_NEAREST, GL_NEAREST, GL_LINEAR,
};
-struct wined3d_caps_gl_ctx
-{
- HDC dc;
- HWND wnd;
- HGLRC gl_ctx;
- HDC restore_dc;
- HGLRC restore_gl_ctx;
-};
-
static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx)
{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+
TRACE("Destroying caps GL context.\n");
+ /* Both glDeleteProgram and glDeleteBuffers silently ignore 0 IDs but
+ * this function might be called before the relevant function pointers
+ * in gl_info are initialized. */
+ if (ctx->test_program_id || ctx->test_vbo)
+ {
+ GL_EXTCALL(glDeleteProgram(ctx->test_program_id));
+ GL_EXTCALL(glDeleteBuffers(1, &ctx->test_vbo));
+ }
+
if (!wglMakeCurrent(NULL, NULL))
ERR("Failed to disable caps GL context.\n");
return TRUE;
}
-static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx)
+static BOOL wined3d_caps_gl_ctx_create(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx)
{
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
goto fail;
}
+ ctx->gl_info = &adapter->gl_info;
return TRUE;
fail:
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS350M, "NVIDIA GeForce GTS 350M", DRIVER_NVIDIA_GEFORCE8, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_410M, "NVIDIA GeForce 410M", DRIVER_NVIDIA_GEFORCE8, 512},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT420, "NVIDIA GeForce GT 420", DRIVER_NVIDIA_GEFORCE8, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT425M, "NVIDIA GeForce GT 425M", DRIVER_NVIDIA_GEFORCE8, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT430, "NVIDIA GeForce GT 430", DRIVER_NVIDIA_GEFORCE8, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT440, "NVIDIA GeForce GT 440", DRIVER_NVIDIA_GEFORCE8, 1024},
{HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS450, "NVIDIA GeForce GTS 450", DRIVER_NVIDIA_GEFORCE8, 1024},
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD2600, "ATI Mobility Radeon HD 2600", DRIVER_AMD_R600, 256 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD2900, "ATI Radeon HD 2900 XT", DRIVER_AMD_R600, 512 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD3200, "ATI Radeon HD 3200 Graphics", DRIVER_AMD_R600, 128 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD3850, "ATI Radeon HD 3850 AGP", DRIVER_AMD_R600, 512 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD4200M, "ATI Mobility Radeon HD 4200", DRIVER_AMD_R600, 256 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD4350, "ATI Radeon HD 4350", DRIVER_AMD_R600, 256 },
{HW_VENDOR_AMD, CARD_AMD_RADEON_HD4600, "ATI Radeon HD 4600 Series", DRIVER_AMD_R600, 512 },
{"GTS 450", CARD_NVIDIA_GEFORCE_GTS450}, /* Geforce 400 - midend low */
{"GT 440", CARD_NVIDIA_GEFORCE_GT440}, /* Geforce 400 - lowend */
{"GT 430", CARD_NVIDIA_GEFORCE_GT430}, /* Geforce 400 - lowend */
+ {"GT 425M", CARD_NVIDIA_GEFORCE_GT425M}, /* Geforce 400 - lowend mobile */
{"GT 420", CARD_NVIDIA_GEFORCE_GT420}, /* Geforce 400 - lowend */
{"410M", CARD_NVIDIA_GEFORCE_410M}, /* Geforce 400 - lowend mobile */
{"GT 330", CARD_NVIDIA_GEFORCE_GT330}, /* Geforce 300 - highend */
/* R600 */
{"R680", CARD_AMD_RADEON_HD2900},
{"R600", CARD_AMD_RADEON_HD2900},
- {"RV670", CARD_AMD_RADEON_HD2900},
+ {"RV670", CARD_AMD_RADEON_HD3850},
{"RV635", CARD_AMD_RADEON_HD2600},
{"RV630", CARD_AMD_RADEON_HD2600},
{"RV620", CARD_AMD_RADEON_HD2350},
/* GL_ARB_draw_instanced */
USE_GL_FUNC(glDrawArraysInstancedARB)
USE_GL_FUNC(glDrawElementsInstancedARB)
+ /* GL_ARB_ES2_compatibility */
+ USE_GL_FUNC(glReleaseShaderCompiler)
+ USE_GL_FUNC(glShaderBinary)
+ USE_GL_FUNC(glGetShaderPrecisionFormat)
+ USE_GL_FUNC(glDepthRangef)
+ USE_GL_FUNC(glClearDepthf)
/* GL_ARB_framebuffer_object */
USE_GL_FUNC(glBindFramebuffer)
USE_GL_FUNC(glBindRenderbuffer)
USE_GL_FUNC(glBeginQuery) /* OpenGL 1.5 */
USE_GL_FUNC(glBindAttribLocation) /* OpenGL 2.0 */
USE_GL_FUNC(glBindBuffer) /* OpenGL 1.5 */
+ USE_GL_FUNC(glBindVertexArray) /* OpenGL 3.0 */
USE_GL_FUNC(glBlendColor) /* OpenGL 1.4 */
USE_GL_FUNC(glBlendEquation) /* OpenGL 1.4 */
USE_GL_FUNC(glBlendEquationSeparate) /* OpenGL 2.0 */
USE_GL_FUNC(glCompressedTexSubImage3D) /* OpenGL 1.3 */
USE_GL_FUNC(glCreateProgram) /* OpenGL 2.0 */
USE_GL_FUNC(glCreateShader) /* OpenGL 2.0 */
+ USE_GL_FUNC(glDebugMessageCallback) /* OpenGL 4.3 */
+ USE_GL_FUNC(glDebugMessageControl) /* OpenGL 4.3 */
+ USE_GL_FUNC(glDebugMessageInsert) /* OpenGL 4.3 */
USE_GL_FUNC(glDeleteBuffers) /* OpenGL 1.5 */
USE_GL_FUNC(glDeleteProgram) /* OpenGL 2.0 */
USE_GL_FUNC(glDeleteQueries) /* OpenGL 1.5 */
USE_GL_FUNC(glDeleteShader) /* OpenGL 2.0 */
+ USE_GL_FUNC(glDeleteVertexArrays) /* OpenGL 3.0 */
USE_GL_FUNC(glDetachShader) /* OpenGL 2.0 */
USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */
USE_GL_FUNC(glDrawArraysInstanced) /* OpenGL 3.1 */
USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */
USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */
USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */
+ USE_GL_FUNC(glGenVertexArrays) /* OpenGL 3.0 */
USE_GL_FUNC(glGetActiveUniform) /* OpenGL 2.0 */
USE_GL_FUNC(glGetAttachedShaders) /* OpenGL 2.0 */
USE_GL_FUNC(glGetAttribLocation) /* OpenGL 2.0 */
USE_GL_FUNC(glGetBufferSubData) /* OpenGL 1.5 */
USE_GL_FUNC(glGetCompressedTexImage) /* OpenGL 1.3 */
+ USE_GL_FUNC(glGetDebugMessageLog) /* OpenGL 4.3 */
USE_GL_FUNC(glGetProgramInfoLog) /* OpenGL 2.0 */
USE_GL_FUNC(glGetProgramiv) /* OpenGL 2.0 */
USE_GL_FUNC(glGetQueryiv) /* OpenGL 1.5 */
MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB);
MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB);
MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB);
+ MAP_GL_FUNCTION(glDebugMessageCallback, glDebugMessageCallbackARB);
+ MAP_GL_FUNCTION(glDebugMessageControl, glDebugMessageControlARB);
+ MAP_GL_FUNCTION(glDebugMessageInsert, glDebugMessageInsertARB);
MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB);
MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB);
MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB);
MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB);
MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB);
MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB);
+ MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB);
MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB);
MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB);
MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB);
MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB);
MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB);
MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB);
+ MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB);
MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB);
MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB);
MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB);
/* Context activation is done by the caller. */
static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
{
+ static const struct
+ {
+ enum wined3d_gl_extension extension;
+ DWORD min_gl_version;
+ }
+ core_extensions[] =
+ {
+ {EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2)},
+ {ARB_MULTISAMPLE, MAKEDWORD_VERSION(1, 3)},
+ {ARB_MULTITEXTURE, MAKEDWORD_VERSION(1, 3)},
+ {ARB_TEXTURE_BORDER_CLAMP, MAKEDWORD_VERSION(1, 3)},
+ {ARB_TEXTURE_COMPRESSION, MAKEDWORD_VERSION(1, 3)},
+ {ARB_TEXTURE_CUBE_MAP, MAKEDWORD_VERSION(1, 3)},
+ {ARB_DEPTH_TEXTURE, MAKEDWORD_VERSION(1, 4)},
+ {ARB_POINT_PARAMETERS, MAKEDWORD_VERSION(1, 4)},
+ {ARB_SHADOW, MAKEDWORD_VERSION(1, 4)},
+ {ARB_TEXTURE_MIRRORED_REPEAT, MAKEDWORD_VERSION(1, 4)},
+ {EXT_BLEND_COLOR, MAKEDWORD_VERSION(1, 4)},
+ {EXT_BLEND_FUNC_SEPARATE, MAKEDWORD_VERSION(1, 4)},
+ {EXT_BLEND_MINMAX, MAKEDWORD_VERSION(1, 4)},
+ {EXT_BLEND_SUBTRACT, MAKEDWORD_VERSION(1, 4)},
+ {EXT_STENCIL_WRAP, MAKEDWORD_VERSION(1, 4)},
+ {NV_POINT_SPRITE, MAKEDWORD_VERSION(1, 4)},
+ {ARB_OCCLUSION_QUERY, MAKEDWORD_VERSION(1, 5)},
+ {ARB_VERTEX_BUFFER_OBJECT, MAKEDWORD_VERSION(1, 5)},
+ {ARB_DRAW_BUFFERS, MAKEDWORD_VERSION(2, 0)},
+ {ARB_FRAGMENT_SHADER, MAKEDWORD_VERSION(2, 0)},
+ {ARB_SHADING_LANGUAGE_100, MAKEDWORD_VERSION(2, 0)},
+ {ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0)},
+ {ARB_VERTEX_SHADER, MAKEDWORD_VERSION(2, 0)},
+ {EXT_BLEND_EQUATION_SEPARATE, MAKEDWORD_VERSION(2, 0)},
+ {ARB_PIXEL_BUFFER_OBJECT, MAKEDWORD_VERSION(2, 1)},
+ {EXT_TEXTURE_SRGB, MAKEDWORD_VERSION(2, 1)},
+ {ARB_COLOR_BUFFER_FLOAT, MAKEDWORD_VERSION(3, 0)},
+ {ARB_DEPTH_BUFFER_FLOAT, MAKEDWORD_VERSION(3, 0)},
+ {ARB_FRAMEBUFFER_OBJECT, MAKEDWORD_VERSION(3, 0)},
+ {ARB_FRAMEBUFFER_SRGB, MAKEDWORD_VERSION(3, 0)},
+ {ARB_HALF_FLOAT_PIXEL, MAKEDWORD_VERSION(3, 0)},
+ {ARB_HALF_FLOAT_VERTEX, MAKEDWORD_VERSION(3, 0)},
+ {ARB_MAP_BUFFER_RANGE, MAKEDWORD_VERSION(3, 0)},
+ {ARB_TEXTURE_COMPRESSION_RGTC, MAKEDWORD_VERSION(3, 0)},
+ {ARB_TEXTURE_FLOAT, MAKEDWORD_VERSION(3, 0)},
+ {ARB_TEXTURE_RG, MAKEDWORD_VERSION(3, 0)},
+ {EXT_DRAW_BUFFERS2, MAKEDWORD_VERSION(3, 0)},
+ /* We don't want to enable EXT_GPU_SHADER4: even though similar
+ * functionality is available in core GL 3.0 / GLSL 1.30, it's different
+ * enough that reusing the same flag for the new features hurts more
+ * than it helps. */
+ /* EXT_framebuffer_object, EXT_framebuffer_blit,
+ * EXT_framebuffer_multisample and EXT_packed_depth_stencil
+ * are integrated into ARB_framebuffer_object. */
+
+ {ARB_DRAW_INSTANCED, MAKEDWORD_VERSION(3, 1)},
+ {ARB_UNIFORM_BUFFER_OBJECT, MAKEDWORD_VERSION(3, 1)},
+ {EXT_TEXTURE_SNORM, MAKEDWORD_VERSION(3, 1)},
+ /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */
+
+ {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
+ * extension for core-only support. */
+ {ARB_PROVOKING_VERTEX, MAKEDWORD_VERSION(3, 2)},
+ {ARB_SYNC, MAKEDWORD_VERSION(3, 2)},
+ {ARB_VERTEX_ARRAY_BGRA, MAKEDWORD_VERSION(3, 2)},
+
+ {ARB_BLEND_FUNC_EXTENDED, MAKEDWORD_VERSION(3, 3)},
+ {ARB_INSTANCED_ARRAYS, MAKEDWORD_VERSION(3, 3)},
+ {ARB_SAMPLER_OBJECTS, MAKEDWORD_VERSION(3, 3)},
+ {ARB_SHADER_BIT_ENCODING, MAKEDWORD_VERSION(3, 3)},
+ {ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)},
+
+ {ARB_MAP_BUFFER_ALIGNMENT, MAKEDWORD_VERSION(4, 2)},
+
+ {ARB_DEBUG_OUTPUT, MAKEDWORD_VERSION(4, 3)},
+ {ARB_INTERNALFORMAT_QUERY2, MAKEDWORD_VERSION(4, 3)},
+ };
struct wined3d_driver_info *driver_info = &adapter->driver_info;
const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
struct wined3d_gl_info *gl_info = &adapter->gl_info;
const char *WGL_Extensions = NULL;
enum wined3d_gl_vendor gl_vendor;
enum wined3d_pci_device device;
- DWORD gl_version;
+ DWORD gl_version, gl_ext_emul_mask;
HDC hdc;
- unsigned int i;
+ unsigned int i, j;
GLint context_profile = 0;
TRACE("adapter %p.\n", adapter);
parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map,
sizeof(wgl_extension_map) / sizeof(*wgl_extension_map));
- if (!gl_info->supported[EXT_TEXTURE3D] && gl_version >= MAKEDWORD_VERSION(1, 2))
- {
- TRACE("GL CORE: GL_EXT_texture3D support.\n");
- gl_info->supported[EXT_TEXTURE3D] = TRUE;
- }
-
- if (!gl_info->supported[NV_POINT_SPRITE] && gl_version >= MAKEDWORD_VERSION(1, 4))
- {
- TRACE("GL CORE: GL_NV_point_sprite support.\n");
- gl_info->supported[NV_POINT_SPRITE] = TRUE;
- }
-
- if ((!gl_info->supported[EXT_BLEND_MINMAX] || !gl_info->supported[EXT_BLEND_SUBTRACT])
- && gl_version >= MAKEDWORD_VERSION(1, 4))
+ for (i = 0; i < ARRAY_SIZE(core_extensions); ++i)
{
- TRACE("GL CORE: GL_EXT_blend_minmax / GL_EXT_blend_subtract support.\n");
- gl_info->supported[EXT_BLEND_MINMAX] = TRUE;
- gl_info->supported[EXT_BLEND_SUBTRACT] = TRUE;
- }
+ if (!gl_info->supported[core_extensions[i].extension]
+ && gl_version >= core_extensions[i].min_gl_version)
+ {
+ for (j = 0; j < ARRAY_SIZE(gl_extension_map); ++j)
+ if (gl_extension_map[j].extension == core_extensions[i].extension)
+ break;
- if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_version >= MAKEDWORD_VERSION(2, 0))
- {
- TRACE("GL CORE: GL_ARB_texture_non_power_of_two support.\n");
- gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = TRUE;
+ if (j < ARRAY_SIZE(gl_extension_map))
+ {
+ TRACE("GL CORE: %s support.\n", gl_extension_map[j].extension_string);
+ gl_info->supported[core_extensions[i].extension] = TRUE;
+ }
+ else
+ {
+ FIXME("GL extension %u not in the GL extensions map.\n", core_extensions[i].extension);
+ }
+ }
}
if (gl_info->supported[EXT_BLEND_MINMAX] || gl_info->supported[EXT_BLEND_SUBTRACT])
if (gl_version >= MAKEDWORD_VERSION(2, 0))
gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
+ if (gl_version >= MAKEDWORD_VERSION(3, 2))
+ gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE;
if (gl_info->supported[APPLE_FENCE])
{
adapter->d3d_info.limits.ps_version = shader_caps.ps_version;
adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
+ adapter->d3d_info.limits.varying_count = shader_caps.varying_count;
adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes;
adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices;
+ adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading;
adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
adapter->d3d_info.valid_rt_mask = 0;
for (i = 0; i < gl_info->limits.buffers; ++i)
- adapter->d3d_info.valid_rt_mask |= (1 << i);
+ adapter->d3d_info.valid_rt_mask |= (1u << i);
+
+ if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ {
+ GLuint vao;
+
+ GL_EXTCALL(glGenVertexArrays(1, &vao));
+ GL_EXTCALL(glBindVertexArray(vao));
+ checkGLcall("creating VAO");
+ }
fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
init_driver_info(gl_info, driver_info, card_vendor, device);
- add_gl_compat_wrappers(gl_info);
+ gl_ext_emul_mask = adapter->vertex_pipe->vp_get_emul_mask(gl_info)
+ | adapter->fragment_pipe->get_emul_mask(gl_info);
+ if (gl_ext_emul_mask & GL_EXT_EMUL_ARB_MULTITEXTURE)
+ install_gl_compat_wrapper(gl_info, ARB_MULTITEXTURE);
+ if (gl_ext_emul_mask & GL_EXT_EMUL_EXT_FOG_COORD)
+ install_gl_compat_wrapper(gl_info, EXT_FOG_COORD);
return TRUE;
}
static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
{
- BYTE redSize, greenSize, blueSize, alphaSize, colorBits;
-
/* Float formats need FBOs. If FBOs are used this function isn't called */
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
return FALSE;
- if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
- if (!getColorBits(format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
- {
- ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
- return FALSE;
- }
-
- if(cfg->redSize < redSize)
- return FALSE;
-
- if(cfg->greenSize < greenSize)
- return FALSE;
-
- if(cfg->blueSize < blueSize)
- return FALSE;
-
- if(cfg->alphaSize < alphaSize)
- return FALSE;
+ /* Probably a RGBA_float or color index mode. */
+ if (cfg->iPixelType != WGL_TYPE_RGBA_ARB)
+ return FALSE;
- return TRUE;
- }
+ if (cfg->redSize < format->red_size
+ || cfg->greenSize < format->green_size
+ || cfg->blueSize < format->blue_size
+ || cfg->alphaSize < format->alpha_size)
+ return FALSE;
- /* Probably a RGBA_float or color index mode */
- return FALSE;
+ return TRUE;
}
static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_info,
const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
{
- BYTE depthSize, stencilSize;
BOOL lockable = FALSE;
- if (!getDepthStencilBits(format, &depthSize, &stencilSize))
- {
- ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
- return FALSE;
- }
-
/* Float formats need FBOs. If FBOs are used this function isn't called */
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
return FALSE;
if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
lockable = TRUE;
- /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
- * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
- * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
- if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
+ /* On some modern cards like the Geforce8/9, GLX doesn't offer some
+ * dephth/stencil formats which D3D9 reports. We can safely report
+ * "compatible" formats (e.g. D24 can be used for D16) as long as we
+ * aren't dealing with a lockable format. This also helps D3D <= 7 as they
+ * expect D16 which isn't offered without this on Geforce8 cards. */
+ if (!(cfg->depthSize == format->depth_size || (!lockable && cfg->depthSize > format->depth_size)))
return FALSE;
- /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
- * allow more stencil bits than requested. */
- if(cfg->stencilSize < stencilSize)
+ /* Some cards like Intel i915 ones only offer D24S8 but lots of games also
+ * need a format without stencil. We can allow a mismatch if the format
+ * doesn't have any stencil bits. If it does have stencil bits the size
+ * must match, or stencil wrapping would break. */
+ if (format->stencil_size && cfg->stencilSize != format->stencil_size)
return FALSE;
return TRUE;
TRACE("Overriding MSAA quality levels to %i\n", *quality_levels);
}
else if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
- {
*quality_levels = gl_info->limits.samples;
- WARN("probably wrong, setting quality_levels to %d\n", *quality_levels);
- }
else
*quality_levels = 1;
}
return FALSE;
if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
{
- BYTE AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
- BYTE CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
const struct wined3d_pixel_format *cfgs = adapter->cfgs;
unsigned int i;
- getColorBits(adapter_format, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
- getColorBits(check_format, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
-
- /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
- * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
- if (!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue)))
+ /* In backbuffer mode the front and backbuffer share the same WGL
+ * pixelformat. The format must match in RGB, alpha is allowed to be
+ * different. (Only the backbuffer can have alpha.) */
+ if (adapter_format->red_size != check_format->red_size
+ || adapter_format->green_size != check_format->green_size
+ || adapter_format->blue_size != check_format->blue_size)
{
TRACE("[FAILED]\n");
return FALSE;
struct wined3d_device *object;
HRESULT hr;
- TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, device_parent %p, device %p.\n",
- wined3d, adapter_idx, device_type, focus_window, flags, device_parent, device);
+ TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, surface_alignment %u, device_parent %p, device %p.\n",
+ wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment, device_parent, device);
/* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
* number and create a device without a 3D adapter for 2D only operation. */
TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
adapter->luid.HighPart, adapter->luid.LowPart, adapter);
- if (!wined3d_caps_gl_ctx_create(&caps_gl_ctx))
+ if (!wined3d_caps_gl_ctx_create(adapter, &caps_gl_ctx))
{
ERR("Failed to get a GL context for adapter %p.\n", adapter);
return FALSE;
return FALSE;
}
- if (!wined3d_adapter_init_format_info(adapter))
+ if (!wined3d_adapter_init_format_info(adapter, &caps_gl_ctx))
{
ERR("Failed to initialize GL format info.\n");
wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
return FALSE;
}
+ gl_info->fixed_polyoffset_scale = wined3d_adapter_find_polyoffset_scale(&caps_gl_ctx, GL_DEPTH_COMPONENT);
+ if (gl_info->supported[ARB_DEPTH_BUFFER_FLOAT])
+ gl_info->float_polyoffset_scale = wined3d_adapter_find_polyoffset_scale(&caps_gl_ctx, GL_DEPTH32F_STENCIL8);
+
adapter->vram_bytes = adapter->driver_info.vram_bytes;
adapter->vram_bytes_used = 0;
TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->vram_bytes));
/* Start drawing in GL */
gl_info->gl_ops.gl.p_glBegin(glPrimType);
- if (si->use_map & (1 << WINED3D_FFP_POSITION))
+ if (si->use_map & (1u << WINED3D_FFP_POSITION))
{
element = &si->elements[WINED3D_FFP_POSITION];
position = element->data.addr;
}
- if (si->use_map & (1 << WINED3D_FFP_NORMAL))
+ if (si->use_map & (1u << WINED3D_FFP_NORMAL))
{
element = &si->elements[WINED3D_FFP_NORMAL];
normal = element->data.addr;
}
num_untracked_materials = context->num_untracked_materials;
- if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
+ if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
{
element = &si->elements[WINED3D_FFP_DIFFUSE];
diffuse = element->data.addr;
gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
- if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
+ if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
{
element = &si->elements[WINED3D_FFP_SPECULAR];
specular = element->data.addr;
continue;
}
- if (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
+ if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
{
element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
texCoords[coordIdx] = element->data.addr;
- tex_mask |= (1 << textureNo);
+ tex_mask |= (1u << textureNo);
}
else
{
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
const DWORD *src = ptr;
- DWORD c = *src & 0xff00ff00;
- c |= (*src & 0xff0000) >> 16;
- c |= (*src & 0xff) << 16;
+ DWORD c = *src & 0xff00ff00u;
+ c |= (*src & 0xff0000u) >> 16;
+ c |= (*src & 0xffu) << 16;
GL_EXTCALL(glVertexAttrib4Nubv(index, (GLubyte *)&c));
break;
}
for (i = MAX_ATTRIBS - 1; i >= 0; i--)
{
- if (!(si->use_map & (1 << i))) continue;
+ if (!(si->use_map & (1u << i))) continue;
ptr = si->elements[i].data.addr + si->elements[i].stride * SkipnStrides;
for (i = 0; i < sizeof(si->elements) / sizeof(*si->elements); ++i)
{
- if (!(si->use_map & (1 << i))) continue;
+ if (!(si->use_map & (1u << i))) continue;
if (state->streams[si->elements[i].stream_idx].flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
{
{
struct wined3d_stream_info_element *e;
- if (!(s->use_map & (1 << i))) continue;
+ if (!(s->use_map & (1u << i))) continue;
e = &s->elements[i];
if (e->data.buffer_object)
#if defined(STAGING_CSMT)
context = context_acquire(device, wined3d_rendertarget_view_get_surface(state->fb.render_targets[0]));
+#else /* STAGING_CSMT */
+ context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]));
+#endif /* STAGING_CSMT */
if (!context->valid)
{
context_release(context);
/* Invalidate the back buffer memory so LockRect will read it the next time */
for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
{
+#if defined(STAGING_CSMT)
struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(state->fb.render_targets[i]);
if (target)
{
if (ds->resource.locations & location)
#else /* STAGING_CSMT */
- if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
- {
- /* Invalidate the back buffer memory so LockRect will read it the next time */
- for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
- {
struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]);
if (target)
{
- surface_load_location(target, target->container->resource.draw_binding);
+ surface_load_location(target, context, target->container->resource.draw_binding);
surface_invalidate_location(target, ~target->container->resource.draw_binding);
}
}
}
- context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]));
- if (!context->valid)
- {
- context_release(context);
- WARN("Invalid context, skipping draw.\n");
- return;
- }
- gl_info = context->gl_info;
-
if (device->fb.depth_stencil)
{
/* Note that this depends on the context_acquire() call above to set
}
static void (WINE_GLAPI *old_fogcoord_glVertex4f) (GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glVertex4fv) (const GLfloat *pos) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glVertex3f) (GLfloat x, GLfloat y, GLfloat z) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glVertex3fv) (const GLfloat *pos) = NULL;
static void (WINE_GLAPI *old_fogcoord_glColor4f) (GLfloat r, GLfloat g, GLfloat b, GLfloat a) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glColor4fv) (const GLfloat *color) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glColor3f) (GLfloat r, GLfloat g, GLfloat b) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glColor3fv) (const GLfloat *color) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glColor4ub) (GLubyte r, GLubyte g, GLubyte b, GLubyte a) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glFogCoordfEXT) (GLfloat f) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glFogCoorddEXT) (GLdouble f) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glFogCoordfvEXT) (const GLfloat *f) = NULL;
-static void (WINE_GLAPI *old_fogcoord_glFogCoorddvEXT) (const GLdouble *f) = NULL;
static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
struct wined3d_context *ctx = context_get_current();
+
+ /* This can be called from draw_test_quad() and at that point there is no
+ * wined3d_context current. */
+ if (!ctx)
+ {
+ old_fogcoord_glVertex4f(x, y, z, w);
+ return;
+ }
if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) {
GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]};
GLfloat i;
static void WINE_GLAPI wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
struct wined3d_context *ctx = context_get_current();
+
+ /* This can be called from draw_test_quad() and at that point there is no
+ * wined3d_context current. */
+ if (!ctx)
+ {
+ old_fogcoord_glColor4f(r, g, b, a);
+ return;
+ }
ctx->color[0] = r;
ctx->color[1] = g;
ctx->color[2] = b;
/* End GL_EXT_fog_coord emulation */
-void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info)
+void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext)
{
- if (!gl_info->supported[ARB_MULTITEXTURE])
+ switch (ext)
{
- TRACE("Applying GL_ARB_multitexture emulation hooks\n");
- gl_info->gl_ops.ext.p_glActiveTexture = wine_glActiveTexture;
- gl_info->gl_ops.ext.p_glClientActiveTextureARB = wine_glClientActiveTextureARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord1fARB = wine_glMultiTexCoord1fARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB = wine_glMultiTexCoord1fvARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord2fARB = wine_glMultiTexCoord2fARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB = wine_glMultiTexCoord2fvARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord3fARB = wine_glMultiTexCoord3fARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB = wine_glMultiTexCoord3fvARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord4fARB = wine_glMultiTexCoord4fARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB = wine_glMultiTexCoord4fvARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord2svARB = wine_glMultiTexCoord2svARB;
- gl_info->gl_ops.ext.p_glMultiTexCoord4svARB = wine_glMultiTexCoord4svARB;
- if(old_multitex_glGetIntegerv) {
- FIXME("GL_ARB_multitexture glGetIntegerv hook already applied\n");
- } else {
+ case ARB_MULTITEXTURE:
+ if (gl_info->supported[ARB_MULTITEXTURE])
+ return;
+ if (gl_info->gl_ops.ext.p_glActiveTexture == wine_glActiveTexture)
+ {
+ FIXME("ARB_multitexture emulation hooks already applied.\n");
+ return;
+ }
+ TRACE("Applying GL_ARB_multitexture emulation hooks.\n");
+ gl_info->gl_ops.ext.p_glActiveTexture = wine_glActiveTexture;
+ gl_info->gl_ops.ext.p_glClientActiveTextureARB = wine_glClientActiveTextureARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord1fARB = wine_glMultiTexCoord1fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB = wine_glMultiTexCoord1fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord2fARB = wine_glMultiTexCoord2fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB = wine_glMultiTexCoord2fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord3fARB = wine_glMultiTexCoord3fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB = wine_glMultiTexCoord3fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord4fARB = wine_glMultiTexCoord4fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB = wine_glMultiTexCoord4fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord2svARB = wine_glMultiTexCoord2svARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord4svARB = wine_glMultiTexCoord4svARB;
old_multitex_glGetIntegerv = gl_info->gl_ops.gl.p_glGetIntegerv;
gl_info->gl_ops.gl.p_glGetIntegerv = wine_glGetIntegerv;
- }
- if(old_multitex_glGetFloatv) {
- FIXME("GL_ARB_multitexture glGetGloatv hook already applied\n");
- } else {
old_multitex_glGetFloatv = gl_info->gl_ops.gl.p_glGetFloatv;
gl_info->gl_ops.gl.p_glGetFloatv = wine_glGetFloatv;
- }
- if(old_multitex_glGetDoublev) {
- FIXME("GL_ARB_multitexture glGetDoublev hook already applied\n");
- } else {
old_multitex_glGetDoublev = gl_info->gl_ops.gl.p_glGetDoublev;
gl_info->gl_ops.gl.p_glGetDoublev = wine_glGetDoublev;
- }
- gl_info->supported[ARB_MULTITEXTURE] = TRUE;
- }
-
- if (!gl_info->supported[EXT_FOG_COORD])
- {
- /* This emulation isn't perfect. There are a number of potential problems, but they should
- * not matter in practise:
- *
- * Fog vs fragment shader: If we are using GL_ARB_fragment_program with the fog option, the
- * glDisable(GL_FOG) here won't matter. However, if we have GL_ARB_fragment_program, it is pretty
- * unlikely that we don't have GL_EXT_fog_coord. Besides, we probably have GL_ARB_vertex_program
- * too, which would allow fog coord emulation in a fixed function vertex pipeline replacement.
- *
- * Fog vs texture: We apply the fog in the vertex color. An app could set up texturing settings which
- * ignore the vertex color, thus effectively disabling our fog. However, in D3D this type of fog is
- * a per-vertex fog too, so the apps shouldn't do that.
- *
- * Fog vs lighting: The app could in theory use D3DFOG_NONE table and D3DFOG_NONE vertex fog with
- * untransformed vertices. That enables lighting and fog coords at the same time, and the lighting
- * calculations could affect the already blended in fog color. There's nothing we can do against that,
- * but most apps using fog color do their own lighting too and often even use RHW vertices. So live
- * with it.
- */
- TRACE("Applying GL_ARB_fog_coord emulation hooks\n");
-
- /* This probably means that the implementation doesn't advertise the extension, but implicitly supports
- * it via the GL core version, or someone messed around in the extension table in directx.c. Add version-
- * dependent loading for this extension if we ever hit this situation
- */
- if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
- {
- FIXME("GL implementation supports GL_ARB_fragment_program but not GL_EXT_fog_coord\n");
- FIXME("The fog coord emulation will most likely fail\n");
- }
- else if (gl_info->supported[ARB_FRAGMENT_SHADER])
- {
- FIXME("GL implementation supports GL_ARB_fragment_shader but not GL_EXT_fog_coord\n");
- FIXME("The fog coord emulation will most likely fail\n");
- }
+ gl_info->supported[ARB_MULTITEXTURE] = TRUE;
+ return;
+
+ case EXT_FOG_COORD:
+ /* This emulation isn't perfect. There are a number of potential problems, but they should
+ * not matter in practise:
+ *
+ * Fog vs fragment shader: If we are using GL_ARB_fragment_program with the fog option, the
+ * glDisable(GL_FOG) here won't matter. However, if we have GL_ARB_fragment_program, it is pretty
+ * unlikely that we don't have GL_EXT_fog_coord. Besides, we probably have GL_ARB_vertex_program
+ * too, which would allow fog coord emulation in a fixed function vertex pipeline replacement.
+ *
+ * Fog vs texture: We apply the fog in the vertex color. An app could set up texturing settings which
+ * ignore the vertex color, thus effectively disabling our fog. However, in D3D this type of fog is
+ * a per-vertex fog too, so the apps shouldn't do that.
+ *
+ * Fog vs lighting: The app could in theory use D3DFOG_NONE table and D3DFOG_NONE vertex fog with
+ * untransformed vertices. That enables lighting and fog coords at the same time, and the lighting
+ * calculations could affect the already blended in fog color. There's nothing we can do against that,
+ * but most apps using fog color do their own lighting too and often even use RHW vertices. So live
+ * with it.
+ */
+ if (gl_info->supported[EXT_FOG_COORD])
+ return;
+ if (gl_info->gl_ops.gl.p_glFogi == wine_glFogi)
+ {
+ FIXME("EXT_fog_coord emulation hooks already applied.\n");
+ return;
+ }
+ TRACE("Applying GL_ARB_fog_coord emulation hooks\n");
+
+ /* This probably means that the implementation doesn't advertise the extension, but implicitly supports
+ * it via the GL core version, or someone messed around in the extension table in directx.c. Add version-
+ * dependent loading for this extension if we ever hit this situation
+ */
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ FIXME("GL implementation supports GL_ARB_fragment_program but not GL_EXT_fog_coord\n");
+ FIXME("The fog coord emulation will most likely fail\n");
+ }
+ else if (gl_info->supported[ARB_FRAGMENT_SHADER])
+ {
+ FIXME("GL implementation supports GL_ARB_fragment_shader but not GL_EXT_fog_coord\n");
+ FIXME("The fog coord emulation will most likely fail\n");
+ }
- if(old_fogcoord_glFogi) {
- FIXME("GL_EXT_fogcoord glFogi hook already applied\n");
- } else {
old_fogcoord_glFogi = gl_info->gl_ops.gl.p_glFogi;
gl_info->gl_ops.gl.p_glFogi = wine_glFogi;
- }
- if(old_fogcoord_glFogiv) {
- FIXME("GL_EXT_fogcoord glFogiv hook already applied\n");
- } else {
old_fogcoord_glFogiv = gl_info->gl_ops.gl.p_glFogiv;
gl_info->gl_ops.gl.p_glFogiv = wine_glFogiv;
- }
- if(old_fogcoord_glFogf) {
- FIXME("GL_EXT_fogcoord glFogf hook already applied\n");
- } else {
old_fogcoord_glFogf = gl_info->gl_ops.gl.p_glFogf;
gl_info->gl_ops.gl.p_glFogf = wine_glFogf;
- }
- if(old_fogcoord_glFogfv) {
- FIXME("GL_EXT_fogcoord glFogfv hook already applied\n");
- } else {
old_fogcoord_glFogfv = gl_info->gl_ops.gl.p_glFogfv;
gl_info->gl_ops.gl.p_glFogfv = wine_glFogfv;
- }
- if(old_fogcoord_glEnable) {
- FIXME("GL_EXT_fogcoord glEnable hook already applied\n");
- } else {
old_fogcoord_glEnable = glEnableWINE;
glEnableWINE = wine_glEnable;
- }
- if(old_fogcoord_glDisable) {
- FIXME("GL_EXT_fogcoord glDisable hook already applied\n");
- } else {
old_fogcoord_glDisable = glDisableWINE;
glDisableWINE = wine_glDisable;
- }
- if(old_fogcoord_glVertex4f) {
- FIXME("GL_EXT_fogcoord glVertex4f hook already applied\n");
- } else {
old_fogcoord_glVertex4f = gl_info->gl_ops.gl.p_glVertex4f;
gl_info->gl_ops.gl.p_glVertex4f = wine_glVertex4f;
- }
- if(old_fogcoord_glVertex4fv) {
- FIXME("GL_EXT_fogcoord glVertex4fv hook already applied\n");
- } else {
- old_fogcoord_glVertex4fv = gl_info->gl_ops.gl.p_glVertex4fv;
gl_info->gl_ops.gl.p_glVertex4fv = wine_glVertex4fv;
- }
- if(old_fogcoord_glVertex3f) {
- FIXME("GL_EXT_fogcoord glVertex3f hook already applied\n");
- } else {
- old_fogcoord_glVertex3f = gl_info->gl_ops.gl.p_glVertex3f;
gl_info->gl_ops.gl.p_glVertex3f = wine_glVertex3f;
- }
- if(old_fogcoord_glVertex3fv) {
- FIXME("GL_EXT_fogcoord glVertex3fv hook already applied\n");
- } else {
- old_fogcoord_glVertex3fv = gl_info->gl_ops.gl.p_glVertex3fv;
gl_info->gl_ops.gl.p_glVertex3fv = wine_glVertex3fv;
- }
- if(old_fogcoord_glColor4f) {
- FIXME("GL_EXT_fogcoord glColor4f hook already applied\n");
- } else {
old_fogcoord_glColor4f = gl_info->gl_ops.gl.p_glColor4f;
gl_info->gl_ops.gl.p_glColor4f = wine_glColor4f;
- }
- if(old_fogcoord_glColor4fv) {
- FIXME("GL_EXT_fogcoord glColor4fv hook already applied\n");
- } else {
- old_fogcoord_glColor4fv = gl_info->gl_ops.gl.p_glColor4fv;
gl_info->gl_ops.gl.p_glColor4fv = wine_glColor4fv;
- }
- if(old_fogcoord_glColor3f) {
- FIXME("GL_EXT_fogcoord glColor3f hook already applied\n");
- } else {
- old_fogcoord_glColor3f = gl_info->gl_ops.gl.p_glColor3f;
gl_info->gl_ops.gl.p_glColor3f = wine_glColor3f;
- }
- if(old_fogcoord_glColor3fv) {
- FIXME("GL_EXT_fogcoord glColor3fv hook already applied\n");
- } else {
- old_fogcoord_glColor3fv = gl_info->gl_ops.gl.p_glColor3fv;
gl_info->gl_ops.gl.p_glColor3fv = wine_glColor3fv;
- }
- if(old_fogcoord_glColor4ub) {
- FIXME("GL_EXT_fogcoord glColor4ub hook already applied\n");
- } else {
- old_fogcoord_glColor4ub = gl_info->gl_ops.gl.p_glColor4ub;
gl_info->gl_ops.gl.p_glColor4ub = wine_glColor4ub;
- }
- if(old_fogcoord_glFogCoordfEXT) {
- FIXME("GL_EXT_fogcoord glFogCoordfEXT hook already applied\n");
- } else {
- old_fogcoord_glFogCoordfEXT = gl_info->gl_ops.ext.p_glFogCoordfEXT;
gl_info->gl_ops.ext.p_glFogCoordfEXT = wine_glFogCoordfEXT;
- }
- if(old_fogcoord_glFogCoordfvEXT) {
- FIXME("GL_EXT_fogcoord glFogCoordfvEXT hook already applied\n");
- } else {
- old_fogcoord_glFogCoordfvEXT = gl_info->gl_ops.ext.p_glFogCoordfvEXT;
gl_info->gl_ops.ext.p_glFogCoordfvEXT = wine_glFogCoordfvEXT;
- }
- if(old_fogcoord_glFogCoorddEXT) {
- FIXME("GL_EXT_fogcoord glFogCoorddEXT hook already applied\n");
- } else {
- old_fogcoord_glFogCoorddEXT = gl_info->gl_ops.ext.p_glFogCoorddEXT;
gl_info->gl_ops.ext.p_glFogCoorddEXT = wine_glFogCoorddEXT;
- }
- if(old_fogcoord_glFogCoorddvEXT) {
- FIXME("GL_EXT_fogcoord glFogCoorddvEXT hook already applied\n");
- } else {
- old_fogcoord_glFogCoorddvEXT = gl_info->gl_ops.ext.p_glFogCoorddvEXT;
gl_info->gl_ops.ext.p_glFogCoorddvEXT = wine_glFogCoorddvEXT;
- }
- gl_info->supported[EXT_FOG_COORD] = TRUE;
+ gl_info->supported[EXT_FOG_COORD] = TRUE;
+ return;
+
+ default:
+ FIXME("Extension %u emulation not supported.\n", ext);
}
}
struct wined3d_string_buffer *name;
DWORD coord_mask;
enum wined3d_data_type data_type;
+ BOOL output_single_component;
};
enum heap_node_op
}
/* Context activation is done by the caller. */
-static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
+void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
{
int length = 0;
char *log;
}
/* Context activation is done by the caller. */
-static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program)
+void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program)
{
GLint tmp;
static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps,
const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
{
- struct wined3d_color float_key;
+ struct wined3d_color float_key[2];
const struct wined3d_texture *texture = state->textures[0];
- wined3d_format_convert_color_to_float(texture->resource.format, NULL,
- texture->async.src_blt_color_key.color_space_high_value, &float_key);
- GL_EXTCALL(glUniform4fv(ps->color_key_location, 1, &float_key.r));
+ wined3d_format_get_float_color_key(texture->resource.format, &texture->async.src_blt_color_key, float_key);
+ GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r));
}
/* Context activation is done by the caller (state handler). */
return ret;
}
+static BOOL needs_legacy_glsl_syntax(const struct wined3d_gl_info *gl_info)
+{
+ return gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
+}
+
+static void PRINTF_ATTR(4, 5) declare_in_varying(const struct wined3d_gl_info *gl_info,
+ struct wined3d_string_buffer *buffer, BOOL flat, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ shader_addline(buffer, "%s%s ", flat ? "flat " : "",
+ needs_legacy_glsl_syntax(gl_info) ? "varying" : "in");
+ for (;;)
+ {
+ va_start(args, format);
+ ret = shader_vaddline(buffer, format, args);
+ va_end(args);
+ if (!ret)
+ return;
+ if (!string_buffer_resize(buffer, ret))
+ return;
+ }
+}
+
+static void PRINTF_ATTR(4, 5) declare_out_varying(const struct wined3d_gl_info *gl_info,
+ struct wined3d_string_buffer *buffer, BOOL flat, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ shader_addline(buffer, "%s%s ", flat ? "flat " : "",
+ needs_legacy_glsl_syntax(gl_info) ? "varying" : "out");
+ for (;;)
+ {
+ va_start(args, format);
+ ret = shader_vaddline(buffer, format, args);
+ va_end(args);
+ if (!ret)
+ return;
+ if (!string_buffer_resize(buffer, ret))
+ return;
+ }
+}
+
+static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned int idx)
+{
+ const struct wined3d_shader_signature *input_signature = &shader->input_signature;
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ const BOOL *input_reg_used = shader->u.ps.input_reg_used;
+ unsigned int i;
+
+ if (reg_maps->shader_version.major < 3)
+ return input_reg_used[idx];
+
+ for (i = 0; i < input_signature->element_count; ++i)
+ {
+ const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
+
+ if (!(reg_maps->input_registers & (1u << input->register_idx)))
+ continue;
+
+ if (shader_match_semantic(input->semantic_name, WINED3D_DECL_USAGE_COLOR)
+ && input->semantic_idx == idx)
+ {
+ if (input_reg_used[input->register_idx])
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
/** Generate the variable & register declarations for the GLSL output target */
static void shader_generate_glsl_declarations(const struct wined3d_context *context,
struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
* Writing gl_ClipVertex requires one uniform for each
* clipplane as well. */
max_constantsF = gl_info->limits.glsl_vs_float_constants - 3;
- if(ctx_priv->cur_vs_args->clip_enabled)
- {
+ if (vs_args->clip_enabled)
max_constantsF -= gl_info->limits.clipplanes;
- }
max_constantsF -= count_bits(reg_maps->integer_constants);
/* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
* so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
continue;
}
- shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << entry->sampler_idx));
+ shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << entry->sampler_idx));
switch (reg_maps->resource_info[entry->resource_idx].type)
{
case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL
- && (ps_args->np2_fixup & (1 << entry->resource_idx))
+ && (ps_args->np2_fixup & (1u << entry->resource_idx))
&& gl_info->supported[ARB_TEXTURE_RECTANGLE];
if (shadow_sampler)
{
for (i = 0; i < shader->limits->sampler; ++i)
{
- if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1 << i)))
+ if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1u << i)))
continue;
if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
if (map & 1) shader_addline(buffer, "ivec4 A%u;\n", i);
}
- /* Declare texture coordinate temporaries and initialize them */
- for (i = 0, map = reg_maps->texcoord; map; map >>= 1, ++i)
- {
- if (map & 1) shader_addline(buffer, "vec4 T%u = gl_TexCoord[%u];\n", i, i);
- }
-
if (version->type == WINED3D_SHADER_TYPE_VERTEX)
{
for (i = 0; i < shader->input_signature.element_count; ++i)
shader_addline(buffer, "} ffp_point;\n");
}
+ if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] && version->major < 3)
+ {
+ declare_out_varying(gl_info, buffer, vs_args->flatshading, "vec4 ffp_varying_diffuse;\n");
+ declare_out_varying(gl_info, buffer, vs_args->flatshading, "vec4 ffp_varying_specular;\n");
+ declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
+ }
+
shader_addline(buffer, "uniform vec4 posFixup;\n");
shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits->packed_output);
}
shader_addline(buffer, " float end;\n");
shader_addline(buffer, " float scale;\n");
shader_addline(buffer, "} ffp_fog;\n");
+
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ {
+ if (glsl_is_color_reg_read(shader, 0))
+ shader_addline(buffer, "vec4 ffp_varying_diffuse;\n");
+ if (glsl_is_color_reg_read(shader, 1))
+ shader_addline(buffer, "vec4 ffp_varying_specular;\n");
+ shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
+ shader_addline(buffer, "float ffp_varying_fogcoord;\n");
+ }
+ else
+ {
+ if (glsl_is_color_reg_read(shader, 0))
+ declare_in_varying(gl_info, buffer, ps_args->flatshading, "vec4 ffp_varying_diffuse;\n");
+ if (glsl_is_color_reg_read(shader, 1))
+ declare_in_varying(gl_info, buffer, ps_args->flatshading, "vec4 ffp_varying_specular;\n");
+ declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
+ declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
+ }
}
if (version->major >= 3)
#else /* STAGING_CSMT */
if (use_vs(state))
#endif /* STAGING_CSMT */
- shader_addline(buffer, "varying vec4 %s_link[%u];\n", prefix, in_count);
+ declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count);
shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
}
shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", i);
- if (reg_maps->luminanceparams & (1 << i))
+ if (reg_maps->luminanceparams & (1u << i))
{
shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", i);
shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", i);
if (version->type == WINED3D_SHADER_TYPE_VERTEX)
{
struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
- if (priv->cur_vs_args->swizzle_map & (1 << reg->idx[0].offset))
+ if (priv->cur_vs_args->swizzle_map & (1u << reg->idx[0].offset))
*is_color = TRUE;
sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset);
break;
* OS X doesn't see the NOP operation there. */
if (idx)
{
- if (shader->u.ps.declared_in_count > in_count)
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]
+ && shader->u.ps.declared_in_count > in_count)
{
sprintf(register_name,
"((%s + %u) > %u ? (%s + %u) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s + %u])",
}
else
{
- if (shader->u.ps.declared_in_count > in_count)
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]
+ && shader->u.ps.declared_in_count > in_count)
{
sprintf(register_name, "((%s) > %u ? (%s) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s])",
rel_param0.param_str, in_count - 1, rel_param0.param_str, in_count,
else
{
if (!reg->idx[0].offset)
- strcpy(register_name, "gl_Color");
+ strcpy(register_name, "ffp_varying_diffuse");
else
- strcpy(register_name, "gl_SecondaryColor");
+ strcpy(register_name, "ffp_varying_specular");
break;
}
break;
enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
const struct wined3d_gl_info *gl_info = ctx->gl_info;
BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
- && (priv->cur_ps_args->shadow & (1 << resource_idx));
+ && (priv->cur_ps_args->shadow & (1u << resource_idx));
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE];
BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
projected = FALSE;
- if (shadow)
- base = "shadow";
+ if (needs_legacy_glsl_syntax(gl_info))
+ {
+ if (shadow)
+ base = "shadow";
- type_part = resource_types[resource_type].type_part;
- if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D && texrect)
- type_part = "2DRect";
- if (!type_part[0])
- FIXME("Unhandled resource type %#x.\n", resource_type);
+ type_part = resource_types[resource_type].type_part;
+ if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D && texrect)
+ type_part = "2DRect";
+ if (!type_part[0])
+ FIXME("Unhandled resource type %#x.\n", resource_type);
- if (!lod && grad && !gl_info->supported[EXT_GPU_SHADER4])
- {
- if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
- suffix = "ARB";
- else
- FIXME("Unsupported grad function.\n");
+ if (!lod && grad && !gl_info->supported[EXT_GPU_SHADER4])
+ {
+ if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ suffix = "ARB";
+ else
+ FIXME("Unsupported grad function.\n");
+ }
}
sample_function->name = string_buffer_get(priv->string_buffers);
coord_size = resource_types[resource_type].coord_size;
if (shadow)
++coord_size;
- sample_function->coord_mask = (1 << coord_size) - 1;
+ sample_function->coord_mask = (1u << coord_size) - 1;
+ sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info);
}
static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx,
const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
fixup = priv->cur_ps_args->color_fixup[sampler];
- if (priv->cur_ps_args->np2_fixup & (1 << sampler))
+ if (priv->cur_ps_args->np2_fixup & (1u << sampler))
np2_fixup = TRUE;
}
else
shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], sample_function->data_type);
+ if (sample_function->output_single_component)
+ shader_addline(ins->ctx->buffer, "vec4(");
+
shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ",
sample_function->name->buffer, shader_glsl_get_prefix(version->type), sampler);
else
shader_addline(ins->ctx->buffer, ")");
+ if (sample_function->output_single_component)
+ shader_addline(ins->ctx->buffer, ")");
+
shader_addline(ins->ctx->buffer, "%s);\n", dst_swizzle);
if (!is_identity_fixup(fixup))
}
}
- if (priv->cur_ps_args->np2_fixup & (1 << resource_idx))
+ if (priv->cur_ps_args->np2_fixup & (1u << resource_idx))
sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
shader_glsl_get_sample_function(ins->ctx, resource_idx, sample_flags, &sample_function);
}
sampler_idx = ins->src[1].reg.idx[0].offset;
- if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ if (priv->cur_ps_args->np2_fixup & (1u << sampler_idx))
sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
sampler_idx = ins->src[1].reg.idx[0].offset;
if (ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
- && priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ && priv->cur_ps_args->np2_fixup & (1u << sampler_idx))
sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
char dst_mask[6];
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
- shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
+ shader_addline(buffer, "clamp(ffp_texcoord[%u], 0.0, 1.0)%s);\n",
ins->dst[0].reg.idx[0].offset, dst_mask);
}
else
shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
- if (src_mod == WINED3DSPSM_DZ)
+ if (src_mod == WINED3DSPSM_DZ || src_mod == WINED3DSPSM_DW)
{
unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
struct glsl_src_param div_param;
+ DWORD src_writemask = src_mod == WINED3DSPSM_DZ ? WINED3DSP_WRITEMASK_2 : WINED3DSP_WRITEMASK_3;
- shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &div_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_writemask, &div_param);
- if (mask_size > 1) {
- shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
- } else {
- shader_addline(buffer, "gl_TexCoord[%u]%s / %s);\n", reg, dst_swizzle, div_param.param_str);
- }
+ if (mask_size > 1)
+ shader_addline(buffer, "ffp_texcoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
+ else
+ shader_addline(buffer, "ffp_texcoord[%u]%s / %s);\n", reg, dst_swizzle, div_param.param_str);
}
- else if (src_mod == WINED3DSPSM_DW)
+ else
{
- unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
- struct glsl_src_param div_param;
-
- shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &div_param);
-
- if (mask_size > 1) {
- shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
- } else {
- shader_addline(buffer, "gl_TexCoord[%u]%s / %s);\n", reg, dst_swizzle, div_param.param_str);
- }
- } else {
- shader_addline(buffer, "gl_TexCoord[%u]%s);\n", reg, dst_swizzle);
+ shader_addline(buffer, "ffp_texcoord[%u]%s);\n", reg, dst_swizzle);
}
}
}
{
case 1:
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
- "dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
+ "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
break;
case 2:
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
- "vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
+ "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
break;
case 3:
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
- "vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
+ "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
break;
default:
shader_addline(buffer, "tmp0.z = dot(vec3(T%u), vec3(%s));\n", reg, src0_param.param_str);
/* Construct the eye-ray vector from w coordinates */
- shader_addline(buffer, "tmp1.xyz = normalize(vec3(gl_TexCoord[%u].w, gl_TexCoord[%u].w, gl_TexCoord[%u].w));\n",
+ shader_addline(buffer, "tmp1.xyz = normalize(vec3(ffp_texcoord[%u].w, ffp_texcoord[%u].w, ffp_texcoord[%u].w));\n",
tex_mx->texcoord_w[0], tex_mx->texcoord_w[1], reg);
shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n");
static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer,
const struct wined3d_shader_signature *input_signature,
const struct wined3d_shader_reg_maps *reg_maps,
- const struct ps_compile_args *args)
+ const struct ps_compile_args *args, const struct wined3d_gl_info *gl_info)
{
unsigned int i;
char reg_mask[6];
/* Unused */
- if (!(reg_maps->input_registers & (1 << input->register_idx)))
+ if (!(reg_maps->input_registers & (1u << input->register_idx)))
continue;
semantic_name = input->semantic_name;
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
- if (semantic_idx < 8 && args->vp_mode == pretransformed)
- shader_addline(buffer, "ps_in[%u]%s = gl_TexCoord[%u]%s;\n",
- shader->u.ps.input_reg_map[input->register_idx], reg_mask, semantic_idx, reg_mask);
+ 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 == 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,
+ gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]
+ ? "gl_TexCoord" : "ffp_varying_texcoord", semantic_idx, reg_mask);
else
shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
{
if (!semantic_idx)
- shader_addline(buffer, "ps_in[%u]%s = vec4(gl_Color)%s;\n",
+ shader_addline(buffer, "ps_in[%u]%s = vec4(ffp_varying_diffuse)%s;\n",
shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
else if (semantic_idx == 1)
- shader_addline(buffer, "ps_in[%u]%s = vec4(gl_SecondaryColor)%s;\n",
+ shader_addline(buffer, "ps_in[%u]%s = vec4(ffp_varying_specular)%s;\n",
shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
else
shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
const struct wined3d_shader_reg_maps *reg_maps_out)
{
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
+ BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
unsigned int i, j;
DWORD *set;
DWORD in_idx;
unsigned int in_count = vec4_varyings(3, gl_info);
+ unsigned int max_varyings = legacy_context ? in_count + 2 : in_count;
char reg_mask[6];
struct wined3d_string_buffer *destination = string_buffer_get(&priv->string_buffers);
- set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2));
+ set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * max_varyings);
for (i = 0; i < input_signature->element_count; ++i)
{
const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
- if (!(reg_maps_in->input_registers & (1 << input->register_idx)))
+ if (!(reg_maps_in->input_registers & (1u << input->register_idx)))
continue;
in_idx = map[input->register_idx];
/* Declared, but not read register */
if (in_idx == ~0u)
continue;
- if (in_idx >= (in_count + 2))
+ if (in_idx >= max_varyings)
{
FIXME("More input varyings declared than supported, expect issues.\n");
continue;
const struct wined3d_shader_signature_element *output = &output_signature->elements[j];
DWORD mask;
- if (!(reg_maps_out->output_registers & (1 << output->register_idx))
+ if (!(reg_maps_out->output_registers & (1u << output->register_idx))
|| input->semantic_idx != output->semantic_idx
|| strcmp(input->semantic_name, output->semantic_name)
|| !(mask = input->mask & output->mask))
continue;
if (set[in_idx] == ~0u)
- set[in_idx] = mask;
- else
- set[in_idx] |= mask;
+ set[in_idx] = 0;
+ set[in_idx] |= mask & reg_maps_out->u.output_registers_mask[output->register_idx];
shader_glsl_write_mask_to_str(mask, reg_mask);
shader_addline(buffer, "%s%s = vs_out[%u]%s;\n",
}
}
- for (i = 0; i < in_count + 2; ++i)
+ for (i = 0; i < max_varyings; ++i)
{
unsigned int size;
/* Context activation is done by the caller. */
static GLuint generate_param_reorder_function(struct shader_glsl_priv *priv,
const struct wined3d_shader *vs, const struct wined3d_shader *ps,
- BOOL per_vertex_point_size, const struct wined3d_gl_info *gl_info)
+ BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info)
{
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
GLuint ret = 0;
const char *semantic_name;
UINT semantic_idx;
char reg_mask[6];
+ BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
string_buffer_clear(buffer);
if (ps_major < 3)
{
+ DWORD colors_written_mask[2] = {0};
+ DWORD texcoords_written_mask[MAX_TEXTURES] = {0};
+
+ if (!legacy_context)
+ {
+ declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_diffuse;\n");
+ declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_specular;\n");
+ declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
+ }
+
shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output);
for (i = 0; i < vs->output_signature.element_count; ++i)
const struct wined3d_shader_signature_element *output = &vs->output_signature.elements[i];
DWORD write_mask;
- if (!(vs->reg_maps.output_registers & (1 << output->register_idx)))
+ if (!(vs->reg_maps.output_registers & (1u << output->register_idx)))
continue;
semantic_name = output->semantic_name;
write_mask = output->mask;
shader_glsl_write_mask_to_str(write_mask, reg_mask);
- if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR) && semantic_idx < 2)
{
- if (!semantic_idx)
- shader_addline(buffer, "gl_FrontColor%s = vs_out[%u]%s;\n",
- reg_mask, output->register_idx, reg_mask);
- else if (semantic_idx == 1)
- shader_addline(buffer, "gl_FrontSecondaryColor%s = vs_out[%u]%s;\n",
- reg_mask, output->register_idx, reg_mask);
+ if (legacy_context)
+ shader_addline(buffer, "gl_Front%sColor%s = vs_out[%u]%s;\n",
+ semantic_idx ? "Secondary" : "", reg_mask, output->register_idx, reg_mask);
+ else
+ shader_addline(buffer, "ffp_varying_%s%s = clamp(vs_out[%u]%s, 0.0, 1.0);\n",
+ semantic_idx ? "specular" : "diffuse", reg_mask, output->register_idx, reg_mask);
+
+ colors_written_mask[semantic_idx] = write_mask;
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION) && !semantic_idx)
{
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
{
- if (semantic_idx < 8)
+ if (semantic_idx < MAX_TEXTURES)
{
- if (!(gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) || ps_major > 0)
- write_mask |= WINED3DSP_WRITEMASK_3;
-
- shader_addline(buffer, "gl_TexCoord[%u]%s = vs_out[%u]%s;\n",
+ shader_addline(buffer, "%s[%u]%s = vs_out[%u]%s;\n",
+ legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord",
semantic_idx, reg_mask, output->register_idx, reg_mask);
- if (!(write_mask & WINED3DSP_WRITEMASK_3))
- shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
+ texcoords_written_mask[semantic_idx] = write_mask;
}
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) && per_vertex_point_size)
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
{
- shader_addline(buffer, "gl_FogFragCoord = clamp(vs_out[%u].%c, 0.0, 1.0);\n",
+ shader_addline(buffer, "%s = clamp(vs_out[%u].%c, 0.0, 1.0);\n",
+ legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord",
output->register_idx, reg_mask[1]);
}
}
- shader_addline(buffer, "}\n");
+
+ for (i = 0; i < 2; ++i)
+ {
+ if (colors_written_mask[i] != WINED3DSP_WRITEMASK_ALL)
+ {
+ shader_glsl_write_mask_to_str(~colors_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask);
+ if (!i)
+ shader_addline(buffer, "%s%s = vec4(1.0)%s;\n",
+ legacy_context ? "gl_FrontColor" : "ffp_varying_diffuse",
+ reg_mask, reg_mask);
+ else
+ shader_addline(buffer, "%s%s = vec4(0.0)%s;\n",
+ legacy_context ? "gl_FrontSecondaryColor" : "ffp_varying_specular",
+ reg_mask, reg_mask);
+ }
+ }
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ if (ps && !(ps->reg_maps.texcoord & (1u << i)))
+ continue;
+
+ if (texcoords_written_mask[i] != WINED3DSP_WRITEMASK_ALL)
+ {
+ if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info)
+ && !texcoords_written_mask[i])
+ continue;
+
+ shader_glsl_write_mask_to_str(~texcoords_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask);
+ shader_addline(buffer, "%s[%u]%s = vec4(0.0)%s;\n",
+ legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", i, reg_mask, reg_mask);
+ }
+ }
}
else
{
UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input);
- /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
- shader_addline(buffer, "varying vec4 ps_link[%u];\n", in_count);
+
+ declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", in_count);
shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits->packed_output);
/* First, sort out position and point size. Those are not passed to the pixel shader */
{
const struct wined3d_shader_signature_element *output = &vs->output_signature.elements[i];
- if (!(vs->reg_maps.output_registers & (1 << output->register_idx)))
+ if (!(vs->reg_maps.output_registers & (1u << output->register_idx)))
continue;
semantic_name = output->semantic_name;
/* Then, fix the pixel shader input */
handle_ps3_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature,
&ps->reg_maps, &vs->output_signature, &vs->reg_maps);
-
- shader_addline(buffer, "}\n");
}
+ shader_addline(buffer, "}\n");
+
ret = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
checkGLcall("glCreateShader(GL_VERTEX_SHADER)");
shader_glsl_compile(gl_info, ret, buffer->buffer);
return;
case WINED3D_FFP_PS_FOG_LINEAR:
- shader_addline(buffer, "float fog = (ffp_fog.end - gl_FogFragCoord) * ffp_fog.scale;\n");
+ shader_addline(buffer, "float fog = (ffp_fog.end - ffp_varying_fogcoord) * ffp_fog.scale;\n");
break;
case WINED3D_FFP_PS_FOG_EXP:
- shader_addline(buffer, "float fog = exp(-ffp_fog.density * gl_FogFragCoord);\n");
+ shader_addline(buffer, "float fog = exp(-ffp_fog.density * ffp_varying_fogcoord);\n");
break;
case WINED3D_FFP_PS_FOG_EXP2:
shader_addline(buffer, "float fog = exp(-ffp_fog.density * ffp_fog.density"
- " * gl_FogFragCoord * gl_FogFragCoord);\n");
+ " * ffp_varying_fogcoord * ffp_varying_fogcoord);\n");
break;
default:
const struct wined3d_gl_info *gl_info = context->gl_info;
const DWORD *function = shader->function;
struct shader_glsl_ctx_priv priv_ctx;
+ BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
/* Create the hw GLSL shader object and assign it as the shader->prgId */
GLuint shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
/* Base Declarations */
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
+ if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader)
+ {
+ unsigned int i;
+ WORD map = reg_maps->texcoord;
+
+ if (legacy_context)
+ {
+ if (glsl_is_color_reg_read(shader, 0))
+ shader_addline(buffer, "ffp_varying_diffuse = gl_Color;\n");
+ if (glsl_is_color_reg_read(shader, 1))
+ shader_addline(buffer, "ffp_varying_specular = gl_SecondaryColor;\n");
+ }
+
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (map & 1)
+ {
+ if (args->pointsprite)
+ shader_addline(buffer, "ffp_texcoord[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", i);
+ else if (args->texcoords_initialized & (1u << i))
+ shader_addline(buffer, "ffp_texcoord[%u] = %s[%u];\n", i,
+ legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", i);
+ else
+ shader_addline(buffer, "ffp_texcoord[%u] = vec4(0.0);\n", i);
+ shader_addline(buffer, "vec4 T%u = ffp_texcoord[%u];\n", i, i);
+ }
+ }
+
+ if (legacy_context)
+ shader_addline(buffer, "ffp_varying_fogcoord = gl_FogFragCoord;\n");
+ }
+
/* Pack 3.0 inputs */
if (reg_maps->shader_version.major >= 3)
- shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps, args);
+ shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps, args, gl_info);
/* Base Shader Body */
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
const struct wined3d_gl_info *gl_info = context->gl_info;
const DWORD *function = shader->function;
struct shader_glsl_ctx_priv priv_ctx;
+ BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
/* Create the hw GLSL shader program and assign it as the shader->prgId */
GLuint shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
* the fog frag coord is thrown away. If the fog frag coord is used, but not written by
* the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
*/
- if (args->fog_src == VS_FOG_Z)
- shader_addline(buffer, "gl_FogFragCoord = gl_Position.z;\n");
- else if (!reg_maps->fog)
- shader_addline(buffer, "gl_FogFragCoord = 0.0;\n");
+ if (reg_maps->shader_version.major < 3)
+ {
+ if (args->fog_src == VS_FOG_Z)
+ shader_addline(buffer, "%s = gl_Position.z;\n",
+ legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
+ else if (!reg_maps->fog)
+ shader_addline(buffer, "%s = 0.0;\n",
+ legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
+ }
/* We always store the clipplanes without y inversion */
if (args->clip_enabled)
return FALSE;
if (stored->per_vertex_point_size != new->per_vertex_point_size)
return FALSE;
+ if (stored->flatshading != new->flatshading)
+ return FALSE;
return stored->fog_src == new->fog_src;
}
if (!settings->lighting)
{
- shader_addline(buffer, "gl_FrontColor = ffp_attrib_diffuse;\n");
- shader_addline(buffer, "gl_FrontSecondaryColor = ffp_attrib_specular;\n");
+ shader_addline(buffer, "ffp_varying_diffuse = ffp_attrib_diffuse;\n");
+ shader_addline(buffer, "ffp_varying_specular = ffp_attrib_specular;\n");
return;
}
}
}
- shader_addline(buffer, "gl_FrontColor.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
+ shader_addline(buffer, "ffp_varying_diffuse.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
ambient, diffuse, emissive);
- shader_addline(buffer, "gl_FrontColor.w = %s.w;\n", diffuse);
- shader_addline(buffer, "gl_FrontSecondaryColor = %s * specular;\n", specular);
+ shader_addline(buffer, "ffp_varying_diffuse.w = %s.w;\n", diffuse);
+ shader_addline(buffer, "ffp_varying_specular = %s * specular;\n", specular);
}
/* Context activation is done by the caller. */
-static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_string_buffer *buffer,
- const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info,
- BOOL legacy_lighting)
+static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *priv,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
{
static const struct attrib_info
{
{"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */
{"vec4", "ffp_attrib_specular"}, /* WINED3D_FFP_SPECULAR */
};
+ struct wined3d_string_buffer *buffer = &priv->shader_buffer;
+ BOOL legacy_lighting = priv->legacy_lighting;
GLuint shader_obj;
unsigned int i;
+ BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
+ BOOL output_legacy_fogcoord = legacy_context;
string_buffer_clear(buffer);
shader_addline(buffer, "} ffp_point;\n");
}
+ if (legacy_context)
+ {
+ shader_addline(buffer, "vec4 ffp_varying_diffuse;\n");
+ shader_addline(buffer, "vec4 ffp_varying_specular;\n");
+ shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ shader_addline(buffer, "float ffp_varying_fogcoord;\n");
+ }
+ else
+ {
+ declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n");
+ declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n");
+ declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
+ }
+
shader_addline(buffer, "\nvoid main()\n{\n");
shader_addline(buffer, "float m;\n");
shader_addline(buffer, "vec3 r;\n");
}
shader_glsl_ffp_vertex_lighting(buffer, settings, legacy_lighting);
+ if (legacy_context)
+ {
+ shader_addline(buffer, "gl_FrontColor = ffp_varying_diffuse;\n");
+ shader_addline(buffer, "gl_FrontSecondaryColor = ffp_varying_specular;\n");
+ }
for (i = 0; i < MAX_TEXTURES; ++i)
{
+ BOOL output_legacy_texcoord = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
+
switch (settings->texgen[i] & 0xffff0000)
{
case WINED3DTSS_TCI_PASSTHRU:
- if (settings->texcoords & (1 << i))
- shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u] * ffp_attrib_texcoord%u;\n",
+ if (settings->texcoords & (1u << i))
+ shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ffp_attrib_texcoord%u;\n",
i, i, i);
+ else if (gl_info->limits.glsl_varyings >= wined3d_max_compat_varyings(gl_info))
+ shader_addline(buffer, "ffp_varying_texcoord[%u] = vec4(0.0);\n", i);
+ else
+ output_legacy_texcoord = FALSE;
break;
case WINED3DTSS_TCI_CAMERASPACENORMAL:
- shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u] * vec4(normal, 1.0);\n", i, i);
+ shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * vec4(normal, 1.0);\n", i, i);
break;
case WINED3DTSS_TCI_CAMERASPACEPOSITION:
- shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u] * ec_pos;\n", i, i);
+ shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ec_pos;\n", i, i);
break;
case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
- shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u]"
+ shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]"
" * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i);
break;
case WINED3DTSS_TCI_SPHEREMAP:
shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n");
shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n");
- shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u]"
+ shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]"
" * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i);
break;
ERR("Unhandled texgen %#x.\n", settings->texgen[i]);
break;
}
+ if (output_legacy_texcoord)
+ shader_addline(buffer, "gl_TexCoord[%u] = ffp_varying_texcoord[%u];\n", i, i);
}
switch (settings->fog_mode)
{
case WINED3D_FFP_VS_FOG_OFF:
+ output_legacy_fogcoord = FALSE;
break;
case WINED3D_FFP_VS_FOG_FOGCOORD:
- shader_addline(buffer, "gl_FogFragCoord = ffp_attrib_specular.w * 255.0;\n");
+ shader_addline(buffer, "ffp_varying_fogcoord = ffp_attrib_specular.w * 255.0;\n");
break;
case WINED3D_FFP_VS_FOG_RANGE:
- shader_addline(buffer, "gl_FogFragCoord = length(ec_pos.xyz);\n");
+ shader_addline(buffer, "ffp_varying_fogcoord = length(ec_pos.xyz);\n");
break;
case WINED3D_FFP_VS_FOG_DEPTH:
if (settings->ortho_fog)
/* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */
- shader_addline(buffer, "gl_FogFragCoord = gl_Position.z * 0.5 + 0.5;\n");
+ shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z * 0.5 + 0.5;\n");
else if (settings->transformed)
- shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n");
+ shader_addline(buffer, "ffp_varying_fogcoord = ec_pos.z;\n");
else
- shader_addline(buffer, "gl_FogFragCoord = abs(ec_pos.z);\n");
+ shader_addline(buffer, "ffp_varying_fogcoord = abs(ec_pos.z);\n");
break;
default:
ERR("Unhandled fog mode %#x.\n", settings->fog_mode);
break;
}
+ if (output_legacy_fogcoord)
+ shader_addline(buffer, "gl_FogFragCoord = ffp_varying_fogcoord;\n");
if (settings->point_size)
{
switch (arg & WINED3DTA_SELECTMASK)
{
case WINED3DTA_DIFFUSE:
- ret = "gl_Color";
+ ret = "ffp_varying_diffuse";
break;
case WINED3DTA_CURRENT:
if (!stage)
- ret = "gl_Color";
+ ret = "ffp_varying_diffuse";
else
ret = "ret";
break;
break;
case WINED3DTA_SPECULAR:
- ret = "gl_SecondaryColor";
+ ret = "ffp_varying_specular";
break;
case WINED3DTA_TEMP:
{
case WINED3D_TOP_DISABLE:
if (!stage)
- shader_addline(buffer, "%s%s = gl_Color%s;\n", dstreg, dstmask, dstmask);
+ shader_addline(buffer, "%s%s = ffp_varying_diffuse%s;\n", dstreg, dstmask, dstmask);
break;
case WINED3D_TOP_SELECT_ARG1:
DWORD arg0, arg1, arg2;
unsigned int stage;
struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers);
+ BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
string_buffer_clear(buffer);
if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE
|| (stage == 0 && settings->color_key_enabled))
- tex_map |= 1 << stage;
+ tex_map |= 1u << stage;
if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR)
tfactor_used = TRUE;
if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
if (settings->op[stage].dst == tempreg)
tempreg_used = TRUE;
if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
- tss_const_map |= 1 << stage;
+ tss_const_map |= 1u << stage;
switch (settings->op[stage].cop)
{
case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
- lum_map |= 1 << stage;
+ lum_map |= 1u << stage;
/* fall through */
case WINED3D_TOP_BUMPENVMAP:
- bump_map |= 1 << stage;
+ bump_map |= 1u << stage;
/* fall through */
case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
- tex_map |= 1 << stage;
+ tex_map |= 1u << stage;
break;
case WINED3D_TOP_BLEND_FACTOR_ALPHA:
arg2 = settings->op[stage].aarg2 & WINED3DTA_SELECTMASK;
if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE)
- tex_map |= 1 << stage;
+ tex_map |= 1u << stage;
if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR)
tfactor_used = TRUE;
if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
tempreg_used = TRUE;
if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
- tss_const_map |= 1 << stage;
+ tss_const_map |= 1u << stage;
}
lowest_disabled_stage = stage;
for (stage = 0; stage < MAX_TEXTURES; ++stage)
{
- if (tss_const_map & (1 << stage))
+ if (tss_const_map & (1u << stage))
shader_addline(buffer, "uniform vec4 tss_const%u;\n", stage);
- if (!(tex_map & (1 << stage)))
+ if (!(tex_map & (1u << stage)))
continue;
switch (settings->op[stage].tex_type)
shader_addline(buffer, "vec4 tex%u;\n", stage);
- if (!(bump_map & (1 << stage)))
+ if (!(bump_map & (1u << stage)))
continue;
shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", stage);
- if (!(lum_map & (1 << stage)))
+ if (!(lum_map & (1u << stage)))
continue;
shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", stage);
shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", stage);
if (tfactor_used)
shader_addline(buffer, "uniform vec4 tex_factor;\n");
if (settings->color_key_enabled)
- shader_addline(buffer, "uniform vec4 color_key;\n");
+ shader_addline(buffer, "uniform vec4 color_key[2];\n");
shader_addline(buffer, "uniform vec4 specular_enable;\n");
if (settings->sRGB_write)
shader_addline(buffer, " float scale;\n");
shader_addline(buffer, "} ffp_fog;\n");
+ if (legacy_context)
+ {
+ shader_addline(buffer, "vec4 ffp_varying_diffuse;\n");
+ shader_addline(buffer, "vec4 ffp_varying_specular;\n");
+ shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
+ shader_addline(buffer, "float ffp_varying_fogcoord;\n");
+ }
+ else
+ {
+ declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n");
+ declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n");
+ declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
+ shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
+ declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
+ }
+
shader_addline(buffer, "void main()\n{\n");
+ if (legacy_context)
+ {
+ shader_addline(buffer, "ffp_varying_diffuse = gl_Color;\n");
+ shader_addline(buffer, "ffp_varying_specular = gl_SecondaryColor;\n");
+ }
+
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ if (tex_map & (1u << stage))
+ {
+ if (settings->pointsprite)
+ shader_addline(buffer, "ffp_texcoord[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", stage);
+ else if (settings->texcoords_initialized & (1u << stage))
+ shader_addline(buffer, "ffp_texcoord[%u] = %s[%u];\n",
+ stage, legacy_context ? "gl_TexCoord" : "ffp_varying_texcoord", stage);
+ else
+ shader_addline(buffer, "ffp_texcoord[%u] = vec4(0.0);\n", stage);
+ }
+ }
+
+ if (legacy_context && settings->fog != WINED3D_FFP_PS_FOG_OFF)
+ shader_addline(buffer, "ffp_varying_fogcoord = gl_FogFragCoord;\n");
+
if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
- shader_addline(buffer, "if (any(lessThan(gl_TexCoord[7], vec4(0.0)))) discard;\n");
+ shader_addline(buffer, "if (any(lessThan(ffp_texcoord[7], vec4(0.0)))) discard;\n");
/* Generate texture sampling instructions) */
for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage)
const char *texture_function, *coord_mask;
BOOL proj;
- if (!(tex_map & (1 << stage)))
+ if (!(tex_map & (1u << stage)))
continue;
if (settings->op[stage].projected == proj_none)
proj = TRUE;
}
+ if (settings->op[stage].tex_type == WINED3D_GL_RES_TYPE_TEX_CUBE)
+ proj = FALSE;
+
switch (settings->op[stage].tex_type)
{
case WINED3D_GL_RES_TYPE_TEX_1D:
coord_mask = "xyzw";
break;
}
+ if (!needs_legacy_glsl_syntax(gl_info))
+ texture_function = proj ? "textureProj" : "texture";
if (stage > 0
&& (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
{
if (settings->op[stage].projected == proj_count4)
{
- shader_addline(buffer, "ret.xy = (ret.xy * gl_TexCoord[%u].w) + gl_TexCoord[%u].xy;\n",
+ shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n",
stage, stage);
- shader_addline(buffer, "ret.zw = gl_TexCoord[%u].ww;\n", stage);
+ shader_addline(buffer, "ret.zw = ffp_texcoord[%u].ww;\n", stage);
}
else
{
- shader_addline(buffer, "ret.xy = (ret.xy * gl_TexCoord[%u].z) + gl_TexCoord[%u].xy;\n",
+ shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].z) + ffp_texcoord[%u].xy;\n",
stage, stage);
- shader_addline(buffer, "ret.zw = gl_TexCoord[%u].zz;\n", stage);
+ shader_addline(buffer, "ret.zw = ffp_texcoord[%u].zz;\n", stage);
}
}
else
{
- shader_addline(buffer, "ret = gl_TexCoord[%u] + ret.xyxy;\n", stage);
+ shader_addline(buffer, "ret = ffp_texcoord[%u] + ret.xyxy;\n", stage);
}
shader_addline(buffer, "tex%u = %s(ps_sampler%u, ret.%s);\n",
}
else if (settings->op[stage].projected == proj_count3)
{
- shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].xyz);\n",
+ shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n",
stage, texture_function, stage, stage);
}
else
{
- shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].%s);\n",
+ shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].%s);\n",
stage, texture_function, stage, stage, coord_mask);
}
}
if (settings->color_key_enabled)
- shader_addline(buffer, "if (all(equal(tex0, color_key))) discard;\n");
+ {
+ shader_addline(buffer, "if (all(greaterThanEqual(tex0, color_key[0])) && all(lessThan(tex0, color_key[1])))\n");
+ shader_addline(buffer, " discard;\n");
+ }
/* Generate the main shader */
for (stage = 0; stage < MAX_TEXTURES; ++stage)
if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
{
if (!stage)
- final_combiner_src = "gl_Color";
+ final_combiner_src = "ffp_varying_diffuse";
break;
}
settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2);
if (!stage)
- shader_addline(buffer, "ret.w = gl_Color.w;\n");
+ shader_addline(buffer, "ret.w = ffp_varying_diffuse.w;\n");
}
else if (op_equal)
{
}
}
- shader_addline(buffer, "gl_FragData[0] = gl_SecondaryColor * specular_enable + %s;\n", final_combiner_src);
+ shader_addline(buffer, "gl_FragData[0] = ffp_varying_specular * specular_enable + %s;\n", final_combiner_src);
if (settings->sRGB_write)
shader_glsl_generate_srgb_write_correction(buffer);
return NULL;
shader->desc.settings = *settings;
- shader->id = shader_glsl_generate_ffp_vertex_shader(&priv->shader_buffer, settings, gl_info, priv->legacy_lighting);
+ shader->id = shader_glsl_generate_ffp_vertex_shader(priv, settings, gl_info);
list_init(&shader->linked_programs);
if (wine_rb_put(&priv->ffp_vertex_shaders, &shader->desc.settings, &shader->desc.entry) == -1)
ERR("Failed to insert ffp vertex shader.\n");
struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
const struct ps_np2fixup_info *np2fixup_info = NULL;
struct glsl_shader_prog_link *entry = NULL;
struct wined3d_shader *vshader = NULL;
WORD attribs_map;
struct wined3d_string_buffer *tmp_name;
- if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX)) && ctx_data->glsl_program)
+ if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_VERTEX)) && ctx_data->glsl_program)
{
vs_id = ctx_data->glsl_program->vs.id;
vs_list = &ctx_data->glsl_program->vs.shader_entry;
vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
- if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_GEOMETRY))
+ if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY))
&& ctx_data->glsl_program->gs.id)
gs_id = ctx_data->glsl_program->gs.id;
else if (gshader)
else if (use_vs(state))
{
struct vs_compile_args vs_compile_args;
+
vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
- find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args);
+ find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, d3d_info);
vs_id = find_glsl_vshader(context, &priv->shader_buffer, &priv->string_buffers, vshader, &vs_compile_args);
vs_list = &vshader->linked_programs;
struct glsl_ffp_vertex_shader *ffp_shader;
struct wined3d_ffp_vs_settings settings;
- wined3d_ffp_get_vs_settings(state, &context->stream_info, &settings);
+ wined3d_ffp_get_vs_settings(context, state, &settings);
ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings);
vs_id = ffp_shader->id;
vs_list = &ffp_shader->linked_programs;
}
- if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program)
+ if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program)
{
ps_id = ctx_data->glsl_program->ps.id;
ps_list = &ctx_data->glsl_program->ps.shader_entry;
{
struct ps_compile_args ps_compile_args;
pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
- find_ps_compile_args(state, pshader, context->stream_info.position_transformed, &ps_compile_args, gl_info);
+ find_ps_compile_args(state, pshader, context->stream_info.position_transformed, &ps_compile_args, context);
ps_id = find_glsl_pshader(context, &priv->shader_buffer, &priv->string_buffers,
pshader, &ps_compile_args, &np2fixup_info);
ps_list = &pshader->linked_programs;
{
attribs_map = vshader->reg_maps.input_registers;
reorder_shader_id = generate_param_reorder_function(priv, vshader, pshader,
- state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size, gl_info);
+ state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size,
+ d3d_info->emulated_flatshading
+ && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info);
TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id);
GL_EXTCALL(glAttachShader(program_id, reorder_shader_id));
checkGLcall("glAttachShader");
}
else
{
- attribs_map = (1 << WINED3D_FFP_ATTRIBS_COUNT) - 1;
+ attribs_map = (1u << WINED3D_FFP_ATTRIBS_COUNT) - 1;
}
/* Bind vertex attributes to a corresponding index number to match
GL_EXTCALL(glUseProgram(program_id));
checkGLcall("glUseProgram");
- /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure
- * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If
- * a pshader with fixed function pipeline is used there are no vertex samplers, and if a
- * vertex shader with fixed function pixel processing is used we make sure that the card
- * supports enough samplers to allow the max number of vertex samplers with all possible
- * fixed function fragment processing setups. So once the program is linked these samplers
- * won't change. */
+ /* Texture unit mapping is set up to be the same each time the shader
+ * program is used so we can hardcode the sampler uniform values. */
shader_glsl_load_samplers(gl_info, priv, context->tex_unit_map, program_id);
entry->constant_update_mask = 0;
struct glsl_context_data *ctx_data = context->shader_backend_data;
ctx_data->glsl_program = NULL;
- context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
- | (1 << WINED3D_SHADER_TYPE_VERTEX)
- | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
+ context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
+ | (1u << WINED3D_SHADER_TYPE_VERTEX)
+ | (1u << WINED3D_SHADER_TYPE_GEOMETRY);
}
/* Context activation is done by the caller. */
{
UINT shader_model;
- if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING]
- && gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)
- && gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && gl_info->supported[ARB_DRAW_INSTANCED]
- && gl_info->supported[ARB_TEXTURE_RG] && gl_info->supported[ARB_SAMPLER_OBJECTS])
+ if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) && gl_info->supported[WINED3D_GL_VERSION_3_2]
+ && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_SAMPLER_OBJECTS])
shader_model = 4;
/* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
* texldd and texldl instructions. */
caps->vs_uniform_count = gl_info->limits.glsl_vs_float_constants;
caps->ps_uniform_count = gl_info->limits.glsl_ps_float_constants;
+ caps->varying_count = gl_info->limits.glsl_varyings;
/* FIXME: The following line is card dependent. -8.0 to 8.0 is the
* Direct3D minimum requirement.
static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
{
caps->xyzrhw = TRUE;
+ caps->emulated_flatshading = !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
caps->ffp_generic_attributes = TRUE;
caps->max_active_lights = MAX_ACTIVE_LIGHTS;
caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
caps->raster_caps = WINED3DPRASTERCAPS_FOGRANGE;
}
+static DWORD glsl_vertex_pipe_vp_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ return GL_EXT_EMUL_ARB_MULTITEXTURE;
+ return 0;
+}
+
static void *glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
struct shader_glsl_priv *priv;
wine_rb_destroy(&priv->ffp_vertex_shaders, shader_glsl_free_ffp_vertex_shader, &ctx);
}
+static void glsl_vertex_pipe_nop(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) {}
+
static void glsl_vertex_pipe_shader(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
}
static void glsl_vertex_pipe_vdecl(struct wined3d_context *context,
* the draw uses the fixed function vertex pipeline regardless of any
* vertex shader set by the application. */
if (transformed != wasrhw)
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
if (!use_vs(state))
{
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX;
- /* Because of settings->texcoords, we have to always regenerate the
- * vertex shader on a vdecl change.
- * TODO: Just always output all the texcoords when there are enough
- * varyings available to drop the dependency. */
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ /* Because of settings->texcoords, we have to regenerate the vertex
+ * shader on a vdecl change if there aren't enough varyings to just
+ * always output all the texture coordinates. */
+ if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info))
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
if (use_ps(state)
&& state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.major == 1
&& state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3)
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
else
{
static void glsl_vertex_pipe_vs(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
/* Different vertex shaders potentially require a different vertex attributes setup. */
if (!isStateDirty(context, STATE_VDECL))
context_apply_state(context, state, STATE_VDECL);
/* Table fog behavior depends on the projection matrix. */
if (state->render_states[WINED3D_RS_FOGENABLE]
&& state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PROJ;
}
return;
if ((np2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
- || context->lastWasPow2Texture & (1 << sampler))
+ || context->lastWasPow2Texture & (1u << sampler))
{
if (np2)
- context->lastWasPow2Texture |= 1 << sampler;
+ context->lastWasPow2Texture |= 1u << sampler;
else
- context->lastWasPow2Texture &= ~(1 << sampler);
+ context->lastWasPow2Texture &= ~(1u << sampler);
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX;
}
context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE;
}
+static void glsl_vertex_pipe_shademode(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+}
+
static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
{
{STATE_VDECL, {STATE_VDECL, glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE },
{STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
{STATE_SAMPLER(7), {STATE_SAMPLER(7), glsl_vertex_pipe_texmatrix_np2}, WINED3D_GL_EXT_NONE },
{STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_nop }, WINED3D_GL_LEGACY_CONTEXT },
+ {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_vertex_pipe_shademode}, WINED3D_GL_EXT_NONE },
{0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE },
};
/* TODO:
- * - This currently depends on GL fixed function functions to set things
- * like light parameters. Ideally we'd use regular uniforms for that.
- * - In part because of the previous point, much of this is modelled after
- * GL fixed function, and has much of the same limitations. For example,
- * D3D spot lights are slightly different from GL spot lights.
- * - We can now implement drawing transformed vertices using the GLSL pipe,
- * instead of using the immediate mode fallback.
- * - Similarly, we don't need the fallback for certain combinations of
- * material sources anymore.
- * - Implement vertex tweening.
- * - Handle WINED3D_TSS_TEXCOORD_INDEX in the shader, instead of duplicating
- * attribute arrays in load_tex_coords().
- * - Per-vertex point sizes. */
+ * - Implement vertex tweening. */
const struct wined3d_vertex_pipe_ops glsl_vertex_pipe =
{
glsl_vertex_pipe_vp_enable,
glsl_vertex_pipe_vp_get_caps,
+ glsl_vertex_pipe_vp_get_emul_mask,
glsl_vertex_pipe_vp_alloc,
glsl_vertex_pipe_vp_free,
glsl_vertex_pipe_vp_states,
caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8);
}
+static DWORD glsl_fragment_pipe_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ return GL_EXT_EMUL_ARB_MULTITEXTURE;
+ return 0;
+}
+
static void *glsl_fragment_pipe_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
struct shader_glsl_priv *priv;
{
context->last_was_pshader = use_ps(state);
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
static void glsl_fragment_pipe_fogparams(struct wined3d_context *context,
DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
if (!state->render_states[WINED3D_RS_FOGENABLE])
return;
static void glsl_fragment_pipe_vdecl(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
+ /* Because of settings->texcoords_initialized and args->texcoords_initialized. */
+ if (context->gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(context->gl_info))
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
+
if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE)))
glsl_fragment_pipe_fog(context, state, state_id);
}
+static void glsl_fragment_pipe_vs(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ /* Because of settings->texcoords_initialized and args->texcoords_initialized. */
+ if (context->gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(context->gl_info))
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
+}
+
static void glsl_fragment_pipe_tex_transform(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *context,
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_COLOR_KEY;
}
+static void glsl_fragment_pipe_shademode(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+}
+
static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] =
{
{STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE },
+ {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), glsl_fragment_pipe_vs }, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
{STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
{STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_LEGACY_CONTEXT},
+ {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GL_EXT_NONE },
{0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE },
};
{
glsl_fragment_pipe_enable,
glsl_fragment_pipe_get_caps,
+ glsl_fragment_pipe_get_emul_mask,
glsl_fragment_pipe_alloc,
glsl_fragment_pipe_free,
glsl_fragment_pipe_alloc_context_data,
|| state->texture_states[stage - 1][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP))
{
bumpmap = TRUE;
- context->texShaderBumpMap |= (1 << stage);
- } else {
- context->texShaderBumpMap &= ~(1 << stage);
+ context->texShaderBumpMap |= (1u << stage);
+ }
+ else
+ {
+ context->texShaderBumpMap &= ~(1u << stage);
}
if (state->textures[stage])
static void nvrc_colorop(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);
- BOOL tex_used = context->fixed_function_usage_map & (1 << stage);
+ BOOL tex_used = context->fixed_function_usage_map & (1u << stage);
DWORD mapped_stage = context->tex_unit_map[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
{
BOOL usesBump = (state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP_LUMINANCE
|| state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP);
- BOOL usedBump = !!(context->texShaderBumpMap & 1 << (stage + 1));
+ BOOL usedBump = !!(context->texShaderBumpMap & 1u << (stage + 1));
if (usesBump != usedBump)
{
context_active_texture(context, gl_info, mapped_stage + 1);
caps->MaxSimultaneousTextures = gl_info->limits.textures;
}
+static DWORD nvrc_fragment_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return GL_EXT_EMUL_ARB_MULTITEXTURE | GL_EXT_EMUL_EXT_FOG_COORD;
+}
+
static void *nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
{
return shader_priv;
{ STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), nvts_texdim }, NV_TEXTURE_SHADER2 },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), nvts_texdim }, NV_TEXTURE_SHADER2 },
const struct fragment_pipeline nvts_fragment_pipeline = {
nvts_enable,
nvrc_fragment_get_caps,
+ nvrc_fragment_get_emul_mask,
nvrc_fragment_alloc,
nvrc_fragment_free,
nvrc_context_alloc,
const struct fragment_pipeline nvrc_fragment_pipeline = {
nvrc_enable,
nvrc_fragment_get_caps,
+ nvrc_fragment_get_emul_mask,
nvrc_fragment_alloc,
nvrc_fragment_free,
nvrc_context_alloc,
struct wined3d_palette *object;
HRESULT hr;
- TRACE("device %p, flags %#x, entries %p, palette %p.\n",
- device, flags, entries, palette);
+ TRACE("device %p, flags %#x, entry_count %u, entries %p, palette %p.\n",
+ device, flags, entry_count, entries, palette);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
const struct wined3d_gl_info *gl_info;
enum wined3d_event_query_result ret;
- TRACE("(%p)\n", query);
+ TRACE("query %p, device %p.\n", query, device);
if (!query->context)
{
void *data, DWORD size, DWORD flags)
{
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
+ if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
+ {
+ static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE};
+
+ if (query->state == QUERY_BUILDING)
+ {
+ TRACE("Query is building, returning S_FALSE.\n");
+ return S_FALSE;
#else /* STAGING_CSMT */
query->state = QUERY_SIGNALLED;
{
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
-#endif /* STAGING_CSMT */
if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
{
static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE};
{
TRACE("Query is building, returning S_FALSE.\n");
return S_FALSE;
+#endif /* STAGING_CSMT */
}
fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data));
struct wined3d_query *object;
HRESULT hr;
- TRACE("device %p, type %#x, query %p.\n", device, type, query);
+ TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
desc->size = resource->size;
}
+HRESULT CDECL wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %p, flags %#x.\n",
+ resource, sub_resource_idx, map_desc, box, flags);
+
+ return resource->resource_ops->resource_sub_resource_map(resource, sub_resource_idx, map_desc, box, flags);
+}
+
+HRESULT CDECL wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
+{
+ TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
+
+ return resource->resource_ops->resource_sub_resource_unmap(resource, sub_resource_idx);
+}
+
BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource)
{
void **p;
else
resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB;
}
+#if defined(STAGING_CSMT)
-void CDECL wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch,
+void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch,
UINT *slice_pitch)
{
unsigned int alignment;
TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch);
}
-#if defined(STAGING_CSMT)
void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location)
{
struct wined3d_device *device = resource->device;
BYTE *base_memory;
const struct wined3d_format *format = resource->format;
- const unsigned int fmt_flags = resource->format_flags;
+ const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D];
TRACE("resource %p, map_desc %p, box %p, flags %#x.\n",
resource, map_desc, box, flags);
return refcount;
}
+#if defined(STAGING_CSMT)
+void wined3d_sampler_destroy(struct wined3d_sampler *sampler)
+{
+ struct wined3d_context *context = context_acquire(sampler->device, NULL);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
+ context_release(context);
+
+ HeapFree(GetProcessHeap(), 0, sampler);
+}
+
+ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
+{
+ ULONG refcount = InterlockedDecrement(&sampler->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
+
+ if (!refcount)
+ {
+ struct wined3d_device *device = sampler->device;
+ wined3d_cs_emit_sampler_destroy(device->cs, sampler);
+#else /* STAGING_CSMT */
ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
{
ULONG refcount = InterlockedDecrement(&sampler->refcount);
context_release(context);
HeapFree(GetProcessHeap(), 0, sampler);
+#endif /* STAGING_CSMT */
}
return refcount;
DWORD idx, shift;
idx = bit >> 5;
shift = bit & 0x1f;
- bitmap[idx] |= (1 << shift);
+ bitmap[idx] |= (1u << shift);
}
static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
{
case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
- reg_maps->texcoord |= 1 << reg->idx[0].offset;
+ reg_maps->texcoord |= 1u << reg->idx[0].offset;
else
- reg_maps->address |= 1 << reg->idx[0].offset;
+ reg_maps->address |= 1u << reg->idx[0].offset;
break;
case WINED3DSPR_TEMP:
- reg_maps->temporary |= 1 << reg->idx[0].offset;
+ reg_maps->temporary |= 1u << reg->idx[0].offset;
break;
case WINED3DSPR_INPUT:
}
}
else
- reg_maps->input_registers |= 1 << reg->idx[0].offset;
+ reg_maps->input_registers |= 1u << reg->idx[0].offset;
break;
case WINED3DSPR_RASTOUT:
}
else
{
- reg_maps->integer_constants |= (1 << reg->idx[0].offset);
+ reg_maps->integer_constants |= (1u << reg->idx[0].offset);
}
break;
}
else
{
- reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
+ reg_maps->boolean_constants |= (1u << reg->idx[0].offset);
}
break;
case WINED3DSPR_COLOROUT:
- reg_maps->rt_mask |= (1 << reg->idx[0].offset);
+ reg_maps->rt_mask |= (1u << reg->idx[0].offset);
break;
default:
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL && shader_version.major == 3
&& semantic->usage == WINED3D_DECL_USAGE_POSITION && !semantic->usage_idx)
return WINED3DERR_INVALIDCALL;
- reg_maps->input_registers |= 1 << reg_idx;
+ reg_maps->input_registers |= 1u << reg_idx;
shader_signature_from_semantic(&input_signature_elements[reg_idx], semantic);
break;
ERR("Invalid output register index %u.\n", reg_idx);
break;
}
- reg_maps->output_registers |= 1 << reg_idx;
+ reg_maps->output_registers |= 1u << reg_idx;
shader_signature_from_semantic(&output_signature_elements[reg_idx], semantic);
if (semantic->usage == WINED3D_DECL_USAGE_FOG)
reg_maps->fog = 1;
memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
list_add_head(&shader->constantsI, &lconst->entry);
- reg_maps->local_int_consts |= (1 << lconst->idx);
+ reg_maps->local_int_consts |= (1u << lconst->idx);
}
else if (ins.handler_idx == WINED3DSIH_DEFB)
{
memcpy(lconst->value, ins.src[0].reg.immconst_data, sizeof(DWORD));
list_add_head(&shader->constantsB, &lconst->entry);
- reg_maps->local_bool_consts |= (1 << lconst->idx);
+ reg_maps->local_bool_consts |= (1u << lconst->idx);
}
/* For subroutine prototypes. */
else if (ins.handler_idx == WINED3DSIH_LABEL)
{
- reg_maps->labels |= 1 << ins.src[0].reg.idx[0].offset;
+ reg_maps->labels |= 1u << ins.src[0].reg.idx[0].offset;
}
/* Set texture, address, temporary registers. */
else
shader_version.type, constf_size))
return WINED3DERR_INVALIDCALL;
- /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
- * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
- * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
- if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX && shader_version.major < 3)
+ if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX)
{
UINT idx = ins.dst[i].reg.idx[0].offset;
switch (ins.dst[i].reg.type)
{
case WINED3DSPR_RASTOUT:
+ if (shader_version.major >= 3)
+ break;
switch (idx)
{
case 0: /* oPos */
- reg_maps->output_registers |= 1 << 10;
+ reg_maps->output_registers |= 1u << 10;
shader_signature_from_usage(&output_signature_elements[10],
WINED3D_DECL_USAGE_POSITION, 0, 10, WINED3DSP_WRITEMASK_ALL);
break;
case 1: /* oFog */
- reg_maps->output_registers |= 1 << 11;
+ reg_maps->output_registers |= 1u << 11;
shader_signature_from_usage(&output_signature_elements[11],
WINED3D_DECL_USAGE_FOG, 0, 11, WINED3DSP_WRITEMASK_0);
break;
case 2: /* oPts */
- reg_maps->output_registers |= 1 << 11;
+ reg_maps->output_registers |= 1u << 11;
shader_signature_from_usage(&output_signature_elements[11],
WINED3D_DECL_USAGE_PSIZE, 0, 11, WINED3DSP_WRITEMASK_1);
break;
break;
case WINED3DSPR_ATTROUT:
+ if (shader_version.major >= 3)
+ break;
if (idx < 2)
{
idx += 8;
- if (reg_maps->output_registers & (1 << idx))
+ if (reg_maps->output_registers & (1u << idx))
{
output_signature_elements[idx].mask |= ins.dst[i].write_mask;
}
else
{
- reg_maps->output_registers |= 1 << idx;
+ reg_maps->output_registers |= 1u << idx;
shader_signature_from_usage(&output_signature_elements[idx],
WINED3D_DECL_USAGE_COLOR, idx - 8, idx, ins.dst[i].write_mask);
}
break;
case WINED3DSPR_TEXCRDOUT:
-
- reg_maps->texcoord_mask[idx] |= ins.dst[i].write_mask;
- if (reg_maps->output_registers & (1 << idx))
+ if (shader_version.major >= 3)
+ {
+ reg_maps->u.output_registers_mask[idx] |= ins.dst[i].write_mask;
+ break;
+ }
+ reg_maps->u.texcoord_mask[idx] |= ins.dst[i].write_mask;
+ if (reg_maps->output_registers & (1u << idx))
{
output_signature_elements[idx].mask |= ins.dst[i].write_mask;
}
else
{
- reg_maps->output_registers |= 1 << idx;
+ reg_maps->output_registers |= 1u << idx;
shader_signature_from_usage(&output_signature_elements[idx],
WINED3D_DECL_USAGE_TEXCOORD, idx, idx, ins.dst[i].write_mask);
}
if (ins.handler_idx == WINED3DSIH_TEXBEM
|| ins.handler_idx == WINED3DSIH_TEXBEML)
{
- reg_maps->bumpmat |= 1 << reg_idx;
+ reg_maps->bumpmat |= 1u << reg_idx;
if (ins.handler_idx == WINED3DSIH_TEXBEML)
{
- reg_maps->luminanceparams |= 1 << reg_idx;
+ reg_maps->luminanceparams |= 1u << reg_idx;
}
}
}
else if (ins.handler_idx == WINED3DSIH_BEM)
{
- reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
+ reg_maps->bumpmat |= 1u << ins.dst[i].reg.idx[0].offset;
}
}
/* PS before 2.0 don't have explicit color outputs. Instead the value of
* R0 is written to the render target. */
if (shader_version.major < 2 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
- reg_maps->rt_mask |= (1 << 0);
+ reg_maps->rt_mask |= (1u << 0);
shader->functionLength = ((const char *)ptr - (const char *)byte_code);
{
for (i = 0; i < input_signature->element_count; ++i)
{
- reg_maps->input_registers |= 1 << input_signature->elements[i].register_idx;
+ reg_maps->input_registers |= 1u << input_signature->elements[i].register_idx;
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL
&& input_signature->elements[i].sysval_semantic == WINED3D_SV_POSITION)
reg_maps->vpos = 1;
e = input_signature->elements;
for (i = 0; i < ARRAY_SIZE(input_signature_elements); ++i)
{
- if (!(reg_maps->input_registers & (1 << i)))
+ if (!(reg_maps->input_registers & (1u << i)))
continue;
input_signature_elements[i].register_idx = i;
*e++ = input_signature_elements[i];
{
for (i = 0; i < output_signature->element_count; ++i)
{
- reg_maps->output_registers |= 1 << output_signature->elements[i].register_idx;
+ reg_maps->output_registers |= 1u << output_signature->elements[i].register_idx;
}
}
else if (reg_maps->output_registers)
e = output_signature->elements;
for (i = 0; i < ARRAY_SIZE(output_signature_elements); ++i)
{
- if (!(reg_maps->output_registers & (1 << i)))
+ if (!(reg_maps->output_registers & (1u << i)))
continue;
*e++ = output_signature_elements[i];
}
unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max)
{
- DWORD map = 1 << max;
+ DWORD map = 1u << max;
map |= map - 1;
map &= reg_maps->shader_version.major < 3 ? ~reg_maps->texcoord : ~reg_maps->input_registers;
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
- TRACE("_volume");
+ TRACE("_3d");
break;
case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
priv->vertex_pipe->vp_enable(gl_info, FALSE);
priv->fragment_pipe->enable_extension(gl_info, FALSE);
- context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
- | (1 << WINED3D_SHADER_TYPE_VERTEX)
- | (1 << WINED3D_SHADER_TYPE_GEOMETRY);
+ context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
+ | (1u << WINED3D_SHADER_TYPE_VERTEX)
+ | (1u << WINED3D_SHADER_TYPE_GEOMETRY);
}
static HRESULT shader_none_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
caps->vs_uniform_count = 0;
caps->ps_uniform_count = 0;
caps->ps_1x_max_value = 0.0f;
+ caps->varying_count = 0;
caps->wined3d_caps = 0;
}
unsigned int backend_version;
const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
- TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u.\n",
- shader, byte_code, output_signature, float_const_count);
+ TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u, type %#x, max_version %u.\n",
+ shader, byte_code, output_signature, float_const_count, type, max_version);
list_init(&shader->constantsF);
list_init(&shader->constantsB);
}
void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
- WORD swizzle_map, struct vs_compile_args *args)
+ WORD swizzle_map, struct vs_compile_args *args, const struct wined3d_d3d_info *d3d_info)
{
args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE]
== WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
args->point_size = state->gl_primitive_type == GL_POINTS;
args->per_vertex_point_size = shader->reg_maps.point_size;
args->swizzle_map = swizzle_map;
+ if (d3d_info->emulated_flatshading)
+ args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
+ else
+ args->flatshading = FALSE;
}
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
{
const struct wined3d_shader_signature_element *input = &shader->input_signature.elements[i];
- if (!(reg_maps->input_registers & (1 << input->register_idx)) || !input->semantic_name)
+ if (!(reg_maps->input_registers & (1u << input->register_idx)) || !input->semantic_name)
continue;
shader->u.vs.attributes[input->register_idx].usage =
}
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
- BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_gl_info *gl_info)
+ BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
const struct wined3d_texture *texture;
UINT i;
args->color_fixup[i] = texture->resource.format->color_fixup;
if (texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW)
- args->shadow |= 1 << i;
+ args->shadow |= 1u << i;
/* Flag samplers that need NP2 texcoord fixup. */
if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
- args->np2_fixup |= (1 << i);
+ args->np2_fixup |= (1u << i);
}
if (shader->reg_maps.shader_version.major >= 3)
{
}
}
+ if (context->d3d_info->limits.varying_count < wined3d_max_compat_varyings(context->gl_info))
+ {
+ const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
+
+ args->texcoords_initialized = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ if (vs)
+ {
+ if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.output_registers & (1u << i))
+ args->texcoords_initialized |= 1u << i;
+ }
+ else
+ {
+ const struct wined3d_stream_info *si = &context->stream_info;
+ unsigned int coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+
+ if ((state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK
+ || (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))))
+ args->texcoords_initialized |= 1u << i;
+ }
+ }
+ }
+ else
+ {
+ args->texcoords_initialized = (1u << MAX_TEXTURES) - 1;
+ }
+
args->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE]
&& state->gl_primitive_type == GL_POINTS;
+
+ if (d3d_info->emulated_flatshading)
+ args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
}
static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
/* DCL usage masks */
#define WINED3DSP_DCL_USAGE_SHIFT 0
-#define WINED3DSP_DCL_USAGE_MASK (0xf << WINED3DSP_DCL_USAGE_SHIFT)
+#define WINED3DSP_DCL_USAGE_MASK (0xfu << WINED3DSP_DCL_USAGE_SHIFT)
#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16
-#define WINED3DSP_DCL_USAGEINDEX_MASK (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT)
+#define WINED3DSP_DCL_USAGEINDEX_MASK (0xfu << WINED3DSP_DCL_USAGEINDEX_SHIFT)
/* DCL sampler type */
#define WINED3D_SM1_RESOURCE_TYPE_SHIFT 27
-#define WINED3D_SM1_RESOURCE_TYPE_MASK (0xf << WINED3D_SM1_RESOURCE_TYPE_SHIFT)
+#define WINED3D_SM1_RESOURCE_TYPE_MASK (0xfu << WINED3D_SM1_RESOURCE_TYPE_SHIFT)
/* Opcode-related masks */
#define WINED3DSI_OPCODE_MASK 0x0000ffff
#define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16
-#define WINED3D_OPCODESPECIFICCONTROL_MASK (0xff << WINED3D_OPCODESPECIFICCONTROL_SHIFT)
+#define WINED3D_OPCODESPECIFICCONTROL_MASK (0xffu << WINED3D_OPCODESPECIFICCONTROL_SHIFT)
#define WINED3DSI_INSTLENGTH_SHIFT 24
-#define WINED3DSI_INSTLENGTH_MASK (0xf << WINED3DSI_INSTLENGTH_SHIFT)
+#define WINED3DSI_INSTLENGTH_MASK (0xfu << WINED3DSI_INSTLENGTH_SHIFT)
-#define WINED3DSI_COISSUE (1 << 30)
+#define WINED3DSI_COISSUE (0x1u << 30)
#define WINED3DSI_COMMENTSIZE_SHIFT 16
-#define WINED3DSI_COMMENTSIZE_MASK (0x7fff << WINED3DSI_COMMENTSIZE_SHIFT)
+#define WINED3DSI_COMMENTSIZE_MASK (0x7fffu << WINED3DSI_COMMENTSIZE_SHIFT)
-#define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28)
+#define WINED3DSHADER_INSTRUCTION_PREDICATED (0x1u << 28)
/* Register number mask */
#define WINED3DSP_REGNUM_MASK 0x000007ff
/* Register type masks */
#define WINED3DSP_REGTYPE_SHIFT 28
-#define WINED3DSP_REGTYPE_MASK (0x7 << WINED3DSP_REGTYPE_SHIFT)
+#define WINED3DSP_REGTYPE_MASK (0x7u << WINED3DSP_REGTYPE_SHIFT)
#define WINED3DSP_REGTYPE_SHIFT2 8
-#define WINED3DSP_REGTYPE_MASK2 (0x18 << WINED3DSP_REGTYPE_SHIFT2)
+#define WINED3DSP_REGTYPE_MASK2 (0x18u << WINED3DSP_REGTYPE_SHIFT2)
/* Relative addressing mask */
#define WINED3DSHADER_ADDRESSMODE_SHIFT 13
-#define WINED3DSHADER_ADDRESSMODE_MASK (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
+#define WINED3DSHADER_ADDRESSMODE_MASK (0x1u << WINED3DSHADER_ADDRESSMODE_SHIFT)
/* Destination modifier mask */
#define WINED3DSP_DSTMOD_SHIFT 20
-#define WINED3DSP_DSTMOD_MASK (0xf << WINED3DSP_DSTMOD_SHIFT)
+#define WINED3DSP_DSTMOD_MASK (0xfu << WINED3DSP_DSTMOD_SHIFT)
/* Destination shift mask */
#define WINED3DSP_DSTSHIFT_SHIFT 24
-#define WINED3DSP_DSTSHIFT_MASK (0xf << WINED3DSP_DSTSHIFT_SHIFT)
+#define WINED3DSP_DSTSHIFT_MASK (0xfu << WINED3DSP_DSTSHIFT_SHIFT)
/* Write mask */
#define WINED3D_SM1_WRITEMASK_SHIFT 16
-#define WINED3D_SM1_WRITEMASK_MASK (0xf << WINED3D_SM1_WRITEMASK_SHIFT)
+#define WINED3D_SM1_WRITEMASK_MASK (0xfu << WINED3D_SM1_WRITEMASK_SHIFT)
/* Swizzle mask */
#define WINED3DSP_SWIZZLE_SHIFT 16
-#define WINED3DSP_SWIZZLE_MASK (0xff << WINED3DSP_SWIZZLE_SHIFT)
+#define WINED3DSP_SWIZZLE_MASK (0xffu << WINED3DSP_SWIZZLE_SHIFT)
/* Source modifier mask */
#define WINED3DSP_SRCMOD_SHIFT 24
-#define WINED3DSP_SRCMOD_MASK (0xf << WINED3DSP_SRCMOD_SHIFT)
+#define WINED3DSP_SRCMOD_MASK (0xfu << WINED3DSP_SRCMOD_SHIFT)
#define WINED3DSP_END 0x0000ffff
enum WINED3DSHADER_ADDRESSMODE_TYPE
{
- WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
- WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+ WINED3DSHADER_ADDRMODE_ABSOLUTE = 0u << WINED3DSHADER_ADDRESSMODE_SHIFT,
+ WINED3DSHADER_ADDRMODE_RELATIVE = 1u << WINED3DSHADER_ADDRESSMODE_SHIFT,
};
enum wined3d_sm1_resource_type
{
if (priv->shader_version.major < 2)
{
- *addr_token = (1 << 31)
+ *addr_token = (1u << 31)
| ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT2) & WINED3DSP_REGTYPE_MASK2)
| ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT) & WINED3DSP_REGTYPE_MASK)
| (WINED3DSP_NOSWIZZLE << WINED3DSP_SWIZZLE_SHIFT);
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
-#define WINED3D_SM4_INSTRUCTION_MODIFIER (1 << 31)
+#define WINED3D_SM4_INSTRUCTION_MODIFIER (0x1u << 31)
#define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24
-#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0x1f << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
+#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0x1fu << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
#define WINED3D_SM4_RESOURCE_TYPE_SHIFT 11
-#define WINED3D_SM4_RESOURCE_TYPE_MASK (0xf << WINED3D_SM4_RESOURCE_TYPE_SHIFT)
+#define WINED3D_SM4_RESOURCE_TYPE_MASK (0xfu << WINED3D_SM4_RESOURCE_TYPE_SHIFT)
#define WINED3D_SM4_PRIMITIVE_TYPE_SHIFT 11
-#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x7 << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
+#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x7u << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
#define WINED3D_SM4_INDEX_TYPE_SHIFT 11
-#define WINED3D_SM4_INDEX_TYPE_MASK (0x1 << WINED3D_SM4_INDEX_TYPE_SHIFT)
+#define WINED3D_SM4_INDEX_TYPE_MASK (0x1u << WINED3D_SM4_INDEX_TYPE_SHIFT)
#define WINED3D_SM4_OPCODE_MASK 0xff
-#define WINED3D_SM4_REGISTER_MODIFIER (1 << 31)
+#define WINED3D_SM4_REGISTER_MODIFIER (0x1u << 31)
#define WINED3D_SM4_ADDRESSING_SHIFT1 25
-#define WINED3D_SM4_ADDRESSING_MASK1 (0x3 << WINED3D_SM4_ADDRESSING_SHIFT1)
+#define WINED3D_SM4_ADDRESSING_MASK1 (0x3u << WINED3D_SM4_ADDRESSING_SHIFT1)
#define WINED3D_SM4_ADDRESSING_SHIFT0 22
-#define WINED3D_SM4_ADDRESSING_MASK0 (0x3 << WINED3D_SM4_ADDRESSING_SHIFT0)
+#define WINED3D_SM4_ADDRESSING_MASK0 (0x3u << WINED3D_SM4_ADDRESSING_SHIFT0)
#define WINED3D_SM4_REGISTER_ORDER_SHIFT 20
-#define WINED3D_SM4_REGISTER_ORDER_MASK (0x3 << WINED3D_SM4_REGISTER_ORDER_SHIFT)
+#define WINED3D_SM4_REGISTER_ORDER_MASK (0x3u << WINED3D_SM4_REGISTER_ORDER_SHIFT)
#define WINED3D_SM4_REGISTER_TYPE_SHIFT 12
-#define WINED3D_SM4_REGISTER_TYPE_MASK (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
+#define WINED3D_SM4_REGISTER_TYPE_MASK (0xfu << WINED3D_SM4_REGISTER_TYPE_SHIFT)
#define WINED3D_SM4_SWIZZLE_TYPE_SHIFT 2
-#define WINED3D_SM4_SWIZZLE_TYPE_MASK (0x3 << WINED3D_SM4_SWIZZLE_TYPE_SHIFT)
+#define WINED3D_SM4_SWIZZLE_TYPE_MASK (0x3u << WINED3D_SM4_SWIZZLE_TYPE_SHIFT)
#define WINED3D_SM4_IMMCONST_TYPE_SHIFT 0
-#define WINED3D_SM4_IMMCONST_TYPE_MASK (0x3 << WINED3D_SM4_IMMCONST_TYPE_SHIFT)
+#define WINED3D_SM4_IMMCONST_TYPE_MASK (0x3u << WINED3D_SM4_IMMCONST_TYPE_SHIFT)
#define WINED3D_SM4_WRITEMASK_SHIFT 4
-#define WINED3D_SM4_WRITEMASK_MASK (0xf << WINED3D_SM4_WRITEMASK_SHIFT)
+#define WINED3D_SM4_WRITEMASK_MASK (0xfu << WINED3D_SM4_WRITEMASK_SHIFT)
#define WINED3D_SM4_SWIZZLE_SHIFT 4
-#define WINED3D_SM4_SWIZZLE_MASK (0xff << WINED3D_SM4_SWIZZLE_SHIFT)
+#define WINED3D_SM4_SWIZZLE_MASK (0xffu << WINED3D_SM4_SWIZZLE_SHIFT)
#define WINED3D_SM4_VERSION_MAJOR(version) (((version) >> 4) & 0xf)
#define WINED3D_SM4_VERSION_MINOR(version) (((version) >> 0) & 0xf)
}
}
-static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
checkGLcall("glShadeModel(GL_FLAT)");
break;
case WINED3D_SHADE_GOURAUD:
+ /* WINED3D_SHADE_PHONG in practice is the same as WINED3D_SHADE_GOURAUD
+ * in D3D. */
+ case WINED3D_SHADE_PHONG:
gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH);
checkGLcall("glShadeModel(GL_SMOOTH)");
break;
- case WINED3D_SHADE_PHONG:
- FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
- break;
default:
FIXME("Unrecognized shade mode %#x.\n",
state->render_states[WINED3D_RS_SHADEMODE]);
* The enabled / disabled planes are hardcoded into the shader. Update the
* shader to update the enabled clipplanes. In case of fixed function, we
* need to update the clipping field from ffp_vertex_settings. */
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
/* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
* of already set values
}
context->num_untracked_materials = 0;
- if ((context->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE))
+ if ((context->stream_info.use_map & (1u << WINED3D_FFP_DIFFUSE))
&& state->render_states[WINED3D_RS_COLORVERTEX])
{
TRACE("diff %d, amb %d, emis %d, spec %d\n",
* by zero and is not properly defined in opengl, so avoid it
*/
if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
- && (context->stream_info.use_map & (1 << WINED3D_FFP_NORMAL)))
+ && (context->stream_info.use_map & (1u << WINED3D_FFP_NORMAL)))
{
gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
checkGLcall("glEnable(GL_NORMALIZE);");
* OpenGL the bias is specified in units of "the smallest value that is
* guaranteed to produce a resolvable offset for a given implementation". To
* convert from D3D to GL we need to divide the D3D depth bias by that value.
- * There's no practical way to retrieve that value from a given GL
- * implementation, but the D3D application has essentially the same problem,
- * which makes a guess of the depth buffer format's highest possible value a
- * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
- * depth slope, and doesn't need to be scaled. */
+ * We try to detect the value from GL with test draws. On most drivers (r300g,
+ * 600g, Nvidia, i965 on Mesa) the value is 2^23 for fixed point depth buffers,
+ * for r200 and i965 on OSX it is 2^24, for r500 on OSX it is 2^22. For floating
+ * point buffers it is 2^22, 2^23 or 2^24 depending on the GPU. The value does
+ * not depend on the depth buffer precision on any driver.
+ *
+ * Two games that are picky regarding depth bias are Mass Effect 2 (flickering
+ * decals) and F.E.A.R and F.E.A.R. 2 (semi-transparent guns).
+ *
+ * Note that SLOPESCALEDEPTHBIAS is a scaling factor for the depth slope, and
+ * doesn't need to be scaled to account for GL vs D3D differences. */
static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
{
if (depth)
{
- const struct wined3d_format *fmt = depth->format;
- scale = powf(2, fmt->depth_size) - 1;
+ if (depth->format_flags & WINED3DFMT_FLAG_FLOAT)
+ scale = gl_info->float_polyoffset_scale;
+ else
+ scale = gl_info->fixed_polyoffset_scale;
+
TRACE("Depth format %s, using depthbias scale of %.8e.\n",
- debug_d3dformat(fmt->id), scale);
+ debug_d3dformat(depth->format->id), scale);
}
else
{
static void tex_colorop(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);
- BOOL tex_used = context->fixed_function_usage_map & (1 << stage);
+ BOOL tex_used = context->fixed_function_usage_map & (1u << stage);
DWORD mapped_stage = context->tex_unit_map[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
void tex_alphaop(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);
- BOOL tex_used = context->fixed_function_usage_map & (1 << stage);
+ BOOL tex_used = context->fixed_function_usage_map & (1u << stage);
DWORD mapped_stage = context->tex_unit_map[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
DWORD op, arg1, arg2, arg0;
continue;
}
- if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
+ 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];
{
const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
- if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
+ if (texIsPow2 || (context->lastWasPow2Texture & (1u << sampler)))
{
if (texIsPow2)
- context->lastWasPow2Texture |= 1 << sampler;
+ context->lastWasPow2Texture |= 1u << sampler;
else
- context->lastWasPow2Texture &= ~(1 << sampler);
+ context->lastWasPow2Texture &= ~(1u << sampler);
transform_texture(context, state,
STATE_TEXTURESTAGE(context->tex_unit_map[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
context->last_was_pshader = FALSE;
}
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_GEOMETRY;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_GEOMETRY;
}
static void shader_bumpenv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
GL_EXTCALL(glVertexAttribDivisor(i, 0));
- context->numbered_array_mask &= ~(1 << i);
+ context->numbered_array_mask &= ~(1u << i);
}
/* This should match any arrays loaded in loadNumberedArrays
{
const struct wined3d_stream_state *stream;
- if (!(stream_info->use_map & (1 << i)))
+ if (!(stream_info->use_map & (1u << i)))
{
- if (context->numbered_array_mask & (1 << 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));
{
/* Unload instanced arrays, they will be loaded using
* immediate mode instead. */
- if (context->numbered_array_mask & (1 << i))
+ if (context->numbered_array_mask & (1u << i))
unload_numbered_array(context, i);
continue;
}
stream_info->elements[i].stride, stream_info->elements[i].data.addr
+ state->load_base_vertex_index * stream_info->elements[i].stride));
- if (!(context->numbered_array_mask & (1 << i)))
+ if (!(context->numbered_array_mask & (1u << i)))
{
GL_EXTCALL(glEnableVertexAttribArray(i));
- context->numbered_array_mask |= (1 << i);
+ context->numbered_array_mask |= (1u << i);
}
}
else
ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, context);
}
- if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
+ if (context->numbered_array_mask & (1u << i)) unload_numbered_array(context, i);
switch (stream_info->elements[i].format->id)
{
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
const DWORD *src = (const DWORD *)ptr;
- DWORD c = *src & 0xff00ff00;
- c |= (*src & 0xff0000) >> 16;
- c |= (*src & 0xff) << 16;
+ DWORD c = *src & 0xff00ff00u;
+ c |= (*src & 0xff0000u) >> 16;
+ c |= (*src & 0xffu) << 16;
GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
break;
}
context->instance_count = 0;
/* Blend Data ---------------------------------------------- */
- if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
- || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
+ if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT))
+ || si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
{
e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
checkGLcall("glWeightPointerARB");
- if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
+ if (si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
{
static BOOL warned;
if (!warned)
}
/* Point Size ----------------------------------------------*/
- if (si->use_map & (1 << WINED3D_FFP_PSIZE))
+ 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");
}
/* Vertex Pointers -----------------------------------------*/
- if (si->use_map & (1 << WINED3D_FFP_POSITION))
+ if (si->use_map & (1u << WINED3D_FFP_POSITION))
{
e = &si->elements[WINED3D_FFP_POSITION];
}
/* Normals -------------------------------------------------*/
- if (si->use_map & (1 << WINED3D_FFP_NORMAL))
+ if (si->use_map & (1u << WINED3D_FFP_NORMAL))
{
e = &si->elements[WINED3D_FFP_NORMAL];
}
/* Diffuse Colour --------------------------------------------*/
- if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
+ if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
{
e = &si->elements[WINED3D_FFP_DIFFUSE];
}
/* Specular Colour ------------------------------------------*/
- if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
+ if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
{
TRACE("setting specular colour\n");
}
context->last_was_vshader = useVertexShaderFunction;
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
if (updateFog)
context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
if (use_ps(state) && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.major == 1
&& state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3)
- context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
}
}
{ STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
- { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
}
+static DWORD vp_ffp_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return GL_EXT_EMUL_ARB_MULTITEXTURE | GL_EXT_EMUL_EXT_FOG_COORD;
+}
+
const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
{
ffp_enable,
vp_ffp_get_caps,
+ vp_ffp_get_emul_mask,
ffp_alloc,
ffp_free,
vp_ffp_states,
caps->MaxSimultaneousTextures = gl_info->limits.textures;
}
+static DWORD ffp_fragment_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return GL_EXT_EMUL_ARB_MULTITEXTURE | GL_EXT_EMUL_EXT_FOG_COORD;
+}
+
static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d))
const struct fragment_pipeline ffp_fragment_pipeline = {
ffp_enable,
ffp_fragment_get_caps,
+ ffp_fragment_get_emul_mask,
ffp_alloc,
ffp_free,
ffp_none_context_alloc,
memset(caps, 0, sizeof(*caps));
}
+static DWORD vp_none_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return 0;
+}
+
const struct wined3d_vertex_pipe_ops none_vertex_pipe =
{
none_enable,
vp_none_get_caps,
+ vp_none_get_emul_mask,
none_alloc,
none_free,
NULL,
memset(caps, 0, sizeof(*caps));
}
+static DWORD fp_none_get_emul_mask(const struct wined3d_gl_info *gl_info)
+{
+ return 0;
+}
+
static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
{
return is_identity_fixup(fixup);
{
none_enable,
fp_none_get_caps,
+ fp_none_get_emul_mask,
none_alloc,
none_free,
ffp_none_context_alloc,
static inline void stateblock_set_bits(DWORD *map, UINT map_size)
{
- DWORD mask = (1 << (map_size & 0x1f)) - 1;
+ DWORD mask = (1u << (map_size & 0x1f)) - 1;
memset(map, 0xff, (map_size >> 5) * sizeof(*map));
if (mask) map[map_size >> 5] = mask;
}
for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
{
DWORD rs = pixel_states_render[i];
- states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
+ states->renderState[rs >> 5] |= 1u << (rs & 0x1f);
}
for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i)
- texture_mask |= 1 << pixel_states_texture[i];
+ texture_mask |= 1u << pixel_states_texture[i];
for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
- sampler_mask |= 1 << pixel_states_sampler[i];
+ sampler_mask |= 1u << pixel_states_sampler[i];
for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
states->pixelShaderConstantsB = 0xffff;
states->pixelShaderConstantsI = 0xffff;
for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
{
DWORD rs = vertex_states_render[i];
- states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
+ states->renderState[rs >> 5] |= 1u << (rs & 0x1f);
}
for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i)
- texture_mask |= 1 << vertex_states_texture[i];
+ texture_mask |= 1u << vertex_states_texture[i];
for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
- sampler_mask |= 1 << vertex_states_sampler[i];
+ sampler_mask |= 1u << vertex_states_sampler[i];
for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
states->vertexShaderConstantsB = 0xffff;
states->vertexShaderConstantsI = 0xffff;
for (i = 0; i < MAX_CONST_I; ++i)
{
- if (stateblock->changed.vertexShaderConstantsI & (1 << i))
+ if (stateblock->changed.vertexShaderConstantsI & (1u << i))
{
stateblock->contained_vs_consts_i[stateblock->num_contained_vs_consts_i] = i;
++stateblock->num_contained_vs_consts_i;
for (i = 0; i < MAX_CONST_B; ++i)
{
- if (stateblock->changed.vertexShaderConstantsB & (1 << i))
+ if (stateblock->changed.vertexShaderConstantsB & (1u << i))
{
stateblock->contained_vs_consts_b[stateblock->num_contained_vs_consts_b] = i;
++stateblock->num_contained_vs_consts_b;
for (i = 0; i < MAX_CONST_I; ++i)
{
- if (stateblock->changed.pixelShaderConstantsI & (1 << i))
+ if (stateblock->changed.pixelShaderConstantsI & (1u << i))
{
stateblock->contained_ps_consts_i[stateblock->num_contained_ps_consts_i] = i;
++stateblock->num_contained_ps_consts_i;
for (i = 0; i < MAX_CONST_B; ++i)
{
- if (stateblock->changed.pixelShaderConstantsB & (1 << i))
+ if (stateblock->changed.pixelShaderConstantsB & (1u << i))
{
stateblock->contained_ps_consts_b[stateblock->num_contained_ps_consts_b] = i;
++stateblock->num_contained_ps_consts_b;
/* Works correctly only for <= 4 bpp formats. */
static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
{
- masks[0] = ((1 << format->red_size) - 1) << format->red_offset;
- masks[1] = ((1 << format->green_size) - 1) << format->green_offset;
- masks[2] = ((1 << format->blue_size) - 1) << format->blue_offset;
+ masks[0] = ((1u << format->red_size) - 1) << format->red_offset;
+ masks[1] = ((1u << format->green_size) - 1) << format->green_offset;
+ masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset;
}
static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
BITMAPINFO *b_info;
int extraline = 0;
DWORD *masks;
+#if defined(STAGING_CSMT)
UINT row_pitch, slice_pitch;
+#endif /* STAGING_CSMT */
TRACE("surface %p.\n", surface);
default:
/* Allocate extra space for a palette. */
b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << (format->byte_count * 8)));
+ sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1u << (format->byte_count * 8)));
break;
}
b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
/* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */
+#if defined(STAGING_CSMT)
wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch);
b_info->bmiHeader.biWidth = row_pitch / format->byte_count;
b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline;
b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline)
* row_pitch;
+#else /* STAGING_CSMT */
+ b_info->bmiHeader.biWidth = wined3d_surface_get_pitch(surface) / format->byte_count;
+ b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline;
+ b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline)
+ * wined3d_surface_get_pitch(surface);
+#endif /* STAGING_CSMT */
b_info->bmiHeader.biPlanes = 1;
b_info->bmiHeader.biBitCount = format->byte_count * 8;
}
if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container)
- surface_load_location(surface, surface->container->resource.draw_binding);
+ {
+ context = context_acquire(device, surface);
+ surface_load_location(surface, context, surface->container->resource.draw_binding);
+ context_release(context);
+ }
else if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
FIXME("Depth / stencil buffer locking is not implemented.\n");
#endif /* STAGING_CSMT */
if (src_mask & WINED3DFMT_FLAG_STENCIL)
gl_mask |= GL_STENCIL_BUFFER_BIT;
-#if !defined(STAGING_CSMT)
- /* Make sure the locations are up-to-date. Loading the destination
- * surface isn't required if the entire surface is overwritten. */
- surface_load_location(src_surface, src_location);
- if (!surface_is_full_rect(dst_surface, dst_rect))
- surface_load_location(dst_surface, dst_location);
-
-#endif /* STAGING_CSMT */
context = context_acquire(device, NULL);
if (!context->valid)
{
return;
}
-#if defined(STAGING_CSMT)
/* Make sure the locations are up-to-date. Loading the destination
* surface isn't required if the entire surface is overwritten. */
+#if defined(STAGING_CSMT)
wined3d_resource_load_location(&src_surface->resource, context, src_location);
if (!surface_is_full_rect(dst_surface, dst_rect))
wined3d_resource_load_location(&dst_surface->resource, context, dst_location);
-
+#else /* STAGING_CSMT */
+ surface_load_location(src_surface, context, src_location);
+ if (!surface_is_full_rect(dst_surface, dst_rect))
+ surface_load_location(dst_surface, context, dst_location);
#endif /* STAGING_CSMT */
+
gl_info = context->gl_info;
context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, src_location);
context_release(context);
}
-#if defined(STAGING_CSMT)
/* 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 surface_blt_fbo(const struct wined3d_device *device,
struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect_in)
{
const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
- struct wined3d_surface *required_rt, *restore_rt;
-#else /* STAGING_CSMT */
-/* Blit between surface locations. Onscreen on different swapchains is not supported.
- * Depth / stencil is not supported. */
-static void surface_blt_fbo(const struct wined3d_device *device, 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)
-{
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
-#endif /* STAGING_CSMT */
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *required_rt, *restore_rt = NULL;
RECT src_rect, dst_rect;
GLenum gl_filter;
GLenum buffer;
wined3d_resource_load_location(&src_surface->resource, old_ctx, src_location);
if (!surface_is_full_rect(dst_surface, &dst_rect))
wined3d_resource_load_location(&dst_surface->resource, old_ctx, dst_location);
+#else /* STAGING_CSMT */
+ surface_load_location(src_surface, old_ctx, src_location);
+ if (!surface_is_full_rect(dst_surface, &dst_rect))
+ surface_load_location(dst_surface, old_ctx, dst_location);
+#endif /* STAGING_CSMT */
if (src_location == WINED3D_LOCATION_DRAWABLE) required_rt = src_surface;
else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface;
restore_rt = old_ctx->current_rt;
context = context_acquire(device, required_rt);
}
- else
- {
- restore_rt = NULL;
- context = old_ctx;
- }
-#else /* STAGING_CSMT */
- surface_load_location(src_surface, src_location);
- if (!surface_is_full_rect(dst_surface, &dst_rect))
- surface_load_location(dst_surface, dst_location);
-
- if (src_location == WINED3D_LOCATION_DRAWABLE) context = context_acquire(device, src_surface);
- else if (dst_location == WINED3D_LOCATION_DRAWABLE) context = context_acquire(device, dst_surface);
- else context = context_acquire(device, NULL);
-#endif /* STAGING_CSMT */
if (!context->valid)
{
&& dst_surface->container->swapchain->front_buffer == dst_surface->container))
gl_info->gl_ops.gl.p_glFlush();
-#if defined(STAGING_CSMT)
if (restore_rt)
- {
- context_release(context);
- context = context_acquire(device, restore_rt);
- context_release(context);
- }
-#else /* STAGING_CSMT */
- context_release(context);
-#endif /* STAGING_CSMT */
+ context_restore(context, restore_rt);
}
static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
|| (dst_usage & WINED3DUSAGE_RENDERTARGET)))
return FALSE;
+ if (!(src_format->id == dst_format->id
+ || (is_identity_fixup(src_format->color_fixup)
+ && is_identity_fixup(dst_format->color_fixup))))
+ return FALSE;
break;
case WINED3D_BLIT_OP_DEPTH_BLIT:
return FALSE;
if (!(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
return FALSE;
+ /* Accept pure swizzle fixups for depth formats. In general we
+ * ignore the stencil component (if present) at the moment and the
+ * swizzle is not relevant with just the depth component. */
+ if (is_complex_fixup(src_format->color_fixup) || is_complex_fixup(dst_format->color_fixup)
+ || is_scaling_fixup(src_format->color_fixup) || is_scaling_fixup(dst_format->color_fixup))
+ return FALSE;
break;
default:
return FALSE;
}
- if (!(src_format->id == dst_format->id
- || (is_identity_fixup(src_format->color_fixup)
- && is_identity_fixup(dst_format->color_fixup))))
- return FALSE;
-
return TRUE;
}
return WINED3D_OK;
}
-HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *surface,
- struct wined3d_surface *render_target)
-{
- TRACE("surface %p, render_target %p.\n", surface, render_target);
-
- /* TODO: Check surface sizes, pools, etc. */
-
- if (render_target->resource.multisample_type)
- return WINED3DERR_INVALIDCALL;
-
- return wined3d_surface_blt(surface, NULL, render_target, NULL, 0, NULL, WINED3D_TEXF_POINT);
-}
-
#if !defined(STAGING_CSMT)
/* Context activation is done by the caller. */
static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
TRACE("surface %p.\n", surface);
-#if defined(STAGING_CSMT)
context = context_acquire(device, NULL);
gl_info = context->gl_info;
if (resource->pool == WINED3D_POOL_DEFAULT)
{
+#if defined(STAGING_CSMT)
/* Default pool resources are supposed to be destroyed before Reset is called.
* Implicit resources stay however. So this means we have an implicit render target
* or depth stencil. The content may be destroyed, but we still have to tear down
wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DISCARDED);
wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DISCARDED);
#else /* STAGING_CSMT */
- if (resource->pool == WINED3D_POOL_DEFAULT)
- {
/* Default pool resources are supposed to be destroyed before Reset is called.
* Implicit resources stay however. So this means we have an implicit render target
* or depth stencil. The content may be destroyed, but we still have to tear down
}
#else /* STAGING_CSMT */
surface_prepare_map_memory(surface);
- surface_load_location(surface, surface->resource.map_binding);
+ surface_load_location(surface, context, surface->resource.map_binding);
surface_invalidate_location(surface, ~surface->resource.map_binding);
}
- context = context_acquire(device, NULL);
- gl_info = context->gl_info;
-
/* Destroy PBOs, but load them into real sysmem before */
if (surface->pbo)
surface_remove_pbo(surface, gl_info);
resource_unload(resource);
}
+static HRESULT surface_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ ERR("Not supported on sub-resources.\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
+static HRESULT surface_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
+{
+ ERR("Not supported on sub-resources.\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
#if defined(STAGING_CSMT)
static void wined3d_surface_location_invalidated(struct wined3d_resource *resource, DWORD location)
{
surface_resource_incref,
surface_resource_decref,
surface_unload,
+ surface_resource_sub_resource_map,
+ surface_resource_sub_resource_unmap,
};
static const struct wined3d_surface_ops surface_ops =
void *mem;
GLenum gl_format = format->glFormat;
GLenum gl_type = format->glType;
+#if defined(STAGING_CSMT)
UINT src_pitch = 0;
UINT dst_row_pitch, dst_slice_pitch;
unsigned char alignment = surface->resource.device->surface_alignment;
src_pitch = format->byte_count * surface->pow2Width;
wined3d_resource_get_pitch(&surface->resource, &dst_row_pitch, &dst_slice_pitch);
+#else /* STAGING_CSMT */
+ int src_pitch = 0;
+ int dst_pitch = 0;
+
+ if (surface->flags & SFLAG_NONPOW2)
+ {
+ unsigned char alignment = surface->resource.device->surface_alignment;
+ src_pitch = format->byte_count * surface->pow2Width;
+ dst_pitch = wined3d_surface_get_pitch(surface);
+#endif /* STAGING_CSMT */
src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1);
mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * surface->pow2Height);
}
* won't be released, and doesn't have to be re-read. */
src_data = mem;
dst_data = data.addr;
+#if defined(STAGING_CSMT)
TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_row_pitch);
for (y = 0; y < surface->resource.height; ++y)
{
memcpy(dst_data, src_data, dst_row_pitch);
src_data += src_pitch;
dst_data += dst_row_pitch;
+#else /* STAGING_CSMT */
+ TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch);
+ for (y = 0; y < surface->resource.height; ++y)
+ {
+ memcpy(dst_data, src_data, dst_pitch);
+ src_data += src_pitch;
+ dst_data += dst_pitch;
+#endif /* STAGING_CSMT */
}
HeapFree(GetProcessHeap(), 0, mem);
}
}
-#if defined(STAGING_CSMT)
-BOOL surface_check_block_align(struct wined3d_surface *surface, const RECT *rect)
+static BOOL surface_check_block_align(struct wined3d_surface *surface, const struct wined3d_box *box)
{
- struct wined3d_box box;
-
- if (!rect)
- return wined3d_resource_check_block_align(&surface->resource, NULL);
+#if defined(STAGING_CSMT)
+ return wined3d_resource_check_block_align(&surface->resource, box);
+}
- box.left = rect->left;
- box.top = rect->top;
- box.front = 0;
- box.right = rect->right;
- box.bottom = rect->bottom;
- box.back = 1;
- return wined3d_resource_check_block_align(&surface->resource, &box);
+BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect)
#else /* STAGING_CSMT */
-static BOOL surface_check_block_align(struct wined3d_surface *surface, const RECT *rect)
-{
UINT width_mask, height_mask;
- if (!rect->left && !rect->top
- && rect->right == surface->resource.width
- && rect->bottom == surface->resource.height)
+ if (!box->left && !box->top
+ && box->right == surface->resource.width
+ && box->bottom == surface->resource.height)
return TRUE;
/* This assumes power of two block sizes, but NPOT block sizes would be
width_mask = surface->resource.format->block_width - 1;
height_mask = surface->resource.format->block_height - 1;
- if (!(rect->left & width_mask) && !(rect->top & height_mask)
- && !(rect->right & width_mask) && !(rect->bottom & height_mask))
+ if (!(box->left & width_mask) && !(box->top & height_mask)
+ && !(box->right & width_mask) && !(box->bottom & height_mask))
return TRUE;
return FALSE;
+}
+
+static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect)
#endif /* STAGING_CSMT */
+{
+ struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1};
+
+ return surface_check_block_align(surface, &box);
}
HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
UINT update_w, update_h;
UINT dst_w, dst_h;
RECT r, dst_rect;
+#if defined(STAGING_CSMT)
UINT src_row_pitch, src_slice_pitch;
+#else /* STAGING_CSMT */
+ UINT src_pitch;
+#endif /* STAGING_CSMT */
POINT p;
TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n",
return WINED3DERR_INVALIDCALL;
}
- if ((src_fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align(src_surface, src_rect))
+ if ((src_fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align_rect(src_surface, src_rect))
{
WARN("Source rectangle not block-aligned.\n");
return WINED3DERR_INVALIDCALL;
}
SetRect(&dst_rect, dst_point->x, dst_point->y, dst_point->x + update_w, dst_point->y + update_h);
- if ((dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align(dst_surface, &dst_rect))
+ if ((dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align_rect(dst_surface, &dst_rect))
{
WARN("Destination rectangle not block-aligned.\n");
return WINED3DERR_INVALIDCALL;
wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE);
wined3d_resource_get_memory(&src_surface->resource, src_surface->resource.locations, &data);
-#else /* STAGING_CSMT */
- surface_load_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB);
- wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE);
-
- surface_get_memory(src_surface, &data, src_surface->locations);
-#endif /* STAGING_CSMT */
wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch);
wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect,
context_release(context);
-#if defined(STAGING_CSMT)
wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB);
#else /* STAGING_CSMT */
+ surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE);
+
+ surface_get_memory(src_surface, &data, src_surface->locations);
+ src_pitch = wined3d_surface_get_pitch(src_surface);
+
+ wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect,
+ src_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
+
+ context_release(context);
+
surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB);
surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB);
#endif /* STAGING_CSMT */
return GL_BACK;
}
-#if defined(STAGING_CSMT)
/* Context activation is done by the caller. */
void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb)
-#else /* STAGING_CSMT */
-void surface_load(struct wined3d_surface *surface, BOOL srgb)
-#endif /* STAGING_CSMT */
{
DWORD location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
}
TRACE("Reloading because surface is dirty.\n");
- surface_load_location(surface, location);
+ surface_load_location(surface, context, location);
#endif /* STAGING_CSMT */
surface_evict_sysmem(surface);
}
if (isinf(*in))
return (*in < 0.0f ? 0xfc00 : 0x7c00);
- if (tmp < powf(2, 10))
+ if (tmp < (float)(1u << 10))
{
do
{
tmp = tmp * 2.0f;
exp--;
- } while (tmp < powf(2, 10));
+ } while (tmp < (float)(1u << 10));
}
- else if (tmp >= powf(2, 11))
+ else if (tmp >= (float)(1u << 11))
{
do
{
tmp /= 2.0f;
exp++;
- } while (tmp >= powf(2, 11));
+ } while (tmp >= (float)(1u << 11));
}
mantissa = (unsigned int)tmp;
return &surface->resource;
}
-HRESULT CDECL wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags)
-{
- TRACE("surface %p, flags %#x.\n", surface, flags);
-
- switch (flags)
- {
- case WINEDDGBS_CANBLT:
- case WINEDDGBS_ISBLTDONE:
- return WINED3D_OK;
-
- default:
- return WINED3DERR_INVALIDCALL;
- }
-}
-
-HRESULT CDECL wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags)
-{
- TRACE("surface %p, flags %#x.\n", surface, flags);
-
- /* XXX: DDERR_INVALIDSURFACETYPE */
-
- switch (flags)
- {
- case WINEDDGFS_CANFLIP:
- case WINEDDGFS_ISFLIPDONE:
- return WINED3D_OK;
-
- default:
- return WINED3DERR_INVALIDCALL;
- }
-}
-
HRESULT CDECL wined3d_surface_is_lost(const struct wined3d_surface *surface)
{
TRACE("surface %p.\n", surface);
return WINED3D_OK;
}
+DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
+{
+#if defined(STAGING_CSMT)
+ UINT row_pitch, slice_pitch;
+ const struct wined3d_resource *resource = &surface->resource;
+ wined3d_resource_get_pitch(resource, &row_pitch, &slice_pitch);
+ return row_pitch;
+#else /* STAGING_CSMT */
+ unsigned int alignment;
+ DWORD pitch;
+
+ TRACE("surface %p.\n", surface);
+
+ if (surface->pitch)
+ return surface->pitch;
+
+ alignment = surface->resource.device->surface_alignment;
+ pitch = wined3d_format_calculate_pitch(surface->resource.format, surface->resource.width);
+ pitch = (pitch + alignment - 1) & ~(alignment - 1);
+
+ TRACE("Returning %u.\n", pitch);
+
+ return pitch;
+#endif /* STAGING_CSMT */
+}
+
HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y)
{
LONG w, h;
#if defined(STAGING_CSMT)
if ((surface->resource.user_memory = mem))
-#else /* STAGING_CSMT */
- if ((surface->user_memory = mem))
-#endif /* STAGING_CSMT */
{
surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
valid_location = WINED3D_LOCATION_USER_MEMORY;
else
{
/* User memory surfaces don't have the regular surface alignment. */
- surface->resource.size = wined3d_format_calculate_size(texture_resource->format, 1, width, height, 1);
+ surface->resource.size = wined3d_format_calculate_size(texture_resource->format,
+ 1, width, height, 1);
surface->resource.custom_row_pitch = wined3d_format_calculate_pitch(texture_resource->format, width);
- surface->resource.custom_slice_pitch = surface->resource.custom_row_pitch * surface->resource.height; /* FIXME */
+#else /* STAGING_CSMT */
+ if ((surface->user_memory = mem))
+ {
+ surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
+ valid_location = WINED3D_LOCATION_USER_MEMORY;
+ }
+ surface->pitch = pitch;
+ surface->resource.format = texture_resource->format;
+ surface->resource.multisample_type = texture_resource->multisample_type;
+ surface->resource.multisample_quality = texture_resource->multisample_quality;
+ if (surface->pitch)
+ {
+ surface->resource.size = height * surface->pitch;
+ }
+ else
+ {
+ /* User memory surfaces don't have the regular surface alignment. */
+ surface->resource.size = wined3d_format_calculate_size(texture_resource->format,
+ 1, width, height, 1);
+ surface->pitch = wined3d_format_calculate_pitch(texture_resource->format, width);
+#endif /* STAGING_CSMT */
}
/* The format might be changed to a format that needs conversion.
for (x = 0; x < w; ++x)
{
WORD pixel = src_line[x];
- dst_line[x] = 0xff000000
- | convert_5to8[(pixel & 0xf800) >> 11] << 16
- | convert_6to8[(pixel & 0x07e0) >> 5] << 8
- | convert_5to8[(pixel & 0x001f)];
+ dst_line[x] = 0xff000000u
+ | convert_5to8[(pixel & 0xf800u) >> 11] << 16
+ | convert_6to8[(pixel & 0x07e0u) >> 5] << 8
+ | convert_5to8[(pixel & 0x001fu)];
}
}
}
memset(&surface->lockedRect, 0, sizeof(surface->lockedRect));
return hr;
-}
-
-HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
- struct wined3d_map_desc *map_desc, const RECT *rect, DWORD flags)
-{
- struct wined3d_box box;
- const struct wined3d_format *format = surface->resource.format;
- unsigned int fmt_flags = surface->container->resource.format_flags;
#else /* STAGING_CSMT */
TRACE("surface %p.\n", surface);
surface->surface_ops->surface_unmap(surface);
return WINED3D_OK;
+#endif /* STAGING_CSMT */
}
HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
- struct wined3d_map_desc *map_desc, const RECT *rect, DWORD flags)
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
{
const struct wined3d_format *format = surface->resource.format;
unsigned int fmt_flags = surface->container->resource.format_flags;
+#if !defined(STAGING_CSMT)
struct wined3d_device *device = surface->resource.device;
struct wined3d_context *context;
const struct wined3d_gl_info *gl_info;
BYTE *base_memory;
- TRACE("surface %p, map_desc %p, rect %s, flags %#x.\n",
- surface, map_desc, wine_dbgstr_rect(rect), flags);
+ TRACE("surface %p, map_desc %p, box %p, flags %#x.\n",
+ surface, map_desc, box, flags);
if (surface->resource.map_count)
{
}
#endif /* STAGING_CSMT */
- if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && rect
- && !surface_check_block_align(surface, rect))
+ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box
+ && !surface_check_block_align(surface, box))
{
- WARN("Map rect %s is misaligned for %ux%u blocks.\n",
- wine_dbgstr_rect(rect), format->block_width, format->block_height);
+ WARN("Map rect %p is misaligned for %ux%u blocks.\n",
+ box, format->block_width, format->block_height);
if (surface->resource.pool == WINED3D_POOL_DEFAULT)
return WINED3DERR_INVALIDCALL;
}
#if defined(STAGING_CSMT)
- if (rect)
+ if (box)
{
- surface->lockedRect = *rect;
-
- box.left = rect->left;
- box.top = rect->top;
- box.front = 0;
- box.right = rect->right;
- box.bottom = rect->bottom;
- box.back = 1;
+ surface->lockedRect.left = box->left;
+ surface->lockedRect.top = box->top;
+ surface->lockedRect.right = box->right;
+ surface->lockedRect.bottom = box->bottom;
}
else
{
surface->lockedRect.bottom = surface->resource.height;
}
- return wined3d_resource_map(&surface->resource, map_desc, rect ? &box : NULL, flags);
+ return wined3d_resource_map(&surface->resource, map_desc, box, flags);
}
void wined3d_surface_getdc_cs(struct wined3d_surface *surface)
if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC))
{
- WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->container->resource.format->id));
+ WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id));
return WINED3DERR_INVALIDCALL;
}
+
+ /* Give more detailed info for ddraw. */
+ if (surface->flags & SFLAG_DCINUSE)
+ return WINEDDERR_DCALREADYCREATED;
+
+ /* Can't GetDC if the surface is locked. */
+ if (surface->resource.map_count)
+ return WINED3DERR_INVALIDCALL;
+
+ surface->flags |= SFLAG_DCINUSE;
+ surface->resource.map_count++;
+ wined3d_cs_emit_getdc(device->cs, surface);
+ *dc = surface->hDC;
+ TRACE("Returning dc %p.\n", *dc);
+
+ return *dc ? WINED3D_OK : WINED3DERR_INVALIDCALL;
+}
+
+void wined3d_surface_releasedc_cs(struct wined3d_surface *surface)
+{
+ if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
#else /* STAGING_CSMT */
surface_prepare_map_memory(surface);
if (flags & WINED3D_MAP_DISCARD)
}
else
{
+ struct wined3d_context *context = NULL;
+
if (surface->resource.usage & WINED3DUSAGE_DYNAMIC)
WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n");
- surface_load_location(surface, surface->resource.map_binding);
+ if (surface->resource.device->d3d_initialized)
+ context = context_acquire(surface->resource.device, NULL);
+ surface_load_location(surface, context, surface->resource.map_binding);
+ if (context)
+ context_release(context);
}
if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
map_desc->row_pitch = surface->resource.width * format->byte_count;
else
- wined3d_resource_get_pitch(&surface->resource, &map_desc->row_pitch, &map_desc->slice_pitch);
- map_desc->slice_pitch = 0;
+ map_desc->row_pitch = wined3d_surface_get_pitch(surface);
+ map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch;
- if (!rect)
+ if (!box)
{
map_desc->data = base_memory;
surface->lockedRect.left = 0;
/* Compressed textures are block based, so calculate the offset of
* the block that contains the top-left pixel of the locked rectangle. */
map_desc->data = base_memory
- + ((rect->top / format->block_height) * map_desc->row_pitch)
- + ((rect->left / format->block_width) * format->block_byte_count);
+ + ((box->top / format->block_height) * map_desc->row_pitch)
+ + ((box->left / format->block_width) * format->block_byte_count);
}
else
{
map_desc->data = base_memory
- + (map_desc->row_pitch * rect->top)
- + (rect->left * format->byte_count);
+ + (map_desc->row_pitch * box->top)
+ + (box->left * format->byte_count);
}
- surface->lockedRect.left = rect->left;
- surface->lockedRect.top = rect->top;
- surface->lockedRect.right = rect->right;
- surface->lockedRect.bottom = rect->bottom;
+ surface->lockedRect.left = box->left;
+ surface->lockedRect.top = box->top;
+ surface->lockedRect.right = box->right;
+ surface->lockedRect.bottom = box->bottom;
}
TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect));
HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
{
HRESULT hr;
+ struct wined3d_device *device = surface->resource.device;
+ struct wined3d_context *context = NULL;
TRACE("surface %p, dc %p.\n", surface, dc);
-#endif /* STAGING_CSMT */
/* Give more detailed info for ddraw. */
if (surface->flags & SFLAG_DCINUSE)
if (surface->resource.map_count)
return WINED3DERR_INVALIDCALL;
-#if defined(STAGING_CSMT)
- surface->flags |= SFLAG_DCINUSE;
- surface->resource.map_count++;
- wined3d_cs_emit_getdc(device->cs, surface);
- *dc = surface->hDC;
- TRACE("Returning dc %p.\n", *dc);
-
- return *dc ? WINED3D_OK : WINED3DERR_INVALIDCALL;
-}
-
-void wined3d_surface_releasedc_cs(struct wined3d_surface *surface)
-{
- if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
- && surface->resource.map_binding != WINED3D_LOCATION_DIB))
- {
- /* The game Salammbo modifies the surface contents without mapping the surface between
- * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active
- * copy and is copied to the screen, this update, which draws the mouse pointer, is lost.
- * Do not only copy the DIB to the map location, but also make sure the map location is
- * copied back to the DIB in the next getdc call.
- *
- * The same consideration applies to user memory surfaces. */
- struct wined3d_device *device = surface->resource.device;
- struct wined3d_context *context = NULL;
-
- if (device->d3d_initialized)
- context = context_acquire(device, NULL);
+ if (device->d3d_initialized)
+ context = context_acquire(surface->resource.device, NULL);
- wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding);
- wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB);
- if (context)
- context_release(context);
- }
-#else /* STAGING_CSMT */
/* Create a DIB section if there isn't a dc yet. */
if (!surface->hDC)
{
if (surface->flags & SFLAG_CLIENT)
{
- surface_load_location(surface, WINED3D_LOCATION_SYSMEM);
+ surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM);
surface_release_client_storage(surface);
}
hr = surface_create_dib_section(surface);
if (FAILED(hr))
- return WINED3DERR_INVALIDCALL;
+ {
+ if (context)
+ context_release(context);
+ return WINED3DERR_INVALIDCALL;
+ }
if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
|| surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
|| surface->pbo))
surface->resource.map_binding = WINED3D_LOCATION_DIB;
}
- surface_load_location(surface, WINED3D_LOCATION_DIB);
+ surface_load_location(surface, context, WINED3D_LOCATION_DIB);
surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB);
+ if (context)
+ context_release(context);
+
surface->flags |= SFLAG_DCINUSE;
surface->resource.map_count++;
TRACE("Returning dc %p.\n", *dc);
return WINED3D_OK;
-#endif /* STAGING_CSMT */
}
HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
surface->resource.map_count--;
surface->flags &= ~SFLAG_DCINUSE;
-#if defined(STAGING_CSMT)
- wined3d_cs_emit_releasedc(surface->resource.device->cs, surface);
-
- return WINED3D_OK;
-}
-
-static void read_from_framebuffer(struct wined3d_surface *surface,
- struct wined3d_context *old_ctx, DWORD dst_location)
-{
- struct wined3d_device *device = surface->resource.device;
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
- struct wined3d_surface *restore_rt;
-#else /* STAGING_CSMT */
if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
|| (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
+#endif /* STAGING_CSMT */
&& surface->resource.map_binding != WINED3D_LOCATION_DIB))
{
/* The game Salammbo modifies the surface contents without mapping the surface between
* copied back to the DIB in the next getdc call.
*
* The same consideration applies to user memory surfaces. */
- surface_load_location(surface, surface->resource.map_binding);
+ struct wined3d_device *device = surface->resource.device;
+ struct wined3d_context *context = NULL;
+
+ if (device->d3d_initialized)
+ context = context_acquire(device, NULL);
+
+#if defined(STAGING_CSMT)
+ wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding);
+ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB);
+ if (context)
+ context_release(context);
+ }
+}
+
+HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
+{
+ TRACE("surface %p, dc %p.\n", surface, dc);
+
+ if (!(surface->flags & SFLAG_DCINUSE))
+ return WINEDDERR_NODC;
+
+ if (surface->hDC != dc)
+ {
+ WARN("Application tries to release invalid DC %p, surface DC is %p.\n",
+ dc, surface->hDC);
+ return WINEDDERR_NODC;
+ }
+
+ surface->resource.map_count--;
+ surface->flags &= ~SFLAG_DCINUSE;
+
+ wined3d_cs_emit_releasedc(surface->resource.device->cs, surface);
+#else /* STAGING_CSMT */
+ surface_load_location(surface, context, surface->resource.map_binding);
surface_invalidate_location(surface, WINED3D_LOCATION_DIB);
+ if (context)
+ context_release(context);
}
+#endif /* STAGING_CSMT */
return WINED3D_OK;
}
-static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_location)
+static void read_from_framebuffer(struct wined3d_surface *surface,
+ struct wined3d_context *old_ctx, DWORD dst_location)
{
struct wined3d_device *device = surface->resource.device;
const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
-#endif /* STAGING_CSMT */
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *restore_rt = NULL;
BYTE *mem;
BYTE *row, *top, *bottom;
int i;
BOOL srcIsUpsideDown;
struct wined3d_bo_address data;
- UINT row_pitch, slice_pitch;
-
#if defined(STAGING_CSMT)
+ DWORD slice_pitch, pitch;
+
wined3d_resource_get_memory(&surface->resource, dst_location, &data);
+#else /* STAGING_CSMT */
- /* Context_release does not restore the original context in case of
- * nested context_acquire calls. Only read_from_framebuffer and
- * surface_blt_to_drawable use nested context_acquire calls. Manually
- * restore the original context at the end of the function if needed. */
- if (old_ctx->current_rt == surface)
- {
- restore_rt = NULL;
- context = old_ctx;
- }
- else
+ surface_get_memory(surface, &data, dst_location);
+#endif /* STAGING_CSMT */
+
+ if (surface != old_ctx->current_rt)
{
restore_rt = old_ctx->current_rt;
context = context_acquire(device, surface);
}
-#else /* STAGING_CSMT */
- surface_get_memory(surface, &data, dst_location);
-
- context = context_acquire(device, surface);
-#endif /* STAGING_CSMT */
context_apply_blit_state(context, device);
gl_info = context->gl_info;
}
/* Setup pixel store pack state -- to glReadPixels into the correct place */
- wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch);
- gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / surface->resource.format->byte_count);
+#if defined(STAGING_CSMT)
+ wined3d_resource_get_pitch(&surface->resource, &pitch, &slice_pitch);
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, pitch / surface->resource.format->byte_count);
+#else /* STAGING_CSMT */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH,
+ wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count);
+#endif /* STAGING_CSMT */
checkGLcall("glPixelStorei");
gl_info->gl_ops.gl.p_glReadPixels(0, 0,
{
/* glReadPixels returns the image upside down, and there is no way to prevent this.
* Flip the lines in software. */
- UINT pitch, slice_pitch;
-
- wined3d_resource_get_pitch(&surface->resource, &pitch, &slice_pitch);
+#if !defined(STAGING_CSMT)
+ UINT pitch = wined3d_surface_get_pitch(surface);
+#endif /* STAGING_CSMT */
if (!(row = HeapAlloc(GetProcessHeap(), 0, pitch)))
goto error;
checkGLcall("glBindBuffer");
}
-#if defined(STAGING_CSMT)
if (restore_rt)
- {
- context_release(context);
- context = context_acquire(device, restore_rt);
- context_release(context);
- }
-#else /* STAGING_CSMT */
- context_release(context);
-#endif /* STAGING_CSMT */
+ context_restore(context, restore_rt);
}
/* Read the framebuffer contents into a texture. Note that this function
* doesn't do any kind of flipping. Using this on an onscreen surface will
- * result in a flipped D3D texture. */
-void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb)
+ * result in a flipped D3D texture.
+ *
+ * Context activation is done by the caller. This function may temporarily
+ * switch to a different context and restore the original one before return. */
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *old_ctx)
{
struct wined3d_device *device = surface->resource.device;
const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *restore_rt = NULL;
+
+ if (old_ctx->current_rt != surface)
+ {
+ restore_rt = old_ctx->current_rt;
+ context = context_acquire(device, surface);
+ }
- context = context_acquire(device, surface);
gl_info = context->gl_info;
device_invalidate_state(device, STATE_FRAMEBUFFER);
0, 0, 0, 0, surface->resource.width, surface->resource.height);
checkGLcall("glCopyTexSubImage2D");
- context_release(context);
+ if (restore_rt)
+ context_restore(context, restore_rt);
}
void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample)
{
if (multisample)
{
- if (surface->rb_multisample)
- return;
+ DWORD samples;
- gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample);
- gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample);
- gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, surface->resource.multisample_type,
- surface->resource.format->glInternal, surface->pow2Width, surface->pow2Height);
- checkGLcall("glRenderbufferStorageMultisample()");
- TRACE("Created multisample rb %u.\n", surface->rb_multisample);
- }
- else
- {
- if (surface->rb_resolved)
+ if (surface->rb_multisample)
return;
- gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_resolved);
- gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_resolved);
- gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, surface->resource.format->glInternal,
- surface->pow2Width, surface->pow2Height);
- checkGLcall("glRenderbufferStorage()");
- TRACE("Created resolved rb %u.\n", surface->rb_resolved);
- }
-}
-
-#if !defined(STAGING_CSMT)
-void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back)
-{
- if (front->container->level_count != 1 || front->container->layer_count != 1
- || back->container->level_count != 1 || back->container->layer_count != 1)
- ERR("Flip between surfaces %p and %p not supported.\n", front, back);
-
- /* Flip the surface contents */
- /* Flip the DC */
- {
- HDC tmp;
- tmp = front->hDC;
- front->hDC = back->hDC;
- back->hDC = tmp;
- }
-
- /* Flip the DIBsection */
- {
- HBITMAP tmp = front->dib.DIBsection;
- front->dib.DIBsection = back->dib.DIBsection;
- back->dib.DIBsection = tmp;
- }
-
- /* Flip the surface data */
- {
- void* tmp;
-
- tmp = front->dib.bitmap_data;
- front->dib.bitmap_data = back->dib.bitmap_data;
- back->dib.bitmap_data = tmp;
-
- tmp = front->resource.heap_memory;
- front->resource.heap_memory = back->resource.heap_memory;
- back->resource.heap_memory = tmp;
- }
-
- /* Flip the PBO */
- {
- GLuint tmp_pbo = front->pbo;
- front->pbo = back->pbo;
- back->pbo = tmp_pbo;
- }
-
- /* Flip the opengl texture */
- {
- GLuint tmp;
-
- tmp = back->container->texture_rgb.name;
- back->container->texture_rgb.name = front->container->texture_rgb.name;
- front->container->texture_rgb.name = tmp;
-
- tmp = back->container->texture_srgb.name;
- back->container->texture_srgb.name = front->container->texture_srgb.name;
- front->container->texture_srgb.name = tmp;
-
- tmp = back->rb_multisample;
- back->rb_multisample = front->rb_multisample;
- front->rb_multisample = tmp;
-
- tmp = back->rb_resolved;
- back->rb_resolved = front->rb_resolved;
- front->rb_resolved = tmp;
+ /* TODO: Nvidia exposes their Coverage Sample Anti-Aliasing (CSAA) feature
+ * through type == MULTISAMPLE_XX and quality != 0. This could be mapped
+ * to GL_NV_framebuffer_multisample_coverage.
+ *
+ * AMD has a similar feature called Enhanced Quality Anti-Aliasing (EQAA),
+ * but it does not have an equivalent OpenGL extension. */
+ if (surface->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
+ samples = surface->resource.multisample_quality;
+ else
+ samples = surface->resource.multisample_type;
- resource_unload(&back->resource);
- resource_unload(&front->resource);
+ gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample);
+ gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ surface->resource.format->glInternal, surface->pow2Width, surface->pow2Height);
+ checkGLcall("glRenderbufferStorageMultisample()");
+ TRACE("Created multisample rb %u.\n", surface->rb_multisample);
}
-
+ else
{
- DWORD tmp_flags = back->flags;
- back->flags = front->flags;
- front->flags = tmp_flags;
+ if (surface->rb_resolved)
+ return;
- tmp_flags = back->locations;
- back->locations = front->locations;
- front->locations = tmp_flags;
+ gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_resolved);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_resolved);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, surface->resource.format->glInternal,
+ surface->pow2Width, surface->pow2Height);
+ checkGLcall("glRenderbufferStorage()");
+ TRACE("Created resolved rb %u.\n", surface->rb_resolved);
}
}
-#endif /* STAGING_CSMT */
/* Does a direct frame buffer -> texture copy. Stretching is done with single
* pixel copy calls. */
static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
rect->bottom = drawable_height - rect->bottom;
}
-#if defined(STAGING_CSMT)
/* Context activation is done by the caller. */
static void surface_blt_to_drawable(const struct wined3d_device *device,
struct wined3d_context *old_ctx,
struct wined3d_surface *dst_surface, const RECT *dst_rect_in)
{
const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
- struct wined3d_surface *restore_rt;
+ struct wined3d_context *context = old_ctx;
+ struct wined3d_surface *restore_rt = NULL;
RECT src_rect, dst_rect;
src_rect = *src_rect_in;
dst_rect = *dst_rect_in;
- /* Context_release does not restore the original context in case of
- * nested context_acquire calls. Only read_from_framebuffer and
- * surface_blt_to_drawable use nested context_acquire calls. Manually
- * restore the original context at the end of the function if needed. */
- if (old_ctx->current_rt == dst_surface)
- {
- restore_rt = NULL;
- context = old_ctx;
- }
- else
+
+ if (old_ctx->current_rt != dst_surface)
{
restore_rt = old_ctx->current_rt;
context = context_acquire(device, dst_surface);
}
+
gl_info = context->gl_info;
+#if defined(STAGING_CSMT)
/* Make sure the surface is up-to-date. This should probably use
* wined3d_resource_load_location() and worry about the destination
* surface too, unless we're overwriting it completely. */
#else /* STAGING_CSMT */
-static void surface_blt_to_drawable(const struct wined3d_device *device,
- enum wined3d_texture_filter_type filter, BOOL alpha_test,
- struct wined3d_surface *src_surface, const RECT *src_rect_in,
- struct wined3d_surface *dst_surface, const RECT *dst_rect_in)
-{
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
- RECT src_rect, dst_rect;
-
- src_rect = *src_rect_in;
- dst_rect = *dst_rect_in;
-
- context = context_acquire(device, dst_surface);
- gl_info = context->gl_info;
-
/* 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. */
if (wined3d_settings.cs_multithreaded)
gl_info->gl_ops.gl.p_glFinish();
else if (wined3d_settings.strict_draw_ordering
- || (dst_surface->container->swapchain
- && dst_surface->container->swapchain->front_buffer == dst_surface->container))
- gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
-
- if (restore_rt)
- {
- context_release(context);
- context = context_acquire(device, restore_rt);
- context_release(context);
- }
#else /* STAGING_CSMT */
if (wined3d_settings.strict_draw_ordering
+#endif /* STAGING_CSMT */
|| (dst_surface->container->swapchain
&& dst_surface->container->swapchain->front_buffer == dst_surface->container))
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
- context_release(context);
-#endif /* STAGING_CSMT */
+ if (restore_rt)
+ context_restore(context, restore_rt);
}
HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color)
struct wined3d_device *device = surface->resource.device;
GLsizei w, h;
- TRACE("surface %p, new location %#x.\n", surface, location);
+ TRACE("surface %p, context %p, new location %#x.\n", surface, context, location);
/* TODO: Make this work for modes other than FBO */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return;
gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
gl_info->gl_ops.gl.p_glBindTexture(bind_target, old_binding);
context_apply_fbo_state_blit(context, GL_FRAMEBUFFER,
FIXME("Can't load surface %p with location flags %s into sysmem.\n",
surface, wined3d_debug_location(surface->resource.locations));
-}
-
-/* Context activation is done by the caller. */
-static HRESULT surface_load_drawable(struct wined3d_surface *surface,
- struct wined3d_context *context)
-{
- RECT r;
-
- if (surface->resource.locations & WINED3D_LOCATION_DISCARDED)
- {
- TRACE("Surface was discarded, nothing to do.\n");
- return WINED3D_OK;
- }
#else /* STAGING_CSMT */
surface->locations |= location;
surface->ds_current_size.cx = surface->resource.width;
memcpy(dst.addr, src.addr, size);
}
+/* Context activation is done by the caller. */
static void surface_load_sysmem(struct wined3d_surface *surface,
- const struct wined3d_gl_info *gl_info, DWORD dst_location)
+ struct wined3d_context *context, DWORD dst_location)
{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
if (surface->locations & surface_simple_locations)
{
surface_copy_simple_location(surface, dst_location);
}
if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
- surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB);
+ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
/* Download the surface to system memory. */
if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
- struct wined3d_device *device = surface->resource.device;
- struct wined3d_context *context;
-
- /* TODO: Use already acquired context when possible. */
- context = context_acquire(device, NULL);
-
wined3d_texture_bind_and_dirtify(surface->container, context,
!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB));
surface_download_data(surface, gl_info, dst_location);
- context_release(context);
-
return;
}
if (surface->locations & WINED3D_LOCATION_DRAWABLE)
{
- read_from_framebuffer(surface, dst_location);
+ read_from_framebuffer(surface, context, dst_location);
return;
}
FIXME("Can't load surface %p with location flags %s into sysmem.\n",
surface, wined3d_debug_location(surface->locations));
+#endif /* STAGING_CSMT */
}
+/* Context activation is done by the caller. */
static HRESULT surface_load_drawable(struct wined3d_surface *surface,
- const struct wined3d_gl_info *gl_info)
+ struct wined3d_context *context)
{
RECT r;
-#endif /* STAGING_CSMT */
+#if defined(STAGING_CSMT)
+ if (surface->resource.locations & WINED3D_LOCATION_DISCARDED)
+ {
+ TRACE("Surface was discarded, nothing to do.\n");
+ return WINED3D_OK;
+ }
+
+#endif /* STAGING_CSMT */
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
&& wined3d_resource_is_offscreen(&surface->container->resource))
{
surface_get_rect(surface, NULL, &r);
#if defined(STAGING_CSMT)
wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB);
+#else /* STAGING_CSMT */
+ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
+#endif /* STAGING_CSMT */
surface_blt_to_drawable(surface->resource.device, context,
WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r);
struct wined3d_device *device = surface->resource.device;
const struct wined3d_color_key_conversion *conversion;
struct wined3d_texture *texture = surface->container;
+#if defined(STAGING_CSMT)
UINT width, src_row_pitch, src_slice_pitch, dst_pitch;
struct wined3d_bo_address data;
struct wined3d_format format;
&& wined3d_resource_is_offscreen(&texture->resource)
&& (surface->resource.locations & WINED3D_LOCATION_DRAWABLE))
{
- surface_load_fb_texture(surface, srgb);
+ surface_load_fb_texture(surface, srgb, context);
return WINED3D_OK;
}
if (surface->resource.locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
- && (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
- && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
- NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
- NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
- {
- if (srgb)
- surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
- &src_rect, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect);
- else
- surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB,
- &src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect);
-
- return WINED3D_OK;
- }
-
- if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)
- && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))
- && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
- NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
- NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
- {
- DWORD src_location = surface->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 rect = {0, 0, surface->resource.width, surface->resource.height};
-
- surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location,
#else /* STAGING_CSMT */
- surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB);
- surface_blt_to_drawable(surface->resource.device,
- WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r);
-
- return WINED3D_OK;
-}
-
-static HRESULT surface_load_texture(struct wined3d_surface *surface,
- const struct wined3d_gl_info *gl_info, BOOL srgb)
-{
- RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
- struct wined3d_device *device = surface->resource.device;
- const struct wined3d_color_key_conversion *conversion;
- struct wined3d_texture *texture = surface->container;
- struct wined3d_context *context;
- UINT width, src_row_pitch, src_slice_pitch, dst_pitch;
+ UINT width, src_pitch, dst_pitch;
struct wined3d_bo_address data;
struct wined3d_format format;
POINT dst_point = {0, 0};
&& wined3d_resource_is_offscreen(&texture->resource)
&& (surface->locations & WINED3D_LOCATION_DRAWABLE))
{
- surface_load_fb_texture(surface, srgb);
+ surface_load_fb_texture(surface, srgb, context);
return WINED3D_OK;
}
if (surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
+#endif /* STAGING_CSMT */
&& (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
&& fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
{
if (srgb)
- surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
+ surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
&src_rect, surface, WINED3D_LOCATION_TEXTURE_SRGB, &src_rect);
else
- surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB,
+ surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_SRGB,
&src_rect, surface, WINED3D_LOCATION_TEXTURE_RGB, &src_rect);
return WINED3D_OK;
}
+#if defined(STAGING_CSMT)
+ if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)
+ && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))
+ && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
+ {
+ DWORD src_location = surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED ?
+#else /* STAGING_CSMT */
if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)
&& (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))
&& fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
{
DWORD src_location = surface->locations & WINED3D_LOCATION_RB_RESOLVED ?
+#endif /* STAGING_CSMT */
WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE;
DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
RECT rect = {0, 0, surface->resource.width, surface->resource.height};
- surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, src_location,
-#endif /* STAGING_CSMT */
+ surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, src_location,
&rect, surface, dst_location, &rect);
return WINED3D_OK;
wined3d_resource_prepare_system_memory(&surface->resource);
wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_SYSMEM);
}
+
+ wined3d_texture_prepare_texture(texture, context, srgb);
+ wined3d_texture_bind_and_dirtify(texture, context, srgb);
+
+ width = surface->resource.width;
+ wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch);
#else /* STAGING_CSMT */
if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_RGB)
/* Performance warning... */
FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface);
surface_prepare_map_memory(surface);
- surface_load_location(surface, surface->resource.map_binding);
+ surface_load_location(surface, context, surface->resource.map_binding);
}
}
else
/* Performance warning... */
FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface);
surface_prepare_map_memory(surface);
- surface_load_location(surface, surface->resource.map_binding);
+ surface_load_location(surface, context, surface->resource.map_binding);
}
}
WARN("Trying to load a texture from sysmem, but no simple location is valid.\n");
/* Lets hope we get it from somewhere... */
surface_prepare_system_memory(surface);
- surface_load_location(surface, WINED3D_LOCATION_SYSMEM);
+ surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM);
}
- /* TODO: Use already acquired context when possible. */
- context = context_acquire(device, NULL);
-#endif /* STAGING_CSMT */
-
wined3d_texture_prepare_texture(texture, context, srgb);
wined3d_texture_bind_and_dirtify(texture, context, srgb);
width = surface->resource.width;
- wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch);
+ src_pitch = wined3d_surface_get_pitch(surface);
+#endif /* STAGING_CSMT */
format = *texture->resource.format;
if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data);
#else /* STAGING_CSMT */
surface_prepare_map_memory(surface);
- surface_load_location(surface, surface->resource.map_binding);
+ surface_load_location(surface, context, surface->resource.map_binding);
surface_remove_pbo(surface, gl_info);
}
context_release(context);
return E_OUTOFMEMORY;
}
+#if defined(STAGING_CSMT)
format.convert(data.addr, mem, src_row_pitch, src_row_pitch * height,
dst_pitch, dst_pitch * height, width, height, 1);
src_row_pitch = dst_pitch;
+#else /* STAGING_CSMT */
+ format.convert(data.addr, mem, src_pitch, src_pitch * height,
+ dst_pitch, dst_pitch * height, width, height, 1);
+ src_pitch = dst_pitch;
+#endif /* STAGING_CSMT */
data.addr = mem;
}
else if (conversion)
}
if (texture->swapchain && texture->swapchain->palette)
palette = texture->swapchain->palette;
+#if defined(STAGING_CSMT)
conversion->convert(data.addr, src_row_pitch, mem, dst_pitch,
width, height, palette, &texture->async.gl_color_key);
src_row_pitch = dst_pitch;
wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
+#else /* STAGING_CSMT */
+ conversion->convert(data.addr, src_pitch, mem, dst_pitch,
+ width, height, palette, &texture->async.gl_color_key);
+ src_pitch = dst_pitch;
+ data.addr = mem;
+ }
+
+ wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
+ src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
+#endif /* STAGING_CSMT */
-#if defined(STAGING_CSMT)
HeapFree(GetProcessHeap(), 0, mem);
return WINED3D_OK;
{
RECT rect = {0, 0, surface->resource.width, surface->resource.height};
+#if defined(STAGING_CSMT)
if (!(surface->resource.locations & WINED3D_LOCATION_RB_MULTISAMPLE))
+#else /* STAGING_CSMT */
+ if (!(surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE))
+#endif /* STAGING_CSMT */
ERR("Trying to resolve multisampled surface %p, but location WINED3D_LOCATION_RB_MULTISAMPLE not current.\n",
surface);
surface, WINED3D_LOCATION_RB_MULTISAMPLE, &rect, surface, WINED3D_LOCATION_RB_RESOLVED, &rect);
}
+#if defined(STAGING_CSMT)
/* Context activation is done by the caller. */
static void wined3d_surface_load_location(struct wined3d_resource *resource,
struct wined3d_context *context, DWORD location)
{
struct wined3d_surface *surface = surface_from_resource(resource);
#else /* STAGING_CSMT */
- context_release(context);
-
- HeapFree(GetProcessHeap(), 0, mem);
-
- return WINED3D_OK;
-}
-
-static void surface_multisample_resolve(struct wined3d_surface *surface)
-{
- RECT rect = {0, 0, surface->resource.width, surface->resource.height};
-
- if (!(surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE))
- ERR("Trying to resolve multisampled surface %p, but location WINED3D_LOCATION_RB_MULTISAMPLE not current.\n",
- surface);
-
- surface_blt_fbo(surface->resource.device, WINED3D_TEXF_POINT,
- surface, WINED3D_LOCATION_RB_MULTISAMPLE, &rect, surface, WINED3D_LOCATION_RB_RESOLVED, &rect);
-}
-
-HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location)
+/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */
+HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location)
{
- struct wined3d_device *device = surface->resource.device;
- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
#endif /* STAGING_CSMT */
HRESULT hr;
#else /* STAGING_CSMT */
&& surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED))
{
- struct wined3d_context *context = context_acquire(device, NULL);
surface_load_ds_location(surface, context, location);
- context_release(context);
return WINED3D_OK;
}
else if (location & surface->locations
case WINED3D_LOCATION_USER_MEMORY:
case WINED3D_LOCATION_SYSMEM:
case WINED3D_LOCATION_BUFFER:
-#if defined(STAGING_CSMT)
surface_load_sysmem(surface, context, location);
break;
case WINED3D_LOCATION_DRAWABLE:
if (FAILED(hr = surface_load_drawable(surface, context)))
+#if defined(STAGING_CSMT)
return;
+#else /* STAGING_CSMT */
+ return hr;
+#endif /* STAGING_CSMT */
break;
case WINED3D_LOCATION_RB_RESOLVED:
case WINED3D_LOCATION_TEXTURE_SRGB:
if (FAILED(hr = surface_load_texture(surface, context,
location == WINED3D_LOCATION_TEXTURE_SRGB)))
+#if defined(STAGING_CSMT)
return;
#else /* STAGING_CSMT */
- surface_load_sysmem(surface, gl_info, location);
- break;
-
- case WINED3D_LOCATION_DRAWABLE:
- if (FAILED(hr = surface_load_drawable(surface, gl_info)))
- return hr;
- break;
-
- case WINED3D_LOCATION_RB_RESOLVED:
- surface_multisample_resolve(surface);
- break;
-
- case WINED3D_LOCATION_TEXTURE_RGB:
- case WINED3D_LOCATION_TEXTURE_SRGB:
- if (FAILED(hr = surface_load_texture(surface, gl_info, location == WINED3D_LOCATION_TEXTURE_SRGB)))
return hr;
#endif /* STAGING_CSMT */
break;
struct wined3d_surface *dst_surface, const RECT *dst_rect,
const struct wined3d_color_key *color_key)
{
+ struct wined3d_context *context;
+
/* Blit from offscreen surface to render target */
struct wined3d_color_key old_blt_key = src_surface->container->async.src_blt_color_key;
DWORD old_color_key_flags = src_surface->container->async.color_key_flags;
-#if defined(STAGING_CSMT)
- struct wined3d_context *context;
TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT,
(old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL);
+#if defined(STAGING_CSMT)
wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding);
wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding);
#else /* STAGING_CSMT */
-
- TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
-
- wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, color_key);
-
- surface_blt_to_drawable(device, filter,
- !!color_key, src_surface, src_rect, dst_surface, dst_rect);
-
- /* Restore the color key parameters */
- wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT,
- (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL);
-
surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding);
surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding);
#endif /* STAGING_CSMT */
struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter)
{
+#if defined(STAGING_CSMT)
int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
const struct wined3d_format *src_format, *dst_format;
unsigned int src_fmt_flags, dst_fmt_flags;
struct wined3d_texture *src_texture = NULL;
-#if defined(STAGING_CSMT)
void *src_data = NULL, *dst_data = NULL;
UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch;
const BYTE *sbase = NULL;
src_data = dst_data;
src_row_pitch = dst_row_pitch;
#else /* STAGING_CSMT */
+ const struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
+ int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
+ const struct wined3d_format *src_format, *dst_format;
+ unsigned int src_fmt_flags, dst_fmt_flags;
+ struct wined3d_texture *src_texture = NULL;
struct wined3d_map_desc dst_map, src_map;
const BYTE *sbase = NULL;
HRESULT hr = WINED3D_OK;
wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch);
dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0);
#else /* STAGING_CSMT */
- wined3d_surface_map(dst_surface, &dst_map, dst_rect, 0);
+ wined3d_surface_map(dst_surface, &dst_map, &dst_box, 0);
#endif /* STAGING_CSMT */
}
goto release;
}
- if (!surface_check_block_align(src_surface, src_rect))
+ if (!surface_check_block_align_rect(src_surface, src_rect))
{
WARN("Source rectangle not block-aligned.\n");
hr = WINED3DERR_INVALIDCALL;
goto release;
}
- if (!surface_check_block_align(dst_surface, dst_rect))
+ if (!surface_check_block_align_rect(dst_surface, dst_rect))
{
WARN("Destination rectangle not block-aligned.\n");
hr = WINED3DERR_INVALIDCALL;
| WINEDDBLT_DONOTWAIT;
#if !defined(STAGING_CSMT)
- TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n",
+ TRACE("dst_surface %p, dst_rect_in %s, src_surface %p, src_rect_in %s, flags %#x, fx %p, filter %s.\n",
dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in),
flags, fx, debug_d3dtexturefiltertype(filter));
TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage));
if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect)))
{
if (!wined3d_resource_is_offscreen(&dst_surface->container->resource))
- surface_load_location(dst_surface, dst_surface->container->resource.draw_binding);
+ {
+ struct wined3d_context *context = context_acquire(device, dst_surface);
+ surface_load_location(dst_surface, context, dst_surface->container->resource.draw_binding);
+ context_release(context);
+ }
return WINED3D_OK;
#endif /* STAGING_CSMT */
}
struct wined3d_device *device = dst_surface->resource.device;
RECT src_rect, dst_rect;
- TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n",
+ TRACE("dst_surface %p, dst_rect_in %s, src_surface %p, src_rect_in %s, flags %#x, fx %p, filter %s.\n",
dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in),
flags, fx, debug_d3dtexturefiltertype(filter));
TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage));
return WINEDDERR_INVALIDRECT;
}
- dst_ds_flags = dst_surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
- src_ds_flags = src_surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
+ dst_ds_flags = dst_surface->container->resource.format_flags
+ & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
+ src_ds_flags = src_surface->container->resource.format_flags
+ & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
if (src_ds_flags != dst_ds_flags)
{
WARN("Rejecting depth / stencil blit between incompatible formats.\n");
memset(&src_rect, 0, sizeof(src_rect));
}
+ /* FIXME: We should select the blitter in the main thread, that way we can return an error if the blit
+ * is unsupported without duplicating all the checks... */
+ if (flags & WINEDDBLT_COLORFILL && (dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS))
+ {
+ WARN("Block color fill, returning WINED3DERR_INVALIDCALL\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
if (!fx || !(fx->dwDDFX))
flags &= ~WINEDDBLT_DDFX;
surface_resource_incref,
surface_resource_decref,
surface_unload,
+ surface_resource_sub_resource_map,
+ surface_resource_sub_resource_unmap,
wined3d_surface_location_invalidated,
wined3d_surface_load_location,
};
&src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format,
&dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format))
{
+ struct wined3d_context *context;
TRACE("Using FBO blit.\n");
- surface_blt_fbo(device, filter,
+ context = context_acquire(device, NULL);
+ surface_blt_fbo(device, context, filter,
src_surface, src_surface->container->resource.draw_binding, &src_rect,
dst_surface, dst_surface->container->resource.draw_binding, &dst_rect);
+ context_release(context);
+
surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding);
surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding);
unsigned int resource_size;
HRESULT hr;
- if (multisample_quality > 0)
- {
- FIXME("multisample_quality set to %u, substituting 0.\n", multisample_quality);
- multisample_quality = 0;
- }
-
/* Quick lockable sanity check.
* TODO: remove this after surfaces, usage and lockability have been debugged properly
* this function is too deep to need to care about things like this.
}
if (FAILED(hr = device_parent->ops->surface_created(device_parent,
- wined3d_texture_get_parent(container), object, &parent, &parent_ops)))
+ container, layer * container->level_count + level, object, &parent, &parent_ops)))
{
WARN("Failed to create surface parent, hr %#x.\n", hr);
wined3d_surface_destroy(object);
}
HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapchain *swapchain,
- struct wined3d_surface *dst_surface)
+ struct wined3d_texture *dst_texture, unsigned int sub_resource_idx)
{
- struct wined3d_surface *src_surface;
+ struct wined3d_surface *src_surface, *dst_surface;
+ struct wined3d_resource *sub_resource;
RECT src_rect, dst_rect;
- TRACE("swapchain %p, dst_surface %p.\n", swapchain, dst_surface);
+ TRACE("swapchain %p, dst_texture %p, sub_resource_idx %u.\n", swapchain, dst_texture, sub_resource_idx);
+ if (!(sub_resource = wined3d_texture_get_sub_resource(dst_texture, sub_resource_idx)) ||
+ sub_resource->type != WINED3D_RTYPE_SURFACE)
+ return WINED3DERR_INVALIDCALL;
+
+ dst_surface = surface_from_resource(sub_resource);
src_surface = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0));
SetRect(&src_rect, 0, 0, src_surface->resource.width, src_surface->resource.height);
dst_rect = src_rect;
return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
}
-struct wined3d_surface * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
- UINT back_buffer_idx, enum wined3d_backbuffer_type type)
+struct wined3d_texture * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
+ UINT back_buffer_idx)
{
- TRACE("swapchain %p, back_buffer_idx %u, type %#x.\n",
- swapchain, back_buffer_idx, type);
+ TRACE("swapchain %p, back_buffer_idx %u.\n",
+ swapchain, back_buffer_idx);
/* Return invalid if there is no backbuffer array, otherwise it will
* crash when ddraw is used (there swapchain->back_buffers is always
TRACE("Returning back buffer %p.\n", swapchain->back_buffers[back_buffer_idx]);
- return surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[back_buffer_idx], 0));
+ return swapchain->back_buffers[back_buffer_idx];
}
HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
#if defined(STAGING_CSMT)
wined3d_resource_load_location(&backbuffer->resource, context, location);
#else /* STAGING_CSMT */
- surface_load_location(backbuffer, location);
+ surface_load_location(backbuffer, context, location);
#endif /* STAGING_CSMT */
}
{
wined3d_resource_load_location(&back_buffer->resource, context, back_buffer->container->resource.draw_binding);
#else /* STAGING_CSMT */
- surface_load_location(back_buffer, WINED3D_LOCATION_TEXTURE_RGB);
+ surface_load_location(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_invalidate_location(back_buffer, WINED3D_LOCATION_DRAWABLE);
swapchain->render_to_fbo = TRUE;
swapchain_update_draw_bindings(swapchain);
}
else
{
- surface_load_location(back_buffer, back_buffer->container->resource.draw_binding);
+ surface_load_location(back_buffer, context, back_buffer->container->resource.draw_binding);
#endif /* STAGING_CSMT */
}
}
front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0));
+
#if defined(STAGING_CSMT)
wined3d_resource_validate_location(&front->resource, WINED3D_LOCATION_DRAWABLE);
wined3d_resource_invalidate_location(&front->resource, ~WINED3D_LOCATION_DRAWABLE);
depth_stencil->resource.width, depth_stencil->resource.height);
if (depth_stencil == swapchain->device->cs->onscreen_depth_stencil)
{
- wined3d_surface_decref(swapchain->device->cs->onscreen_depth_stencil);
+ wined3d_texture_decref(swapchain->device->cs->onscreen_depth_stencil->container);
swapchain->device->cs->onscreen_depth_stencil = NULL;
#else /* STAGING_CSMT */
- if (!swapchain->render_to_fbo && ((front->locations & WINED3D_LOCATION_SYSMEM)
- || (back_buffer->locations & WINED3D_LOCATION_SYSMEM)))
- {
- /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
- * Doesn't work with render_to_fbo because we're not flipping
- */
-
- if (front->resource.size == back_buffer->resource.size)
- {
- flip_surface(front, back_buffer);
-
- /* Tell the front buffer surface that is has been modified. However,
- * the other locations were preserved during that, so keep the flags.
- * This serves to update the emulated overlay, if any. */
- surface_validate_location(front, WINED3D_LOCATION_DRAWABLE);
- }
- else
- {
- surface_validate_location(front, WINED3D_LOCATION_DRAWABLE);
- surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE);
- surface_validate_location(back_buffer, WINED3D_LOCATION_DRAWABLE);
- surface_invalidate_location(back_buffer, ~WINED3D_LOCATION_DRAWABLE);
- }
- }
- else
- {
- surface_validate_location(front, WINED3D_LOCATION_DRAWABLE);
- surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE);
- /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
- * and INTEXTURE copies can keep their old content if they have any defined content.
- * If the swapeffect is COPY, the content remains the same. If it is FLIP however,
- * the texture / sysmem copy needs to be reloaded from the drawable
- */
- if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP)
- {
- surface_validate_location(back_buffer, back_buffer->container->resource.draw_binding);
- surface_invalidate_location(back_buffer, ~back_buffer->container->resource.draw_binding);
- }
- }
+ surface_validate_location(front, WINED3D_LOCATION_DRAWABLE);
+ surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE);
+ /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
+ * and INTEXTURE copies can keep their old content if they have any defined content.
+ * If the swapeffect is COPY, the content remains the same.
+ *
+ * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE
+ * up to date and hope WGL flipped front and back buffers and read this data into
+ * the FBO. Don't bother about this for now. */
if (fb->depth_stencil)
{
fb->depth_stencil->width, fb->depth_stencil->height);
if (ds == swapchain->device->onscreen_depth_stencil)
{
- wined3d_surface_decref(swapchain->device->onscreen_depth_stencil);
+ wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container);
swapchain->device->onscreen_depth_stencil = NULL;
#endif /* STAGING_CSMT */
}
#if defined(STAGING_CSMT)
wined3d_resource_load_location(&front->resource, NULL, WINED3D_LOCATION_DIB);
#else /* STAGING_CSMT */
- surface_load_location(front, WINED3D_LOCATION_DIB);
+ surface_load_location(front, NULL, WINED3D_LOCATION_DIB);
#endif /* STAGING_CSMT */
src_dc = front->hDC;
swapchain_gdi_present,
};
-void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain)
+static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain)
{
RECT client_rect;
struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_adapter *adapter = device->adapter;
- struct wined3d_resource_desc surface_desc;
+ struct wined3d_resource_desc texture_desc;
struct wined3d_surface *front_buffer;
BOOL displaymode_set = FALSE;
RECT client_rect;
HRESULT hr;
UINT i;
- if (desc->backbuffer_count > WINED3DPRESENT_BACK_BUFFER_MAX)
- {
- FIXME("The application requested %u back buffers, this is not supported.\n",
- desc->backbuffer_count);
- return WINED3DERR_INVALIDCALL;
- }
-
if (desc->backbuffer_count > 1)
{
FIXME("The application requested more than one back buffer, this is not properly supported.\n"
TRACE("Creating front buffer.\n");
- surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
- surface_desc.format = swapchain->desc.backbuffer_format;
- surface_desc.multisample_type = swapchain->desc.multisample_type;
- surface_desc.multisample_quality = swapchain->desc.multisample_quality;
- surface_desc.usage = 0;
- surface_desc.pool = WINED3D_POOL_DEFAULT;
- surface_desc.width = swapchain->desc.backbuffer_width;
- surface_desc.height = swapchain->desc.backbuffer_height;
- surface_desc.depth = 1;
- surface_desc.size = 0;
-
- if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
- parent, &surface_desc, &front_buffer)))
+ texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ texture_desc.format = swapchain->desc.backbuffer_format;
+ texture_desc.multisample_type = swapchain->desc.multisample_type;
+ texture_desc.multisample_quality = swapchain->desc.multisample_quality;
+ texture_desc.usage = 0;
+ texture_desc.pool = WINED3D_POOL_DEFAULT;
+ texture_desc.width = swapchain->desc.backbuffer_width;
+ texture_desc.height = swapchain->desc.backbuffer_height;
+ texture_desc.depth = 1;
+ texture_desc.size = 0;
+
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
+ parent, &texture_desc, &swapchain->front_buffer)))
{
WARN("Failed to create front buffer, hr %#x.\n", hr);
goto err;
}
- swapchain->front_buffer = front_buffer->container;
wined3d_texture_set_swapchain(swapchain->front_buffer, swapchain);
+ front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0));
if (!(device->wined3d->flags & WINED3D_NO3D))
{
#if defined(STAGING_CSMT)
goto err;
}
- surface_desc.usage |= WINED3DUSAGE_RENDERTARGET;
+ texture_desc.usage |= WINED3DUSAGE_RENDERTARGET;
for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
{
- struct wined3d_surface *back_buffer;
-
TRACE("Creating back buffer %u.\n", i);
- if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
- parent, &surface_desc, &back_buffer)))
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
+ parent, &texture_desc, &swapchain->back_buffers[i])))
{
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
swapchain->desc.backbuffer_count = i;
goto err;
}
- swapchain->back_buffers[i] = back_buffer->container;
wined3d_texture_set_swapchain(swapchain->back_buffers[i], swapchain);
}
}
TRACE("Creating depth/stencil buffer.\n");
if (!device->auto_depth_stencil_view)
{
- struct wined3d_surface *ds;
+ struct wined3d_texture *ds;
+ struct wined3d_rendertarget_view_desc desc;
- surface_desc.format = swapchain->desc.auto_depth_stencil_format;
- surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
+ texture_desc.format = swapchain->desc.auto_depth_stencil_format;
+ texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
- if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
- device->device_parent, &surface_desc, &ds)))
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
+ device->device_parent, &texture_desc, &ds)))
{
WARN("Failed to create the auto depth/stencil surface, hr %#x.\n", hr);
goto err;
}
- hr = wined3d_rendertarget_view_create_from_surface(ds,
- NULL, &wined3d_null_parent_ops, &device->auto_depth_stencil_view);
- wined3d_surface_decref(ds);
+ desc.format_id = ds->resource.format->id;
+ desc.u.texture.level_idx = 0;
+ desc.u.texture.layer_idx = 0;
+ desc.u.texture.layer_count = 1;
+ hr = wined3d_rendertarget_view_create(&desc, &ds->resource, NULL, &wined3d_null_parent_ops,
+ &device->auto_depth_stencil_view);
+ wined3d_texture_decref(ds);
if (FAILED(hr))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
device->filter_messages = filter_messages;
}
+
+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)
+{
+ BOOL update_desc = FALSE;
+
+ TRACE("swapchain %p, buffer_count %u, width %u, height %u, format %s, "
+ "multisample_type %#x, multisample_quality %#x.\n",
+ swapchain, buffer_count, width, height, debug_d3dformat(format_id),
+ multisample_type, multisample_quality);
+
+ if (buffer_count && buffer_count != swapchain->desc.backbuffer_count)
+ FIXME("Cannot change the back buffer count yet.\n");
+
+ if (!width || !height)
+ {
+ /* The application is requesting that either the swapchain width or
+ * height be set to the corresponding dimension in the window's
+ * client rect. */
+
+ RECT client_rect;
+
+ if (!swapchain->desc.windowed)
+ return WINED3DERR_INVALIDCALL;
+
+ if (!GetClientRect(swapchain->device_window, &client_rect))
+ {
+ ERR("Failed to get client rect, last error %#x.\n", GetLastError());
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!width)
+ width = client_rect.right;
+
+ if (!height)
+ height = client_rect.bottom;
+ }
+
+ if (width != swapchain->desc.backbuffer_width
+ || height != swapchain->desc.backbuffer_height)
+ {
+ swapchain->desc.backbuffer_width = width;
+ swapchain->desc.backbuffer_height = height;
+ update_desc = TRUE;
+ }
+
+ if (format_id == WINED3DFMT_UNKNOWN)
+ {
+ if (!swapchain->desc.windowed)
+ return WINED3DERR_INVALIDCALL;
+ format_id = swapchain->original_mode.format_id;
+ }
+
+ if (format_id != swapchain->desc.backbuffer_format)
+ {
+ swapchain->desc.backbuffer_format = format_id;
+ update_desc = TRUE;
+ }
+
+ if (multisample_type != swapchain->desc.multisample_type
+ || multisample_quality != swapchain->desc.multisample_quality)
+ {
+ swapchain->desc.multisample_type = multisample_type;
+ swapchain->desc.multisample_quality = multisample_quality;
+ update_desc = TRUE;
+ }
+
+ if (update_desc)
+ {
+ HRESULT hr;
+ UINT i;
+
+ if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
+ swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
+ swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
+ return hr;
+
+ for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
+ {
+ if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width,
+ swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
+ swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
+ return hr;
+ }
+ }
+
+ swapchain_update_render_to_fbo(swapchain);
+ swapchain_update_draw_bindings(swapchain);
+
+ return WINED3D_OK;
+}
gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT;
gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
}
+
+ if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] && gl_info->supported[ARB_DEPTH_TEXTURE])
+ {
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
+ checkGLcall("glTexParameteri(GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)");
+ }
}
/* Context activation is done by the caller. */
active_sampler = context->rev_tex_unit_map[context->active_texture];
if (active_sampler != WINED3D_UNMAPPED_STAGE)
context_invalidate_state(context, STATE_SAMPLER(active_sampler));
+ /* FIXME: Ideally we'd only do this when touching a binding that's used by
+ * a shader. */
+ context_invalidate_state(context, STATE_SHADER_RESOURCE_BINDING);
wined3d_texture_bind(texture, context, srgb);
}
if (!sampler_desc->compare != !gl_tex->sampler_desc.compare)
{
if (sampler_desc->compare)
- {
- gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- }
else
- {
gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
- }
gl_tex->sampler_desc.compare = sampler_desc->compare;
}
DWORD flag;
UINT i;
- TRACE("texture %p, srgb %#x.\n", texture, srgb);
+ TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
srgb = FALSE;
DWORD flags, const struct wined3d_color_key *color_key)
{
struct wined3d_device *device = texture->resource.device;
- static const DWORD all_flags = WINED3D_CKEY_COLORSPACE | WINED3D_CKEY_DST_BLT
- | WINED3D_CKEY_DST_OVERLAY | WINED3D_CKEY_SRC_BLT | WINED3D_CKEY_SRC_OVERLAY;
+ static const DWORD all_flags = WINED3D_CKEY_DST_BLT | WINED3D_CKEY_DST_OVERLAY
+ | WINED3D_CKEY_SRC_BLT | WINED3D_CKEY_SRC_OVERLAY;
TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key);
return WINED3DERR_INVALIDCALL;
}
- if (flags & WINED3D_CKEY_COLORSPACE)
- {
- FIXME("Unhandled flags %#x.\n", flags);
- return WINED3DERR_INVALIDCALL;
- }
-
-#if defined(STAGING_CSMT)
- /*
- if (wined3d_settings.cs_multithreaded)
- {
- FIXME("waiting for cs\n");
- texture->resource.device->cs->ops->finish(texture->resource.device->cs);
- }
- */
-
-#endif /* STAGING_CSMT */
wined3d_cs_emit_set_color_key(device->cs, texture, flags, color_key);
return WINED3D_OK;
return WINED3D_OK;
}
-static void wined3d_texture_upload_data(struct wined3d_texture *texture, const struct wined3d_sub_resource_data *data)
+static HRESULT wined3d_texture_upload_data(struct wined3d_texture *texture,
+ const struct wined3d_sub_resource_data *data)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
struct wined3d_context *context;
unsigned int i;
+ for (i = 0; i < sub_count; ++i)
+ {
+ if (!data[i].data)
+ {
+ WARN("Invalid sub-resource data specified for sub-resource %u.\n", i);
+ return E_INVALIDARG;
+ }
+ }
+
context = context_acquire(texture->resource.device, NULL);
wined3d_texture_prepare_texture(texture, context, FALSE);
}
context_release(context);
+
+ return WINED3D_OK;
}
static void texture2d_sub_resource_load(struct wined3d_resource *sub_resource,
struct wined3d_context *context, BOOL srgb)
{
-#if defined(STAGING_CSMT)
surface_load(surface_from_resource(sub_resource), context, srgb);
}
struct wined3d_surface *surface = surface_from_resource(sub_resource);
struct wined3d_context *context;
+#if defined(STAGING_CSMT)
context = context_acquire(surface->resource.device, NULL);
wined3d_resource_prepare_map_memory(&surface->resource, context);
wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding);
context_release(context);
wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding);
#else /* STAGING_CSMT */
- surface_load(surface_from_resource(sub_resource), srgb);
-}
-
-static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource,
- const struct wined3d_box *dirty_region)
-{
- struct wined3d_surface *surface = surface_from_resource(sub_resource);
-
surface_prepare_map_memory(surface);
- surface_load_location(surface, surface->resource.map_binding);
+ context = context_acquire(surface->resource.device, NULL);
+ surface_load_location(surface, context, surface->resource.map_binding);
+ context_release(context);
surface_invalidate_location(surface, ~surface->resource.map_binding);
#endif /* STAGING_CSMT */
}
GLenum internal;
UINT i;
- TRACE("texture %p, format %s.\n", texture, debug_d3dformat(format->id));
+ TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
if (format->convert)
{
wined3d_texture_unload_gl_texture(texture);
}
+static HRESULT texture2d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ struct wined3d_resource *sub_resource;
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx)))
+ return E_INVALIDARG;
+
+ return wined3d_surface_map(surface_from_resource(sub_resource), map_desc, box, flags);
+}
+
+static HRESULT texture2d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
+{
+ struct wined3d_resource *sub_resource;
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx)))
+ return E_INVALIDARG;
+
+ return wined3d_surface_unmap(surface_from_resource(sub_resource));
+}
+
#if defined(STAGING_CSMT)
static void wined3d_texture_load_location_invalidated(struct wined3d_resource *resource, DWORD location)
{
ERR("Should not be called on textures.\n");
}
-static const struct wined3d_resource_ops texture_resource_ops =
+#endif /* STAGING_CSMT */
+static const struct wined3d_resource_ops texture2d_resource_ops =
{
texture_resource_incref,
texture_resource_decref,
wined3d_texture_unload,
+ texture2d_resource_sub_resource_map,
+ texture2d_resource_sub_resource_unmap,
+#if defined(STAGING_CSMT)
wined3d_texture_load_location_invalidated,
wined3d_texture_load_location,
-#else /* STAGING_CSMT */
-static const struct wined3d_resource_ops texture_resource_ops =
-{
- texture_resource_incref,
- texture_resource_decref,
- wined3d_texture_unload,
#endif /* STAGING_CSMT */
};
}
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, desc,
- surface_flags, device, parent, parent_ops, &texture_resource_ops)))
+ surface_flags, device, parent, parent_ops, &texture2d_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x\n", hr);
#if defined(STAGING_CSMT)
}
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, desc,
- surface_flags, device, parent, parent_ops, &texture_resource_ops)))
+ surface_flags, device, parent, parent_ops, &texture2d_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
#if defined(STAGING_CSMT)
struct wined3d_const_bo_address addr;
unsigned int row_pitch, slice_pitch;
+#if defined(STAGING_CSMT)
wined3d_resource_get_pitch(sub_resource, &row_pitch, &slice_pitch);
+#else /* STAGING_CSMT */
+ wined3d_volume_get_pitch(volume, &row_pitch, &slice_pitch);
+#endif /* STAGING_CSMT */
if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch)
FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch);
texture3d_prepare_texture,
};
+static HRESULT texture3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ struct wined3d_resource *sub_resource;
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx)))
+ return E_INVALIDARG;
+
+ return wined3d_volume_map(volume_from_resource(sub_resource), map_desc, box, flags);
+}
+
+static HRESULT texture3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
+{
+ struct wined3d_resource *sub_resource;
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx)))
+ return E_INVALIDARG;
+
+ return wined3d_volume_unmap(volume_from_resource(sub_resource));
+}
+
+static const struct wined3d_resource_ops texture3d_resource_ops =
+{
+ texture_resource_incref,
+ texture_resource_decref,
+ wined3d_texture_unload,
+ texture3d_resource_sub_resource_map,
+ texture3d_resource_sub_resource_unmap,
+};
+
static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
UINT levels, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops)
{
}
if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, desc,
- 0, device, parent, parent_ops, &texture_resource_ops)))
+ 0, device, parent, parent_ops, &texture3d_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
#if defined(STAGING_CSMT)
return WINED3D_OK;
}
+HRESULT CDECL wined3d_texture_blt(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_in, DWORD flags,
+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter)
+{
+ struct wined3d_resource *dst_resource, *src_resource = NULL;
+
+ TRACE("dst_texture %p, dst_sub_resource_idx %u, src_texture %p, src_sub_resource_idx %u.\n",
+ dst_texture, dst_sub_resource_idx, src_texture, src_sub_resource_idx);
+
+ if (!(dst_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx))
+ || dst_resource->type != WINED3D_RTYPE_SURFACE)
+ return WINED3DERR_INVALIDCALL;
+
+ if (src_texture)
+ {
+ if (!(src_resource = wined3d_texture_get_sub_resource(src_texture, src_sub_resource_idx))
+ || src_resource->type != WINED3D_RTYPE_SURFACE)
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return wined3d_surface_blt(surface_from_resource(dst_resource), dst_rect_in,
+ src_resource ? surface_from_resource(src_resource) : NULL, src_rect_in, flags, fx, filter);
+}
+
HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
/* FIXME: We'd like to avoid ever allocating system memory for the texture
* in this case. */
- if (data)
- wined3d_texture_upload_data(object, data);
+ if (data && FAILED(hr = wined3d_texture_upload_data(object, data)))
+ {
+ wined3d_texture_cleanup(object);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
TRACE("Created texture %p.\n", object);
*texture = object;
return WINED3D_OK;
}
+
+HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc)
+{
+ struct wined3d_resource *sub_resource;
+
+ TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ if (sub_resource->type != WINED3D_RTYPE_SURFACE)
+ {
+ WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return wined3d_surface_getdc(surface_from_resource(sub_resource), dc);
+}
+
+HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
+{
+ struct wined3d_resource *sub_resource;
+
+ TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ if (sub_resource->type != WINED3D_RTYPE_SURFACE)
+ {
+ WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return wined3d_surface_releasedc(surface_from_resource(sub_resource), dc);
+}
{WINED3DFMT_R10G10B10A2_UINT, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
{WINED3DFMT_R10G10B10A2_SNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
{WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_R8G8B8A8_UNORM_SRGB, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
{WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
{WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0},
{WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
for (x = 0; x < width; x++ )
{
unsigned char color = (*Source++);
- /* A */ Dest[1] = (color & 0xf0) << 0;
- /* L */ Dest[0] = (color & 0x0f) << 4;
+ /* A */ Dest[1] = (color & 0xf0u) << 0;
+ /* L */ Dest[0] = (color & 0x0fu) << 4;
Dest += 2;
}
}
texel_in = (const unsigned short *)(src + z * src_slice_pitch + y * src_row_pitch);
for (x = 0; x < width; x++ )
{
- l_in = (*texel_in & 0xfc00) >> 10;
- g_in = (*texel_in & 0x03e0) >> 5;
- r_in = *texel_in & 0x001f;
+ l_in = (*texel_in & 0xfc00u) >> 10;
+ g_in = (*texel_in & 0x03e0u) >> 5;
+ r_in = *texel_in & 0x001fu;
*texel_out = ((r_in + 16) << 11) | (l_in << 5) | (g_in + 16);
texel_out++;
texel_out = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
- l_in = (*texel_in & 0xfc00) >> 10;
- g_in = (*texel_in & 0x03e0) >> 5;
- r_in = *texel_in & 0x001f;
+ l_in = (*texel_in & 0xfc00u) >> 10;
+ g_in = (*texel_in & 0x03e0u) >> 5;
+ r_in = *texel_in & 0x001fu;
r_out = r_in << 3;
if (!(r_in & 0x10)) /* r > 0 */
texel_out = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
- l_in = (*texel_in & 0xfc00) >> 10;
- g_in = (*texel_in & 0x03e0) >> 5;
- r_in = *texel_in & 0x001f;
+ l_in = (*texel_in & 0xfc00u) >> 10;
+ g_in = (*texel_in & 0x03e0u) >> 5;
+ r_in = *texel_in & 0x001fu;
ds_out = r_in << 3;
if (!(r_in & 0x10)) /* r > 0 */
for (x = 0; x < width; ++x)
{
- dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
+ dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00u) >> 8);
dest_s[x * 2 + 1] = source[x] & 0xff;
}
}
{
WORD src_color = src_row[x];
if (!color_in_range(color_key, src_color))
- dst_row[x] = 0x8000 | ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
+ dst_row[x] = 0x8000u | ((src_color & 0xffc0u) >> 1) | (src_color & 0x1fu);
else
- dst_row[x] = ((src_color & 0xffc0) >> 1) | (src_color & 0x1f);
+ dst_row[x] = ((src_color & 0xffc0u) >> 1) | (src_color & 0x1fu);
}
}
}
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_RENDERTARGET,
WINED3D_GL_EXT_NONE, NULL},
- {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
+ {WINED3DFMT_B5G6R5_UNORM, GL_RGB565, GL_RGB565, GL_RGB8,
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET,
+ ARB_ES2_COMPATIBILITY, NULL},
+ {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5, 0,
GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
WINED3D_GL_EXT_NONE, NULL},
while (gl_info->gl_ops.gl.p_glGetError());
}
+static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d_vec3 *geometry,
+ const struct wined3d_color *color)
+{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ static const struct wined3d_vec3 default_geometry[] =
+ {
+ {-1.0f, -1.0f, 0.0f},
+ { 1.0f, -1.0f, 0.0f},
+ {-1.0f, 1.0f, 0.0f},
+ { 1.0f, 1.0f, 0.0f},
+ };
+ static const char vs_core_header[] =
+ "#version 150\n"
+ "in vec4 pos;\n"
+ "in vec4 color;\n"
+ "out vec4 out_color;\n"
+ "\n";
+ static const char vs_legacy_header[] =
+ "#version 120\n"
+ "attribute vec4 pos;\n"
+ "attribute vec4 color;\n"
+ "varying vec4 out_color;\n"
+ "\n";
+ static const char vs_body[] =
+ "void main()\n"
+ "{\n"
+ " gl_Position = pos;\n"
+ " out_color = color;\n"
+ "}\n";
+ static const char fs_core[] =
+ "#version 150\n"
+ "in vec4 out_color;\n"
+ "out vec4 fragment_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " fragment_color = out_color;\n"
+ "}\n";
+ static const char fs_legacy[] =
+ "#version 120\n"
+ "varying vec4 out_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragData[0] = out_color;\n"
+ "}\n";
+ const char *source[2];
+ GLuint vs_id, fs_id;
+ unsigned int i;
+
+ if (!geometry)
+ geometry = default_geometry;
+
+ if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] || !gl_info->supported[ARB_VERTEX_SHADER]
+ || !gl_info->supported[ARB_FRAGMENT_SHADER])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glColor4f(color->r, color->g, color->b, color->a);
+ for (i = 0; i < 4; ++i)
+ gl_info->gl_ops.gl.p_glVertex3fv(&geometry[i].x);
+ gl_info->gl_ops.gl.p_glEnd();
+ checkGLcall("Drawing a quad");
+ return;
+ }
+
+ if (!ctx->test_vbo)
+ GL_EXTCALL(glGenBuffers(1, &ctx->test_vbo));
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, ctx->test_vbo));
+ GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(struct wined3d_vec3) * 4, geometry, GL_STREAM_DRAW));
+ GL_EXTCALL(glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, 0, NULL));
+ GL_EXTCALL(glVertexAttrib4f(1, color->r, color->g, color->b, color->a));
+ GL_EXTCALL(glEnableVertexAttribArray(0));
+ GL_EXTCALL(glDisableVertexAttribArray(1));
+
+ if (!ctx->test_program_id)
+ {
+ ctx->test_program_id = GL_EXTCALL(glCreateProgram());
+
+ vs_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
+ source[0] = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? vs_legacy_header : vs_core_header;
+ source[1] = vs_body;
+ GL_EXTCALL(glShaderSource(vs_id, 2, source, NULL));
+ GL_EXTCALL(glAttachShader(ctx->test_program_id, vs_id));
+ GL_EXTCALL(glDeleteShader(vs_id));
+
+ fs_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
+ source[0] = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? fs_legacy : fs_core;
+ GL_EXTCALL(glShaderSource(fs_id, 1, source, NULL));
+ GL_EXTCALL(glAttachShader(ctx->test_program_id, fs_id));
+ GL_EXTCALL(glDeleteShader(fs_id));
+
+ GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 0, "pos"));
+ GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 1, "color"));
+
+ GL_EXTCALL(glCompileShader(vs_id));
+ print_glsl_info_log(gl_info, vs_id, FALSE);
+ GL_EXTCALL(glCompileShader(fs_id));
+ print_glsl_info_log(gl_info, fs_id, FALSE);
+ GL_EXTCALL(glLinkProgram(ctx->test_program_id));
+ shader_glsl_validate_link(gl_info, ctx->test_program_id);
+ }
+ GL_EXTCALL(glUseProgram(ctx->test_program_id));
+
+ gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ GL_EXTCALL(glUseProgram(0));
+ GL_EXTCALL(glDisableVertexAttribArray(0));
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
+ checkGLcall("Drawing a quad");
+}
+
/* Context activation is done by the caller. */
-static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
+static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_format *format)
{
/* Check if the default internal format is supported as a frame buffer
* target, otherwise fall back to the render target internal.
*
* Try to stick to the standard format if possible, this limits precision differences. */
+ static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 1.0f};
+ static const struct wined3d_color half_transparent_red = {1.0f, 0.0f, 0.0f, 0.5f};
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
GLenum status, rt_internal = format->rtInternal;
GLuint object, color_rb;
enum wined3d_gl_resource_type type;
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
else
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
- gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
- gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
- gl_info->gl_ops.gl.p_glLoadIdentity();
- gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
- gl_info->gl_ops.gl.p_glLoadIdentity();
-
gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- /* Draw a full-black quad */
- gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
- gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glEnd();
+ draw_test_quad(ctx, NULL, &black);
gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
- /* Draw a half-transparent red quad */
- gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
- gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glEnd();
+
+ draw_test_quad(ctx, NULL, &half_transparent_red);
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
checkGLcall("Post-pixelshader blending check");
a = color >> 24;
- r = (color & 0x00ff0000) >> 16;
+ r = (color & 0x00ff0000u) >> 16;
- r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
- a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
+ r_range = format->red_size < 8 ? 1u << (8 - format->red_size) : 1;
+ a_range = format->alpha_size < 8 ? 1u << (8 - format->alpha_size) : 1;
if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
match = FALSE;
else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
}
/* Context activation is done by the caller. */
-static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
+static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
unsigned int i, type;
GLuint fbo;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
- check_fbo_compat(gl_info, format);
+ check_fbo_compat(ctx, format);
}
else
{
/* This was already handled by init_format_texture_info(). */
return;
- if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ || !gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
{
WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
gl_info->formats[idx].height_scale.denominator = 2;
gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
+ if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+ {
+ idx = getFmtIdx(WINED3DFMT_INTZ);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
+ }
+
if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
{
idx = getFmtIdx(WINED3DFMT_P8_UINT);
}
/* Context activation is done by the caller. */
-BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
+BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx)
{
struct wined3d_gl_info *gl_info = &adapter->gl_info;
if (!init_format_vertex_info(gl_info)) goto fail;
apply_format_fixups(adapter, gl_info);
- init_format_fbo_compat_info(gl_info);
+ init_format_fbo_compat_info(ctx);
init_format_filter_info(gl_info, adapter->driver_info.vendor);
return TRUE;
return FALSE;
}
+float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *ctx, GLenum format)
+{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ static const struct wined3d_color blue = {0.0f, 0.0f, 1.0f, 1.0f};
+ GLuint fbo, color, depth;
+ unsigned int low = 0, high = 32, cur;
+ DWORD readback[256];
+ static const struct wined3d_vec3 geometry[] =
+ {
+ {-1.0f, -1.0f, -1.0f},
+ { 1.0f, -1.0f, 0.0f},
+ {-1.0f, 1.0f, -1.0f},
+ { 1.0f, 1.0f, 0.0f},
+ };
+
+ /* Most drivers want 2^23 for fixed point depth buffers, including r300g, r600g,
+ * Nvidia. Use this as a fallback if the detection fails. */
+ unsigned int fallback = 23;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ {
+ FIXME("No FBOs, assuming polyoffset scale of 2^%u.\n", fallback);
+ return (float)(1u << fallback);
+ }
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &color);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, color);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
+
+ gl_info->fbo_ops.glGenRenderbuffers(1, &depth);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, depth);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format, 256, 1);
+
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
+ checkGLcall("Setup framebuffer");
+
+ gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.5f, 0.0f);
+ gl_info->gl_ops.gl.p_glClearDepth(0.5f);
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
+ gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
+ gl_info->gl_ops.gl.p_glViewport(0, 0, 256, 1);
+ checkGLcall("Misc parameters");
+
+ for (;;)
+ {
+ if (high - low <= 1)
+ {
+ ERR("PolygonOffset scale factor detection failed, using fallback value 2^%u.\n", fallback);
+ cur = fallback;
+ break;
+ }
+ cur = (low + high) / 2;
+
+ gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ /* The post viewport transform Z of the geometry runs from 0.0 to 0.5. We want to push it another
+ * 0.25 so that the Z buffer content (0.5) cuts the quad off at half the screen. */
+ gl_info->gl_ops.gl.p_glPolygonOffset(0.0f, (float)(1u << cur) * 0.25f);
+ draw_test_quad(ctx, geometry, &blue);
+ checkGLcall("Test draw");
+
+ /* Rebinding texture to workaround a fglrx bug. */
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, color);
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
+ checkGLcall("readback");
+
+ TRACE("low %02u, high %02u, cur %2u, 0=0x%08x, 125=0x%08x, 131=0x%08x, 255=0x%08x\n",
+ low, high, cur, readback[0], readback[125], readback[131], readback[255]);
+
+ if ((readback[125] & 0xff) < 0xa0)
+ high = cur;
+ else if ((readback[131] & 0xff) > 0xa0)
+ low = cur;
+ else
+ {
+ TRACE("Found scale factor 2^%u for format %x\n", cur, format);
+ break;
+ }
+ }
+
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &color);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &depth);
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ checkGLcall("Delete framebuffer");
+
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+ gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
+ return (float)(1u << cur);
+}
+
const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
enum wined3d_format_id format_id)
{
compute_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + tex],
state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
generated, context->last_was_rhw,
- context->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))
+ context->stream_info.use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))
? context->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id
: WINED3DFMT_UNKNOWN,
device->shader_backend->shader_has_ffp_proj_control(device->shader_priv), mat);
- if ((context->lastWasPow2Texture & (1 << tex)) && state->textures[tex])
+ if ((context->lastWasPow2Texture & (1u << tex)) && state->textures[tex])
{
if (generated)
FIXME("Non-power-of-two texture being used with generated texture coords.\n");
return count;
}
-/* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
- * The later function requires individual color components. */
-BOOL getColorBits(const struct wined3d_format *format,
- BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
-{
- TRACE("format %s.\n", debug_d3dformat(format->id));
-
- switch (format->id)
- {
- case WINED3DFMT_B10G10R10A2_UNORM:
- case WINED3DFMT_R10G10B10A2_UNORM:
- case WINED3DFMT_B8G8R8X8_UNORM:
- case WINED3DFMT_B8G8R8_UNORM:
- case WINED3DFMT_B8G8R8A8_UNORM:
- case WINED3DFMT_R8G8B8A8_UNORM:
- case WINED3DFMT_B5G5R5X1_UNORM:
- case WINED3DFMT_B5G5R5A1_UNORM:
- case WINED3DFMT_B5G6R5_UNORM:
- case WINED3DFMT_B4G4R4X4_UNORM:
- case WINED3DFMT_B4G4R4A4_UNORM:
- case WINED3DFMT_B2G3R3_UNORM:
- case WINED3DFMT_P8_UINT_A8_UNORM:
- case WINED3DFMT_P8_UINT:
- break;
- default:
- FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
- return FALSE;
- }
-
- *redSize = format->red_size;
- *greenSize = format->green_size;
- *blueSize = format->blue_size;
- *alphaSize = format->alpha_size;
- *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
-
- TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
- *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
- return TRUE;
-}
-
-/* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
-BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
-{
- TRACE("format %s.\n", debug_d3dformat(format->id));
-
- switch (format->id)
- {
- case WINED3DFMT_D16_LOCKABLE:
- case WINED3DFMT_D16_UNORM:
- case WINED3DFMT_S1_UINT_D15_UNORM:
- case WINED3DFMT_X8D24_UNORM:
- case WINED3DFMT_S4X4_UINT_D24_UNORM:
- case WINED3DFMT_D24_UNORM_S8_UINT:
- case WINED3DFMT_S8_UINT_D24_FLOAT:
- case WINED3DFMT_D32_UNORM:
- case WINED3DFMT_D32_FLOAT:
- case WINED3DFMT_INTZ:
- break;
- default:
- FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
- return FALSE;
- }
-
- *depthSize = format->depth_size;
- *stencilSize = format->stencil_size;
-
- TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
- *depthSize, *stencilSize, debug_d3dformat(format->id));
- return TRUE;
-}
-
/* Note: It's the caller's responsibility to ensure values can be expressed
* in the requested format. UNORM formats for example can only express values
* in the range 0.0f -> 1.0f. */
static float color_to_float(DWORD color, DWORD size, DWORD offset)
{
- DWORD mask = (1 << size) - 1;
+ DWORD mask = (1u << size) - 1;
if (!size)
return 1.0f;
}
}
+void wined3d_format_get_float_color_key(const struct wined3d_format *format,
+ const struct wined3d_color_key *key, struct wined3d_color *float_colors)
+{
+ struct wined3d_color slop;
+
+ switch (format->id)
+ {
+ case WINED3DFMT_B8G8R8_UNORM:
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ case WINED3DFMT_B8G8R8X8_UNORM:
+ case WINED3DFMT_B5G6R5_UNORM:
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ case WINED3DFMT_B5G5R5A1_UNORM:
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ case WINED3DFMT_B2G3R3_UNORM:
+ case WINED3DFMT_R8_UNORM:
+ case WINED3DFMT_A8_UNORM:
+ case WINED3DFMT_B2G3R3A8_UNORM:
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ case WINED3DFMT_R10G10B10A2_SNORM:
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ case WINED3DFMT_R8G8B8X8_UNORM:
+ case WINED3DFMT_R16G16_UNORM:
+ case WINED3DFMT_B10G10R10A2_UNORM:
+ slop.r = 0.5f / ((1 << format->red_size) - 1);
+ slop.g = 0.5f / ((1 << format->green_size) - 1);
+ slop.b = 0.5f / ((1 << format->blue_size) - 1);
+ slop.a = 0.5f / ((1 << format->alpha_size) - 1);
+
+ float_colors[0].r = color_to_float(key->color_space_low_value, format->red_size, format->red_offset)
+ - slop.r;
+ float_colors[0].g = color_to_float(key->color_space_low_value, format->green_size, format->green_offset)
+ - slop.g;
+ float_colors[0].b = color_to_float(key->color_space_low_value, format->blue_size, format->blue_offset)
+ - slop.b;
+ float_colors[0].a = color_to_float(key->color_space_low_value, format->alpha_size, format->alpha_offset)
+ - slop.a;
+
+ float_colors[1].r = color_to_float(key->color_space_high_value, format->red_size, format->red_offset)
+ + slop.r;
+ float_colors[1].g = color_to_float(key->color_space_high_value, format->green_size, format->green_offset)
+ + slop.g;
+ float_colors[1].b = color_to_float(key->color_space_high_value, format->blue_size, format->blue_offset)
+ + slop.b;
+ float_colors[1].a = color_to_float(key->color_space_high_value, format->alpha_size, format->alpha_offset)
+ + slop.a;
+ break;
+
+ case WINED3DFMT_P8_UINT:
+ float_colors[0].r = 0.0f;
+ float_colors[0].g = 0.0f;
+ float_colors[0].b = 0.0f;
+ float_colors[0].a = (key->color_space_low_value - 0.5f) / 255.0f;
+
+ float_colors[1].r = 0.0f;
+ float_colors[1].g = 0.0f;
+ float_colors[1].b = 0.0f;
+ float_colors[1].a = (key->color_space_high_value + 0.5f) / 255.0f;
+ break;
+
+ default:
+ ERR("Unhandled color key to float conversion for format %s.\n", debug_d3dformat(format->id));
+ }
+}
+
/* DirectDraw stuff */
enum wined3d_format_id pixelformat_for_depth(DWORD depth)
{
return size;
}
+unsigned int wined3d_max_compat_varyings(const struct wined3d_gl_info *gl_info)
+{
+ /* On core profile we have to also count diffuse and specular colors and the
+ * fog coordinate. */
+ return gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? MAX_TEXTURES * 4 : (MAX_TEXTURES + 2) * 4 + 1;
+}
+
void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
struct ffp_frag_settings *settings, BOOL ignore_textype)
{
settings->color_key_enabled = 1;
else
settings->color_key_enabled = 0;
+
+ /* texcoords_initialized is set to meaningful values only when GL doesn't
+ * support enough varyings to always pass around all the possible texture
+ * coordinates.
+ * This is used to avoid reading a varying not written by the vertex shader.
+ * Reading uninitialized varyings on core profile contexts results in an
+ * error while with builtin varyings on legacy contexts you get undefined
+ * behavior. */
+ if (d3d_info->limits.varying_count
+ && d3d_info->limits.varying_count < wined3d_max_compat_varyings(gl_info))
+ {
+ settings->texcoords_initialized = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ if (use_vs(state))
+ {
+ if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.output_registers & (1u << i))
+ settings->texcoords_initialized |= 1u << i;
+ }
+ else
+ {
+ const struct wined3d_stream_info *si = &context->stream_info;
+ unsigned int coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if ((state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK
+ || (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))))
+ settings->texcoords_initialized |= 1u << i;
+ }
+ }
+ }
+ else
+ {
+ settings->texcoords_initialized = (1u << MAX_TEXTURES) - 1;
+ }
+
+ settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE]
+ && state->gl_primitive_type == GL_POINTS;
+
+ if (d3d_info->emulated_flatshading)
+ settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
+ else
+ settings->flatshading = FALSE;
}
const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
ffp_frag_program_key_compare,
};
-void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
- struct wined3d_ffp_vs_settings *settings)
+void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
+ const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings)
{
+ const struct wined3d_stream_info *si = &context->stream_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
unsigned int coord_idx, i;
if (si->position_transformed)
settings->transformed = 1;
settings->point_size = state->gl_primitive_type == GL_POINTS;
- settings->per_vertex_point_size = !!(si->use_map & 1 << WINED3D_FFP_PSIZE);
+ settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE);
if (!state->render_states[WINED3D_RS_FOGENABLE])
settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
for (i = 0; i < MAX_TEXTURES; ++i)
{
coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
- if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
- settings->texcoords |= 1 << i;
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1u << i;
settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
}
+ if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info))
+ settings->texcoords = (1u << MAX_TEXTURES) - 1;
+
+ if (d3d_info->emulated_flatshading)
+ settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
+ else
+ settings->flatshading = FALSE;
+
return;
}
settings->transformed = 0;
settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE];
- settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
+ settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL));
settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
settings->point_size = state->gl_primitive_type == GL_POINTS;
- settings->per_vertex_point_size = !!(si->use_map & 1 << WINED3D_FFP_PSIZE);
+ settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE);
- if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1u << WINED3D_FFP_DIFFUSE)))
{
settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
settings->emissive_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
for (i = 0; i < MAX_TEXTURES; ++i)
{
coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
- if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
- settings->texcoords |= 1 << i;
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1u << i;
settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
}
+ if (d3d_info->limits.varying_count >= wined3d_max_compat_varyings(gl_info))
+ settings->texcoords = (1u << MAX_TEXTURES) - 1;
settings->light_type = 0;
for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
else
settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+ if (d3d_info->emulated_flatshading)
+ settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
+ else
+ settings->flatshading = FALSE;
+
settings->padding = 0;
}
{
struct wined3d_rendertarget_view *object;
- TRACE("desc %p, resource %p, parent %p, view %p.\n",
- desc, resource, parent, view);
+ TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
+ desc, resource, parent, parent_ops, view);
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
{
struct wined3d_rendertarget_view_desc desc;
- TRACE("surface %p, view %p.\n", surface, view);
+ TRACE("surface %p, parent %p, parent_ops %p, view %p.\n", surface, parent, parent_ops, view);
desc.format_id = surface->resource.format->id;
desc.u.texture.level_idx = surface->texture_level;
return wined3d_rendertarget_view_create(&desc, &surface->container->resource, parent, parent_ops, view);
}
+HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture,
+ unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_rendertarget_view **view)
+{
+ struct wined3d_resource *sub_resource;
+
+ TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n",
+ texture, sub_resource_idx, parent, parent_ops, view);
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ if (sub_resource->type != WINED3D_RTYPE_SURFACE)
+ {
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(texture->resource.type));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return wined3d_rendertarget_view_create_from_surface(surface_from_resource(sub_resource),
+ parent, parent_ops, view);
+}
+
ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view)
{
ULONG refcount = InterlockedIncrement(&view->refcount);
{
struct wined3d_shader_resource_view *object;
- TRACE("parent %p, parent_ops %p, view %p.\n", parent, parent_ops, view);
+ TRACE("resource %p, parent %p, parent_ops %p, view %p.\n", resource, parent, parent_ops, view);
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
return TRUE;
}
+#if !defined(STAGING_CSMT)
+void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch)
+{
+ const struct wined3d_format *format = volume->resource.format;
+
+ if (volume->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+ {
+ /* Since compressed formats are block based, pitch means the amount of
+ * bytes to the next row of block rather than the next row of pixels. */
+ UINT row_block_count = (volume->resource.width + format->block_width - 1) / format->block_width;
+ UINT slice_block_count = (volume->resource.height + format->block_height - 1) / format->block_height;
+ *row_pitch = row_block_count * format->block_byte_count;
+ *slice_pitch = *row_pitch * slice_block_count;
+ }
+ else
+ {
+ unsigned char alignment = volume->resource.device->surface_alignment;
+ *row_pitch = format->byte_count * volume->resource.width; /* Bytes / row */
+ *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1);
+ *slice_pitch = *row_pitch * volume->resource.height;
+ }
+
+ TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch);
+}
+
+#endif /* STAGING_CSMT */
/* This call just uploads data, the caller is responsible for binding the
* correct texture. */
/* Context activation is done by the caller. */
dst_row_pitch = width * format->conv_byte_count;
dst_slice_pitch = dst_row_pitch * height;
+#if defined(STAGING_CSMT)
wined3d_resource_get_pitch(&volume->resource, &src_row_pitch, &src_slice_pitch);
+#else /* STAGING_CSMT */
+ wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch);
+#endif /* STAGING_CSMT */
converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch,
resource_unload(resource);
}
-ULONG CDECL wined3d_volume_incref(struct wined3d_volume *volume)
-{
- TRACE("Forwarding to container %p.\n", volume->container);
-
- return wined3d_texture_incref(volume->container);
-}
-
-#if defined(STAGING_CSMT)
-void wined3d_volume_cleanup_cs(struct wined3d_volume *volume)
-{
- HeapFree(GetProcessHeap(), 0, volume);
-}
-
-#endif /* STAGING_CSMT */
-ULONG CDECL wined3d_volume_decref(struct wined3d_volume *volume)
-{
- TRACE("Forwarding to container %p.\n", volume->container);
-
- return wined3d_texture_decref(volume->container);
-}
-
-void * CDECL wined3d_volume_get_parent(const struct wined3d_volume *volume)
-{
- TRACE("volume %p.\n", volume);
-
- return volume->resource.parent;
-}
-
-void CDECL wined3d_volume_preload(struct wined3d_volume *volume)
-{
- FIXME("volume %p stub!\n", volume);
-}
-
-struct wined3d_resource * CDECL wined3d_volume_get_resource(struct wined3d_volume *volume)
-{
- TRACE("volume %p.\n", volume);
-
- return &volume->resource;
-}
-
#if !defined(STAGING_CSMT)
static BOOL volume_check_block_align(const struct wined3d_volume *volume,
const struct wined3d_box *box)
return TRUE;
}
-HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
+HRESULT wined3d_volume_map(struct wined3d_volume *volume,
struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
{
#if defined(STAGING_CSMT)
WARN("Map box is invalid.\n");
return WINED3DERR_INVALIDCALL;
}
- if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) &&
- !wined3d_resource_check_block_align(&volume->resource, box))
+ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !wined3d_resource_check_block_align(&volume->resource, box))
{
WARN("Map box is misaligned for %ux%u blocks.\n",
format->block_width, format->block_height);
return hr;
return hr;
+}
+
+HRESULT wined3d_volume_unmap(struct wined3d_volume *volume)
+{
+ HRESULT hr;
+
+ if (volume->resource.unmap_dirtify)
+ wined3d_texture_set_dirty(volume->container);
+
+ hr = wined3d_resource_unmap(&volume->resource);
+ if (hr == WINEDDERR_NOTLOCKED)
+ return WINED3DERR_INVALIDCALL;
+ return hr;
#else /* STAGING_CSMT */
struct wined3d_device *device = volume->resource.device;
struct wined3d_context *context;
}
else
{
- wined3d_resource_get_pitch(&volume->resource, &map_desc->row_pitch, &map_desc->slice_pitch);
+ wined3d_volume_get_pitch(volume, &map_desc->row_pitch, &map_desc->slice_pitch);
}
if (!box)
map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
return WINED3D_OK;
-#endif /* STAGING_CSMT */
-}
-
-struct wined3d_volume * CDECL wined3d_volume_from_resource(struct wined3d_resource *resource)
-{
- return volume_from_resource(resource);
}
-HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume)
+HRESULT wined3d_volume_unmap(struct wined3d_volume *volume)
{
-#if defined(STAGING_CSMT)
- HRESULT hr;
-
- if (volume->resource.unmap_dirtify)
- wined3d_texture_set_dirty(volume->container);
-
- hr = wined3d_resource_unmap(&volume->resource);
- if (hr == WINEDDERR_NOTLOCKED)
- return WINED3DERR_INVALIDCALL;
- return hr;
-#else /* STAGING_CSMT */
TRACE("volume %p.\n", volume);
if (!volume->resource.map_count)
static ULONG volume_resource_incref(struct wined3d_resource *resource)
{
- return wined3d_volume_incref(volume_from_resource(resource));
+ struct wined3d_volume *volume = volume_from_resource(resource);
+ TRACE("Forwarding to container %p.\n", volume->container);
+
+ return wined3d_texture_incref(volume->container);
+}
+
+#if defined(STAGING_CSMT)
+void wined3d_volume_cleanup_cs(struct wined3d_volume *volume)
+{
+ HeapFree(GetProcessHeap(), 0, volume);
}
+#endif /* STAGING_CSMT */
static ULONG volume_resource_decref(struct wined3d_resource *resource)
{
- return wined3d_volume_decref(volume_from_resource(resource));
+ struct wined3d_volume *volume = volume_from_resource(resource);
+ TRACE("Forwarding to container %p.\n", volume->container);
+
+ return wined3d_texture_decref(volume->container);
+}
+
+static HRESULT volume_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ ERR("Not supported on sub-resources.\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
+static HRESULT volume_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
+{
+ ERR("Not supported on sub-resources.\n");
+ return WINED3DERR_INVALIDCALL;
}
#if defined(STAGING_CSMT)
wined3d_texture_set_dirty(volume->container);
}
+#endif /* STAGING_CSMT */
static const struct wined3d_resource_ops volume_resource_ops =
{
volume_resource_incref,
volume_resource_decref,
volume_unload,
+ volume_resource_sub_resource_map,
+ volume_resource_sub_resource_unmap,
+#if defined(STAGING_CSMT)
wined3d_volume_location_invalidated,
wined3d_volume_load_location,
-#else /* STAGING_CSMT */
-static const struct wined3d_resource_ops volume_resource_ops =
-{
- volume_resource_incref,
- volume_resource_decref,
- volume_unload,
#endif /* STAGING_CSMT */
};
}
if (FAILED(hr = device_parent->ops->volume_created(device_parent,
- wined3d_texture_get_parent(container), object, &parent, &parent_ops)))
+ container, level, &parent, &parent_ops)))
{
WARN("Failed to create volume parent, hr %#x.\n", hr);
wined3d_volume_destroy(object);
@ cdecl wined3d_device_clear(ptr long ptr long ptr float long)
@ cdecl wined3d_device_clear_rendertarget_view(ptr 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)
@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
@ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_draw_indexed_primitive(ptr long long)
@ cdecl wined3d_device_end_stateblock(ptr ptr)
@ cdecl wined3d_device_evict_managed_resources(ptr)
@ cdecl wined3d_device_get_available_texture_mem(ptr)
-@ cdecl wined3d_device_get_back_buffer(ptr long long long ptr)
@ cdecl wined3d_device_get_base_vertex_index(ptr)
@ cdecl wined3d_device_get_clip_plane(ptr long ptr)
@ cdecl wined3d_device_get_clip_status(ptr ptr)
@ cdecl wined3d_device_get_depth_stencil_view(ptr)
@ cdecl wined3d_device_get_device_caps(ptr ptr)
@ cdecl wined3d_device_get_display_mode(ptr long ptr ptr)
-@ cdecl wined3d_device_get_front_buffer_data(ptr long ptr)
@ cdecl wined3d_device_get_gamma_ramp(ptr long ptr)
@ cdecl wined3d_device_get_geometry_shader(ptr)
@ cdecl wined3d_device_get_gs_cb(ptr long)
@ cdecl wined3d_device_init_3d(ptr ptr)
@ cdecl wined3d_device_init_gdi(ptr ptr)
@ cdecl wined3d_device_multiply_transform(ptr long ptr)
-@ cdecl wined3d_device_present(ptr ptr ptr ptr ptr long)
@ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long)
@ cdecl wined3d_device_release_focus_window(ptr)
@ cdecl wined3d_device_reset(ptr ptr ptr ptr long)
@ cdecl wined3d_device_set_clip_plane(ptr long ptr)
@ cdecl wined3d_device_set_clip_status(ptr ptr)
@ cdecl wined3d_device_set_cursor_position(ptr long long long)
-@ cdecl wined3d_device_set_cursor_properties(ptr long long ptr)
+@ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long)
@ cdecl wined3d_device_set_depth_stencil_view(ptr ptr)
@ cdecl wined3d_device_set_dialog_box_mode(ptr long)
@ cdecl wined3d_device_set_gamma_ramp(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)
@ cdecl wined3d_device_update_surface(ptr ptr ptr ptr ptr)
@ cdecl wined3d_device_update_texture(ptr ptr ptr)
@ cdecl wined3d_device_validate_device(ptr ptr)
@ cdecl wined3d_resource_get_desc(ptr ptr)
@ cdecl wined3d_resource_get_parent(ptr)
-@ cdecl wined3d_resource_get_pitch(ptr ptr ptr)
@ cdecl wined3d_resource_get_priority(ptr)
@ cdecl wined3d_resource_set_parent(ptr ptr)
@ cdecl wined3d_resource_set_priority(ptr long)
+@ cdecl wined3d_resource_sub_resource_map(ptr long ptr ptr long)
+@ cdecl wined3d_resource_sub_resource_unmap(ptr long)
@ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr)
@ cdecl wined3d_rendertarget_view_create_from_surface(ptr ptr ptr ptr)
+@ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr)
@ cdecl wined3d_rendertarget_view_decref(ptr)
@ cdecl wined3d_rendertarget_view_get_parent(ptr)
@ cdecl wined3d_rendertarget_view_get_resource(ptr)
@ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long)
@ cdecl wined3d_surface_decref(ptr)
@ cdecl wined3d_surface_from_resource(ptr)
-@ cdecl wined3d_surface_get_blt_status(ptr long)
-@ cdecl wined3d_surface_get_flip_status(ptr long)
@ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr)
@ cdecl wined3d_surface_get_parent(ptr)
-@ cdecl wined3d_surface_get_render_target_data(ptr ptr)
+@ cdecl wined3d_surface_get_pitch(ptr)
@ cdecl wined3d_surface_get_resource(ptr)
@ cdecl wined3d_surface_getdc(ptr ptr)
@ cdecl wined3d_surface_incref(ptr)
@ cdecl wined3d_swapchain_get_back_buffer(ptr long long)
@ cdecl wined3d_swapchain_get_device(ptr)
@ cdecl wined3d_swapchain_get_display_mode(ptr ptr ptr)
-@ cdecl wined3d_swapchain_get_front_buffer_data(ptr ptr)
+@ cdecl wined3d_swapchain_get_front_buffer_data(ptr ptr long)
@ cdecl wined3d_swapchain_get_gamma_ramp(ptr ptr)
@ cdecl wined3d_swapchain_get_parent(ptr)
@ cdecl wined3d_swapchain_get_desc(ptr ptr)
@ cdecl wined3d_swapchain_get_raster_status(ptr ptr)
@ cdecl wined3d_swapchain_incref(ptr)
@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long)
@ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr)
@ cdecl wined3d_swapchain_set_palette(ptr ptr)
@ cdecl wined3d_swapchain_set_window(ptr ptr)
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
+@ cdecl wined3d_texture_blt(ptr long ptr ptr long ptr long ptr long)
@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr ptr)
@ cdecl wined3d_texture_decref(ptr)
@ cdecl wined3d_texture_generate_mipmaps(ptr)
@ cdecl wined3d_texture_get_autogen_filter_type(ptr)
+@ cdecl wined3d_texture_get_dc(ptr long ptr)
@ cdecl wined3d_texture_get_level_count(ptr)
@ cdecl wined3d_texture_get_lod(ptr)
@ cdecl wined3d_texture_get_parent(ptr)
@ cdecl wined3d_texture_get_sub_resource(ptr long)
@ cdecl wined3d_texture_incref(ptr)
@ cdecl wined3d_texture_preload(ptr)
+@ cdecl wined3d_texture_release_dc(ptr long ptr)
@ cdecl wined3d_texture_set_autogen_filter_type(ptr long)
@ cdecl wined3d_texture_set_color_key(ptr long ptr)
@ cdecl wined3d_texture_set_lod(ptr long)
@ cdecl wined3d_vertex_declaration_get_parent(ptr)
@ cdecl wined3d_vertex_declaration_incref(ptr)
-@ cdecl wined3d_volume_decref(ptr)
-@ cdecl wined3d_volume_from_resource(ptr)
-@ cdecl wined3d_volume_get_parent(ptr)
-@ cdecl wined3d_volume_get_resource(ptr)
-@ cdecl wined3d_volume_incref(ptr)
-@ cdecl wined3d_volume_map(ptr ptr ptr long)
-@ cdecl wined3d_volume_preload(ptr)
-@ cdecl wined3d_volume_unmap(ptr)
-
@ cdecl wined3d_dxtn_supported()
@ cdecl wined3d_dxt1_decode(ptr ptr long long long long long)
@ cdecl wined3d_dxt1_encode(ptr ptr long long long long long)
ARB_DRAW_BUFFERS,
ARB_DRAW_ELEMENTS_BASE_VERTEX,
ARB_DRAW_INSTANCED,
+ ARB_ES2_COMPATIBILITY,
ARB_FRAGMENT_PROGRAM,
ARB_FRAGMENT_SHADER,
ARB_FRAMEBUFFER_OBJECT,
WINED3D_GL_NORMALIZED_TEXRECT,
WINED3D_GL_LEGACY_CONTEXT,
WINED3D_GL_VERSION_2_0,
+ WINED3D_GL_VERSION_3_2,
WINED3D_GL_EXT_COUNT,
};
+#if defined(STAGING_CSMT)
+/*
+ * Direct3D wine internal private include file
+ *
+ * Copyright 2002-2003 The wine-d3d team
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2002-2003, 2004 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006-2011, 2013-2014 Stefan Dösinger for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#else /* STAGING_CSMT */
/*
* Direct3D wine internal private include file
*
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#endif /* STAGING_CSMT */
#ifndef __WINE_WINED3D_PRIVATE_H
#define __WINE_WINED3D_PRIVATE_H
{
struct color_fixup_desc fixup =
{
- 0, complex_fixup & (1 << 0) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
- 0, complex_fixup & (1 << 1) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
- 0, complex_fixup & (1 << 2) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
- 0, complex_fixup & (1 << 3) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0u, complex_fixup & (1u << 0) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0u, complex_fixup & (1u << 1) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0u, complex_fixup & (1u << 2) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0u, complex_fixup & (1u << 3) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
};
return fixup;
}
return fixup.x_source == CHANNEL_SOURCE_COMPLEX0 || fixup.x_source == CHANNEL_SOURCE_COMPLEX1;
}
+static inline BOOL is_scaling_fixup(struct color_fixup_desc fixup)
+{
+ return fixup.x_sign_fixup || fixup.y_sign_fixup || fixup.z_sign_fixup || fixup.w_sign_fixup;
+}
+
static inline BOOL is_same_fixup(struct color_fixup_desc f1, struct color_fixup_desc f2)
{
return f1.x_sign_fixup == f2.x_sign_fixup && f1.x_source == f2.x_source
static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup)
{
enum complex_fixup complex_fixup = 0;
- if (fixup.x_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 0);
- if (fixup.y_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 1);
- if (fixup.z_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 2);
- if (fixup.w_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 3);
+ if (fixup.x_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1u << 0);
+ if (fixup.y_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1u << 1);
+ if (fixup.z_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1u << 2);
+ if (fixup.w_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1u << 3);
return complex_fixup;
}
*/
static inline float float_16_to_32(const unsigned short *in)
{
- const unsigned short s = ((*in) & 0x8000);
- const unsigned short e = ((*in) & 0x7c00) >> 10;
- const unsigned short m = (*in) & 0x3ff;
+ const unsigned short s = ((*in) & 0x8000u);
+ const unsigned short e = ((*in) & 0x7c00u) >> 10;
+ const unsigned short m = (*in) & 0x3ffu;
const float sgn = (s ? -1.0f : 1.0f);
if(e == 0) {
static inline float float_24_to_32(DWORD in)
{
- const float sgn = in & 0x800000 ? -1.0f : 1.0f;
- const unsigned short e = (in & 0x780000) >> 19;
- const unsigned int m = in & 0x7ffff;
+ const float sgn = in & 0x800000u ? -1.0f : 1.0f;
+ const unsigned short e = (in & 0x780000u) >> 19;
+ const unsigned int m = in & 0x7ffffu;
if (e == 0)
{
WINED3D_IMMCONST_VEC4,
};
-#define WINED3DSP_NOSWIZZLE (0 | (1 << 2) | (2 << 4) | (3 << 6))
+#define WINED3DSP_NOSWIZZLE (0u | (1u << 2) | (2u << 4) | (3u << 6))
enum wined3d_shader_src_modifier
{
WINED3DSPSM_NOT = 13,
};
-#define WINED3DSP_WRITEMASK_0 0x1 /* .x r */
-#define WINED3DSP_WRITEMASK_1 0x2 /* .y g */
-#define WINED3DSP_WRITEMASK_2 0x4 /* .z b */
-#define WINED3DSP_WRITEMASK_3 0x8 /* .w a */
-#define WINED3DSP_WRITEMASK_ALL 0xf /* all */
+#define WINED3DSP_WRITEMASK_0 0x1u /* .x r */
+#define WINED3DSP_WRITEMASK_1 0x2u /* .y g */
+#define WINED3DSP_WRITEMASK_2 0x4u /* .z b */
+#define WINED3DSP_WRITEMASK_3 0x8u /* .w a */
+#define WINED3DSP_WRITEMASK_ALL 0xfu /* all */
enum wined3d_shader_dst_modifier
{
WINED3D_SHADER_REL_OP_LE = 6,
};
-#define WINED3D_SM1_VS 0xfffe
-#define WINED3D_SM1_PS 0xffff
-#define WINED3D_SM4_PS 0x0000
-#define WINED3D_SM4_VS 0x0001
-#define WINED3D_SM4_GS 0x0002
+#define WINED3D_SM1_VS 0xfffeu
+#define WINED3D_SM1_PS 0xffffu
+#define WINED3D_SM4_PS 0x0000u
+#define WINED3D_SM4_VS 0x0001u
+#define WINED3D_SM4_GS 0x0002u
/* Shader version tokens, and shader end tokens */
#define WINED3DPS_VERSION(major, minor) ((WINED3D_SM1_PS << 16) | ((major) << 8) | (minor))
struct wined3d_shader_reg_maps
{
struct wined3d_shader_version shader_version;
- BYTE texcoord; /* MAX_REG_TEXCRD, 8 */
- BYTE address; /* MAX_REG_ADDR, 1 */
- WORD labels; /* MAX_LABELS, 16 */
- DWORD temporary; /* MAX_REG_TEMP, 32 */
- DWORD *constf; /* pixel, vertex */
- DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */
- DWORD input_registers; /* max(MAX_REG_INPUT, MAX_ATTRIBS), 32 */
- DWORD output_registers; /* MAX_REG_OUTPUT, 32 */
- WORD integer_constants; /* MAX_CONST_I, 16 */
- WORD boolean_constants; /* MAX_CONST_B, 16 */
- WORD local_int_consts; /* MAX_CONST_I, 16 */
- WORD local_bool_consts; /* MAX_CONST_B, 16 */
+ BYTE texcoord; /* MAX_REG_TEXCRD, 8 */
+ BYTE address; /* MAX_REG_ADDR, 1 */
+ WORD labels; /* MAX_LABELS, 16 */
+ DWORD temporary; /* MAX_REG_TEMP, 32 */
+ DWORD *constf; /* pixel, vertex */
+ union
+ {
+ DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */
+ BYTE output_registers_mask[MAX_REG_OUTPUT]; /* vertex >= 3.0 */
+ } u;
+ DWORD input_registers; /* max(MAX_REG_INPUT, MAX_ATTRIBS), 32 */
+ DWORD output_registers; /* MAX_REG_OUTPUT, 32 */
+ WORD integer_constants; /* MAX_CONST_I, 16 */
+ WORD boolean_constants; /* MAX_CONST_B, 16 */
+ WORD local_int_consts; /* MAX_CONST_I, 16 */
+ WORD local_bool_consts; /* MAX_CONST_B, 16 */
UINT cb_sizes[WINED3D_MAX_CBS];
struct wined3d_shader_resource_info resource_info[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
struct wined3d_shader_sampler_map sampler_map;
- BYTE bumpmat; /* MAX_TEXTURES, 8 */
- BYTE luminanceparams; /* MAX_TEXTURES, 8 */
+ BYTE bumpmat; /* MAX_TEXTURES, 8 */
+ BYTE luminanceparams; /* MAX_TEXTURES, 8 */
WORD usesnrm : 1;
WORD vpos : 1;
DWORD vs_uniform_count;
DWORD ps_uniform_count;
float ps_1x_max_value;
+ DWORD varying_count;
DWORD wined3d_caps;
};
* into the shader code
*/
-#define WINED3D_PSARGS_PROJECTED (1 << 3)
+#define WINED3D_PSARGS_PROJECTED (1u << 3)
#define WINED3D_PSARGS_TEXTRANSFORM_SHIFT 4
-#define WINED3D_PSARGS_TEXTRANSFORM_MASK 0xf
+#define WINED3D_PSARGS_TEXTRANSFORM_MASK 0xfu
#define WINED3D_PSARGS_TEXTYPE_SHIFT 2
-#define WINED3D_PSARGS_TEXTYPE_MASK 0x3
+#define WINED3D_PSARGS_TEXTYPE_MASK 0x3u
/* Used for Shader Model 1 pixel shaders to track the bound texture
* type. 2D and RECT textures are separated through NP2 fixup. */
WORD tex_transform; /* ps 1.0-1.3, 4 textures */
WORD tex_types; /* ps 1.0 - 1.4, 6 textures */
WORD srgb_correction;
- WORD np2_fixup;
/* Bitmap for NP2 texcoord fixups (16 samplers max currently).
D3D9 has a limit of 16 samplers and the fixup is superfluous
in D3D10 (unconditional NP2 support mandatory). */
+ WORD np2_fixup;
WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */
+ WORD texcoords_initialized; /* MAX_TEXTURES, 8 */
BOOL pointsprite;
+ BOOL flatshading;
};
enum fog_src_type {
BYTE clip_enabled : 1;
BYTE point_size : 1;
BYTE per_vertex_point_size : 1;
- BYTE padding : 5;
+ BYTE flatshading : 1;
+ BYTE padding : 4;
WORD swizzle_map; /* MAX_ATTRIBS, 16 */
};
DWORD MaxSimultaneousTextures;
};
+#define GL_EXT_EMUL_ARB_MULTITEXTURE 0x00000001
+#define GL_EXT_EMUL_EXT_FOG_COORD 0x00000002
+
struct fragment_pipeline
{
void (*enable_extension)(const struct wined3d_gl_info *gl_info, BOOL enable);
void (*get_caps)(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps);
+ DWORD (*get_emul_mask)(const struct wined3d_gl_info *gl_info);
void *(*alloc_private)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
void (*free_private)(struct wined3d_device *device);
BOOL (*allocate_context_data)(struct wined3d_context *context);
struct wined3d_vertex_caps
{
BOOL xyzrhw;
+ BOOL emulated_flatshading;
BOOL ffp_generic_attributes;
DWORD max_active_lights;
DWORD max_vertex_blend_matrices;
{
void (*vp_enable)(const struct wined3d_gl_info *gl_info, BOOL enable);
void (*vp_get_caps)(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps);
+ DWORD (*vp_get_emul_mask)(const struct wined3d_gl_info *gl_info);
void *(*vp_alloc)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
void (*vp_free)(struct wined3d_device *device);
const struct StateEntryTemplate *vp_states;
struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
void context_resource_unloaded(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;
CARD_AMD_RADEON_HD2600 = 0x9581,
CARD_AMD_RADEON_HD2900 = 0x9400,
CARD_AMD_RADEON_HD3200 = 0x9620,
+ CARD_AMD_RADEON_HD3850 = 0x9515,
CARD_AMD_RADEON_HD4200M = 0x9712,
CARD_AMD_RADEON_HD4350 = 0x954f,
CARD_AMD_RADEON_HD4600 = 0x9495,
CARD_NVIDIA_GEFORCE_GTS350M = 0x0cb0,
CARD_NVIDIA_GEFORCE_410M = 0x1055,
CARD_NVIDIA_GEFORCE_GT420 = 0x0de2,
+ CARD_NVIDIA_GEFORCE_GT425M = 0x0df0,
CARD_NVIDIA_GEFORCE_GT430 = 0x0de1,
CARD_NVIDIA_GEFORCE_GT440 = 0x0de0,
CARD_NVIDIA_GEFORCE_GTS450 = 0x0dc4,
DWORD quirks;
BOOL supported[WINED3D_GL_EXT_COUNT];
GLint wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP + 1];
+ float fixed_polyoffset_scale, float_polyoffset_scale;
HGLRC (WINAPI *p_wglCreateContextAttribsARB)(HDC dc, HGLRC share, const GLint *attribs);
struct opengl_funcs gl_ops;
UINT vs_version, gs_version, ps_version;
DWORD vs_uniform_count;
DWORD ps_uniform_count;
+ UINT varying_count;
UINT ffp_textures;
UINT ffp_blend_stages;
UINT ffp_vertex_blend_matrices;
struct wined3d_d3d_limits limits;
struct wined3d_ffp_attrib_ops ffp_attrib_ops;
BOOL xyzrhw;
+ BOOL emulated_flatshading;
BOOL ffp_generic_attributes;
BOOL vs_clipping;
BOOL shader_color_key;
const struct blit_shader *blitter;
};
-BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter) DECLSPEC_HIDDEN;
+struct wined3d_caps_gl_ctx
+{
+ HDC dc;
+ HWND wnd;
+ HGLRC gl_ctx;
+ HDC restore_dc;
+ HGLRC restore_gl_ctx;
+
+ const struct wined3d_gl_info *gl_info;
+ GLuint test_vbo;
+ GLuint test_program_id;
+};
+
+float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *ctx, GLenum format) DECLSPEC_HIDDEN;
+BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter,
+ struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN;
UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) DECLSPEC_HIDDEN;
BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
-extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext) DECLSPEC_HIDDEN;
enum projection_types
{
enum wined3d_ffp_ps_fog_mode fog;
unsigned char sRGB_write;
unsigned char emul_clipplanes;
- unsigned char color_key_enabled;
- unsigned char padding;
+ unsigned char texcoords_initialized;
+ unsigned char color_key_enabled : 1;
+ unsigned char pointsprite : 1;
+ unsigned char flatshading : 1;
+ unsigned char padding : 5;
};
struct ffp_frag_desc
extern const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions DECLSPEC_HIDDEN;
extern const struct wined3d_parent_ops wined3d_null_parent_ops DECLSPEC_HIDDEN;
+unsigned int wined3d_max_compat_varyings(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
struct ffp_frag_settings *settings, BOOL ignore_textype) DECLSPEC_HIDDEN;
const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
};
#define WINED3D_FFP_TCI_SHIFT 16
-#define WINED3D_FFP_TCI_MASK 0xff
+#define WINED3D_FFP_TCI_MASK 0xffu
#define WINED3D_FFP_LIGHT_TYPE_SHIFT(idx) (3 * (idx))
-#define WINED3D_FFP_LIGHT_TYPE_MASK 0x7
+#define WINED3D_FFP_LIGHT_TYPE_MASK 0x7u
struct wined3d_ffp_vs_settings
{
DWORD fog_mode : 2;
DWORD texcoords : 8; /* MAX_TEXTURES */
DWORD ortho_fog : 1;
- DWORD padding : 11;
+ DWORD flatshading : 1;
+ DWORD padding : 10;
DWORD texgen[MAX_TEXTURES];
};
struct wined3d_ffp_vs_settings settings;
};
-void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
- struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN;
+void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
+ const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN;
struct wined3d
{
{
DWORD idx = state / (sizeof(*context->isStateDirty) * CHAR_BIT);
BYTE shift = state & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
- return context->isStateDirty[idx] & (1 << shift);
+ return context->isStateDirty[idx] & (1u << shift);
}
#define WINED3D_RESOURCE_ACCESS_GPU 0x1
ULONG (*resource_incref)(struct wined3d_resource *resource);
ULONG (*resource_decref)(struct wined3d_resource *resource);
void (*resource_unload)(struct wined3d_resource *resource);
+ HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
+ HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx);
#if defined(STAGING_CSMT)
void (*resource_location_invalidated)(struct wined3d_resource *resource, DWORD location);
void (*resource_load_location)(struct wined3d_resource *resource,
BOOL unmap_dirtify;
#else /* STAGING_CSMT */
void *heap_memory;
- UINT custom_row_pitch, custom_slice_pitch;
struct list resource_list_entry;
#endif /* STAGING_CSMT */
const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_resource_get_memory(const struct wined3d_resource *resource,
DWORD location, struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
+void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch,
+ UINT *slice_pitch) DECLSPEC_HIDDEN;
GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN;
BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context,
BOOL srgb_mode) DECLSPEC_HIDDEN;
+HRESULT wined3d_volume_map(struct wined3d_volume *volume,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN;
+HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN;
void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
+void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN;
void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context,
BOOL srgb_mode) DECLSPEC_HIDDEN;
void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
+HRESULT wined3d_volume_map(struct wined3d_volume *volume,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
+HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
DWORD flags;
+ UINT pitch;
UINT pow2Width;
UINT pow2Height;
void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void surface_load_ds_location(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
-void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
+ struct wined3d_context *context) DECLSPEC_HIDDEN;
#else /* STAGING_CSMT */
void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
-void surface_load(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
+void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void surface_load_ds_location(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
-void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
-HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
+ struct wined3d_context *context) DECLSPEC_HIDDEN;
+HRESULT surface_load_location(struct wined3d_surface *surface,
+ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
#endif /* STAGING_CSMT */
void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
void surface_prepare_rb(struct wined3d_surface *surface,
void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_in,
struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags,
const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
-BOOL surface_check_block_align(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN;
+BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN;
void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void wined3d_surface_getdc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
-
-void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context,
- const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
-void surface_flip(struct wined3d_surface *front, struct wined3d_surface *back) DECLSPEC_HIDDEN;
#else /* STAGING_CSMT */
void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
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;
+#endif /* STAGING_CSMT */
void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context,
const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
-void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) DECLSPEC_HIDDEN;
-#endif /* STAGING_CSMT */
/* Surface flags: */
#define SFLAG_DIBSECTION 0x00000001 /* Has a DIB section attached for GetDC. */
GLuint name;
};
+#if defined(STAGING_CSMT)
+void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN;
+
+#endif /* STAGING_CSMT */
struct wined3d_vertex_declaration_element
{
const struct wined3d_format *format;
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) 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,
+ unsigned int depth_pitch) DECLSPEC_HIDDEN;
#endif /* STAGING_CSMT */
/* Direct3D terminology with little modifications. We do not have an issued state
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_update_render_to_fbo(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
#if defined(STAGING_CSMT)
HRESULT swapchain_create_context_cs(struct wined3d_device *device,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void state_pointsprite(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_shademode(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
-BOOL getColorBits(const struct wined3d_format *format,
- BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;
-BOOL getDepthStencilBits(const struct wined3d_format *format,
- BYTE *depthSize, BYTE *stencilSize) DECLSPEC_HIDDEN;
GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN;
/* Math utils */
void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN;
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
BOOL position_transformed, struct ps_compile_args *args,
- const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+ const struct wined3d_context *context) DECLSPEC_HIDDEN;
void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
- WORD swizzle_map, struct vs_compile_args *args) DECLSPEC_HIDDEN;
+ WORD swizzle_map, struct vs_compile_args *args,
+ const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN;
void string_buffer_clear(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
BOOL string_buffer_init(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
WORD num_consts;
};
+void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program) DECLSPEC_HIDDEN;
+void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program) DECLSPEC_HIDDEN;
+
struct wined3d_palette
{
LONG ref;
const struct wined3d_color *color) DECLSPEC_HIDDEN;
BOOL wined3d_format_convert_color_to_float(const struct wined3d_format *format,
const struct wined3d_palette *palette, DWORD color, struct wined3d_color *float_color) DECLSPEC_HIDDEN;
+void wined3d_format_get_float_color_key(const struct wined3d_format *format,
+ const struct wined3d_color_key *key, struct wined3d_color *float_colors) DECLSPEC_HIDDEN;
const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
const struct wined3d_texture *texture, BOOL need_alpha_ck) DECLSPEC_HIDDEN;
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
-#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff))
+#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffffu) << 16) | (min & 0xffffu))
#endif
/*** IDirect3DSwapChain9 methods ***/
#define IDirect3DSwapChain9Ex_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e)
#define IDirect3DSwapChain9Ex_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a)
-#define IDirect3DSwapChain9EX_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
-#define IDirect3DSwapChain9EX_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
+#define IDirect3DSwapChain9Ex_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
+#define IDirect3DSwapChain9Ex_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
#define IDirect3DSwapChain9Ex_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
#define IDirect3DSwapChain9Ex_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
#define IDirect3DSwapChain9Ex_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a)
WINED3D_PATCH_EDGE_CONTINUOUS = 1,
};
-enum wined3d_backbuffer_type
-{
- WINED3D_BACKBUFFER_TYPE_MONO = 0,
- WINED3D_BACKBUFFER_TYPE_LEFT = 1,
- WINED3D_BACKBUFFER_TYPE_RIGHT = 2,
-};
-
enum wined3d_swap_effect
{
WINED3D_SWAP_EFFECT_DISCARD = 1,
BOOL disjoint;
};
-#define WINED3DISSUE_BEGIN (1 << 1)
-#define WINED3DISSUE_END (1 << 0)
-#define WINED3DGETDATA_FLUSH (1 << 0)
+#define WINED3DISSUE_BEGIN (1u << 1)
+#define WINED3DISSUE_END (1u << 0)
+#define WINED3DGETDATA_FLUSH (1u << 0)
enum wined3d_stateblock_type
{
WINED3D_DISPLAY_ROTATION_270 = 4,
};
-#define WINED3DCOLORWRITEENABLE_RED (1 << 0)
-#define WINED3DCOLORWRITEENABLE_GREEN (1 << 1)
-#define WINED3DCOLORWRITEENABLE_BLUE (1 << 2)
-#define WINED3DCOLORWRITEENABLE_ALPHA (1 << 3)
+#define WINED3DCOLORWRITEENABLE_RED (1u << 0)
+#define WINED3DCOLORWRITEENABLE_GREEN (1u << 1)
+#define WINED3DCOLORWRITEENABLE_BLUE (1u << 2)
+#define WINED3DCOLORWRITEENABLE_ALPHA (1u << 3)
#define WINED3DADAPTER_DEFAULT 0
#define WINED3DENUM_NO_WHQL_LEVEL 2
-#define WINED3DPRESENT_BACK_BUFFER_MAX 3
#define WINED3DTSS_TCI_PASSTHRU 0x00000
#define WINED3DTSS_TCI_CAMERASPACENORMAL 0x10000
#define WINED3DPRESENT_INTERVAL_IMMEDIATE 0x80000000
#define WINED3DMAXUSERCLIPPLANES 32
-#define WINED3DCLIPPLANE0 (1 << 0)
-#define WINED3DCLIPPLANE1 (1 << 1)
-#define WINED3DCLIPPLANE2 (1 << 2)
-#define WINED3DCLIPPLANE3 (1 << 3)
-#define WINED3DCLIPPLANE4 (1 << 4)
-#define WINED3DCLIPPLANE5 (1 << 5)
+#define WINED3DCLIPPLANE0 (1u << 0)
+#define WINED3DCLIPPLANE1 (1u << 1)
+#define WINED3DCLIPPLANE2 (1u << 2)
+#define WINED3DCLIPPLANE3 (1u << 3)
+#define WINED3DCLIPPLANE4 (1u << 4)
+#define WINED3DCLIPPLANE5 (1u << 5)
/* FVF (Flexible Vertex Format) codes */
#define WINED3DFVF_RESERVED0 0x0001
#define WINED3DFVF_LASTBETA_D3DCOLOR 0x8000
#define WINED3DFVF_RESERVED2 0x6000
-#define WINED3DFVF_TEXTUREFORMAT1 3
-#define WINED3DFVF_TEXTUREFORMAT2 0
-#define WINED3DFVF_TEXTUREFORMAT3 1
-#define WINED3DFVF_TEXTUREFORMAT4 2
+#define WINED3DFVF_TEXTUREFORMAT1 3u
+#define WINED3DFVF_TEXTUREFORMAT2 0u
+#define WINED3DFVF_TEXTUREFORMAT3 1u
+#define WINED3DFVF_TEXTUREFORMAT4 2u
#define WINED3DFVF_TEXCOORDSIZE1(idx) (WINED3DFVF_TEXTUREFORMAT1 << (idx * 2 + 16))
#define WINED3DFVF_TEXCOORDSIZE2(idx) (WINED3DFVF_TEXTUREFORMAT2 << (idx * 2 + 16))
#define WINED3DFVF_TEXCOORDSIZE3(idx) (WINED3DFVF_TEXTUREFORMAT3 << (idx * 2 + 16))
#define WINED3DCLEAR_STENCIL 0x00000004
/* Stream source flags */
-#define WINED3DSTREAMSOURCE_INDEXEDDATA (1 << 30)
-#define WINED3DSTREAMSOURCE_INSTANCEDATA (2 << 30)
+#define WINED3DSTREAMSOURCE_INDEXEDDATA (1u << 30)
+#define WINED3DSTREAMSOURCE_INSTANCEDATA (2u << 30)
/* SetPrivateData flags */
#define WINED3DSPD_IUNKNOWN 0x00000001
#define WINED3D_RESZ_CODE 0x7fa05000
-#define WINED3D_CKEY_COLORSPACE 0x00000001
#define WINED3D_CKEY_DST_BLT 0x00000002
#define WINED3D_CKEY_DST_OVERLAY 0x00000004
#define WINED3D_CKEY_SRC_BLT 0x00000008
struct wined3d_swapchain;
struct wined3d_texture;
struct wined3d_vertex_declaration;
-struct wined3d_volume;
struct wined3d_device_parent
{
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 *surface_created)(struct wined3d_device_parent *device_parent, void *container_parent,
+ HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent,
+ struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_surface *surface, void **parent, const struct wined3d_parent_ops **parent_ops);
- HRESULT (__cdecl *volume_created)(struct wined3d_device_parent *device_parent, void *container_parent,
- struct wined3d_volume *volume, void **parent, const struct wined3d_parent_ops **parent_ops);
- HRESULT (__cdecl *create_swapchain_surface)(struct wined3d_device_parent *device_parent, void *container_parent,
- const struct wined3d_resource_desc *desc, struct wined3d_surface **surface);
+ 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, struct wined3d_texture **texture);
HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain);
};
UINT adapter_idx, const struct wined3d_display_mode *mode);
HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
- const void *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer);
+ const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_buffer **buffer);
HRESULT __cdecl wined3d_buffer_create_ib(struct wined3d_device *device, UINT length, DWORD usage,
enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_buffer **buffer);
struct wined3d_rendertarget_view *view, const RECT *rect, const struct wined3d_color *color);
void __cdecl wined3d_device_copy_resource(struct wined3d_device *device,
struct wined3d_resource *dst_resource, struct wined3d_resource *src_resource);
+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);
HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment,
struct wined3d_device_parent *device_parent, struct wined3d_device **device);
HRESULT __cdecl wined3d_device_end_stateblock(struct wined3d_device *device, struct wined3d_stateblock **stateblock);
void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device);
UINT __cdecl wined3d_device_get_available_texture_mem(const struct wined3d_device *device);
-HRESULT __cdecl wined3d_device_get_back_buffer(const struct wined3d_device *device, UINT swapchain_idx,
- UINT backbuffer_idx, enum wined3d_backbuffer_type backbuffer_type, struct wined3d_surface **backbuffer);
INT __cdecl wined3d_device_get_base_vertex_index(const struct wined3d_device *device);
HRESULT __cdecl wined3d_device_get_clip_plane(const struct wined3d_device *device,
UINT plane_idx, struct wined3d_vec4 *plane);
HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps);
HRESULT __cdecl wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
-HRESULT __cdecl wined3d_device_get_front_buffer_data(const struct wined3d_device *device,
- UINT swapchain_idx, struct wined3d_surface *dst_surface);
void __cdecl wined3d_device_get_gamma_ramp(const struct wined3d_device *device,
UINT swapchain_idx, struct wined3d_gamma_ramp *ramp);
struct wined3d_shader * __cdecl wined3d_device_get_geometry_shader(const struct wined3d_device *device);
HRESULT __cdecl wined3d_device_init_gdi(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc);
void __cdecl wined3d_device_multiply_transform(struct wined3d_device *device,
enum wined3d_transform_state state, const struct wined3d_matrix *matrix);
-HRESULT __cdecl wined3d_device_present(const struct wined3d_device *device, const RECT *src_rect,
- const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags);
HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device,
UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer,
const struct wined3d_vertex_declaration *declaration, DWORD flags, DWORD dst_fvf);
void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device,
int x_screen_space, int y_screen_space, DWORD flags);
HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device,
- UINT x_hotspot, UINT y_hotspot, struct wined3d_surface *cursor_surface);
+ UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx);
void __cdecl wined3d_device_set_depth_stencil_view(struct wined3d_device *device,
struct wined3d_rendertarget_view *view);
HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs);
BOOL __cdecl wined3d_device_show_cursor(struct wined3d_device *device, BOOL show);
HRESULT __cdecl wined3d_device_uninit_3d(struct wined3d_device *device);
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);
HRESULT __cdecl wined3d_device_update_surface(struct wined3d_device *device, struct wined3d_surface *src_surface,
const RECT *src_rect, struct wined3d_surface *dst_surface, const POINT *dst_point);
HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device,
void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource,
struct wined3d_resource_desc *desc);
void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource);
-void __cdecl wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch,
- UINT *slice_pitch);
DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource);
void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent);
DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority);
+HRESULT __cdecl wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
+HRESULT __cdecl wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx);
HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view);
HRESULT __cdecl wined3d_rendertarget_view_create_from_surface(struct wined3d_surface *surface,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view);
+HRESULT __cdecl wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture,
+ unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_rendertarget_view **view);
ULONG __cdecl wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view);
void * __cdecl wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view);
struct wined3d_resource * __cdecl wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view);
const WINEDDBLTFX *blt_fx, enum wined3d_texture_filter_type filter);
ULONG __cdecl wined3d_surface_decref(struct wined3d_surface *surface);
struct wined3d_surface * __cdecl wined3d_surface_from_resource(struct wined3d_resource *resource);
-HRESULT __cdecl wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags);
-HRESULT __cdecl wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags);
HRESULT __cdecl wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y);
void * __cdecl wined3d_surface_get_parent(const struct wined3d_surface *surface);
-HRESULT __cdecl wined3d_surface_get_render_target_data(struct wined3d_surface *surface,
- struct wined3d_surface *render_target);
+DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface);
struct wined3d_resource * __cdecl wined3d_surface_get_resource(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc);
ULONG __cdecl wined3d_surface_incref(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_is_lost(const struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_map(struct wined3d_surface *surface,
- struct wined3d_map_desc *map_desc, const RECT *rect, DWORD flags);
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
void __cdecl wined3d_surface_preload(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc);
HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain);
ULONG __cdecl wined3d_swapchain_decref(struct wined3d_swapchain *swapchain);
-struct wined3d_surface * __cdecl wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
- UINT backbuffer_idx, enum wined3d_backbuffer_type backbuffer_type);
+struct wined3d_texture * __cdecl wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
+ UINT backbuffer_idx);
struct wined3d_device * __cdecl wined3d_swapchain_get_device(const struct wined3d_swapchain *swapchain);
HRESULT __cdecl wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain,
struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
HRESULT __cdecl wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapchain *swapchain,
- struct wined3d_surface *dst_surface);
+ struct wined3d_texture *dst_texture, unsigned int sub_resource_idx);
HRESULT __cdecl wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain,
struct wined3d_gamma_ramp *ramp);
void * __cdecl wined3d_swapchain_get_parent(const 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,
const RGNDATA *dirty_region, 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);
HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain,
DWORD flags, const struct wined3d_gamma_ramp *ramp);
void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette);
HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
UINT layer, const struct wined3d_box *dirty_region);
+HRESULT __cdecl wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_idx, const RECT *dst_rect_in,
+ struct wined3d_texture *src_texture, unsigned int src_idx, const RECT *src_rect_in, DWORD flags,
+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter);
HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture);
void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture);
enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture);
+HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc);
DWORD __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture);
DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture);
void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture);
HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture,
DWORD flags, const struct wined3d_color_key *color_key);
DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
+HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc);
HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture,
UINT width, UINT height, enum wined3d_format_id format_id,
enum wined3d_multisample_type multisample_type, UINT multisample_quality,
void * __cdecl wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration);
ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration);
-ULONG __cdecl wined3d_volume_decref(struct wined3d_volume *volume);
-struct wined3d_volume * __cdecl wined3d_volume_from_resource(struct wined3d_resource *resource);
-void * __cdecl wined3d_volume_get_parent(const struct wined3d_volume *volume);
-struct wined3d_resource * __cdecl wined3d_volume_get_resource(struct wined3d_volume *volume);
-ULONG __cdecl wined3d_volume_incref(struct wined3d_volume *volume);
-HRESULT __cdecl wined3d_volume_map(struct wined3d_volume *volume,
- struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
-void __cdecl wined3d_volume_preload(struct wined3d_volume *volume);
-HRESULT __cdecl wined3d_volume_unmap(struct wined3d_volume *volume);
-
/* Return the integer base-2 logarithm of x. Undefined for x == 0. */
static inline unsigned int wined3d_log2i(unsigned int x)
{
The following libraries are shared with Wine.
reactos/dll/directx/wine/amstream # Synced to WineStaging-1.7.55
-reactos/dll/directx/wine/d3d8 # Synced to WineStaging-1.7.47
-reactos/dll/directx/wine/d3d9 # Synced to WineStaging-1.7.47
+reactos/dll/directx/wine/d3d8 # Synced to WineStaging-1.7.55
+reactos/dll/directx/wine/d3d9 # Synced to WineStaging-1.7.55
reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-1.7.47
reactos/dll/directx/wine/d3drm # Synced to WineStaging-1.7.47
reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-1.7.55
reactos/dll/directx/wine/d3dxof # Synced to WineStaging-1.7.47
-reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.7.47
+reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.7.55
reactos/dll/directx/wine/devenum # Synced to WineStaging-1.7.47
reactos/dll/directx/wine/dinput # Synced to WineStaging-1.7.47
reactos/dll/directx/wine/dinput8 # Synced to WineStaging-1.7.47
reactos/dll/directx/wine/msdmo # Synced to WineStaging-1.7.47
reactos/dll/directx/wine/qedit # Synced to WineStaging-1.7.37
reactos/dll/directx/wine/quartz # Synced to WineStaging-1.7.47
-reactos/dll/directx/wine/wined3d # Synced to WineStaging-1.7.47
+reactos/dll/directx/wine/wined3d # Synced to WineStaging-1.7.55
reactos/dll/win32/activeds # Synced to WineStaging-1.7.47
reactos/dll/win32/actxprxy # Synced to WineStaging-1.7.47