wined3d: Use rendertarget views for color output instead of surfaces.

This commit is contained in:
Henri Verbeet 2014-08-21 09:55:55 +02:00 committed by Alexandre Julliard
parent 7ede9788d4
commit b005ad6f90
29 changed files with 512 additions and 179 deletions

View File

@ -53,6 +53,8 @@ struct d3d10_shader_info
struct wined3d_shader_signature *output_signature;
};
extern const struct wined3d_parent_ops d3d10_null_wined3d_parent_ops DECLSPEC_HIDDEN;
/* TRACE helper functions */
const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology) DECLSPEC_HIDDEN;
const char *debug_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN;

View File

@ -745,7 +745,8 @@ HRESULT d3d10_rendertarget_view_init(struct d3d10_rendertarget_view *view, struc
}
wined3d_rendertarget_view_desc_from_d3d10core(&wined3d_desc, &view->desc);
if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource, view, &view->wined3d_view)))
if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
view, &d3d10_null_wined3d_parent_ops, &view->wined3d_view)))
{
WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr);
return hr;

View File

@ -227,11 +227,14 @@ struct d3d8_surface
IDirect3DSurface8 IDirect3DSurface8_iface;
struct d3d8_resource resource;
struct wined3d_surface *wined3d_surface;
struct list rtv_entry;
struct wined3d_rendertarget_view *wined3d_rtv;
IDirect3DDevice8 *parent_device;
IUnknown *container;
struct d3d8_texture *texture;
};
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;
struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
@ -268,6 +271,7 @@ struct d3d8_texture
struct d3d8_resource resource;
struct wined3d_texture *wined3d_texture;
IDirect3DDevice8 *parent_device;
struct list rtv_list;
};
HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,

View File

@ -1136,19 +1136,22 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
if (ds_impl)
{
struct wined3d_rendertarget_view *original_rtv;
struct wined3d_resource_desc ds_desc, rt_desc;
struct wined3d_resource *wined3d_resource;
struct wined3d_surface *original_rt = NULL;
struct d3d8_surface *original_surface;
/* If no render target is passed in check the size against the current RT */
if (!render_target)
{
if (!(original_rt = wined3d_device_get_render_target(device->wined3d_device, 0)))
if (!(original_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
{
wined3d_mutex_unlock();
return D3DERR_NOTFOUND;
}
wined3d_resource = wined3d_surface_get_resource(original_rt);
original_surface = wined3d_rendertarget_view_get_sub_resource_parent(original_rtv);
wined3d_resource = wined3d_surface_get_resource(original_surface->wined3d_surface);
}
else
wined3d_resource = wined3d_surface_get_resource(rt_impl->wined3d_surface);
@ -1167,12 +1170,9 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
original_ds = wined3d_device_get_depth_stencil(device->wined3d_device);
wined3d_device_set_depth_stencil(device->wined3d_device, ds_impl ? ds_impl->wined3d_surface : NULL);
if (render_target)
{
hr = wined3d_device_set_render_target(device->wined3d_device, 0, rt_impl->wined3d_surface, TRUE);
if (FAILED(hr))
wined3d_device_set_depth_stencil(device->wined3d_device, original_ds);
}
if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0,
d3d8_surface_get_rendertarget_view(rt_impl), TRUE)))
wined3d_device_set_depth_stencil(device->wined3d_device, original_ds);
wined3d_mutex_unlock();
@ -1182,7 +1182,7 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
static HRESULT WINAPI d3d8_device_GetRenderTarget(IDirect3DDevice8 *iface, IDirect3DSurface8 **render_target)
{
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
struct wined3d_surface *wined3d_surface;
struct wined3d_rendertarget_view *wined3d_rtv;
struct d3d8_surface *surface_impl;
HRESULT hr;
@ -1192,9 +1192,11 @@ static HRESULT WINAPI d3d8_device_GetRenderTarget(IDirect3DDevice8 *iface, IDire
return D3DERR_INVALIDCALL;
wined3d_mutex_lock();
if ((wined3d_surface = wined3d_device_get_render_target(device->wined3d_device, 0)))
if ((wined3d_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
{
surface_impl = wined3d_surface_get_parent(wined3d_surface);
/* We want the sub resource parent here, since the view itself may be
* internal to wined3d and may not have a parent. */
surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_rtv);
*render_target = &surface_impl->IDirect3DSurface8_iface;
IDirect3DSurface8_AddRef(*render_target);
hr = D3D_OK;

View File

@ -68,6 +68,8 @@ static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
if (surface->parent_device)
IDirect3DDevice8_AddRef(surface->parent_device);
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
wined3d_surface_incref(surface->wined3d_surface);
wined3d_mutex_unlock();
}
@ -96,6 +98,8 @@ static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
IDirect3DDevice8 *parent_device = surface->parent_device;
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
wined3d_surface_decref(surface->wined3d_surface);
wined3d_mutex_unlock();
@ -297,6 +301,7 @@ void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
d3d8_resource_init(&surface->resource);
surface->resource.refcount = 0;
surface->wined3d_surface = wined3d_surface;
list_init(&surface->rtv_entry);
surface->container = container_parent;
if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
@ -309,6 +314,48 @@ void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
*parent_ops = &d3d8_surface_wined3d_parent_ops;
}
static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent)
{
struct d3d8_surface *surface = parent;
/* If the surface reference count drops to zero, we release our reference
* to the view, but don't clear the pointer yet, in case e.g. a
* GetRenderTarget() call brings the surface back before the view is
* actually destroyed. When the view is destroyed, we need to clear the
* pointer, or a subsequent surface AddRef() would reference it again.
*
* This is safe because as long as the view still has a reference to the
* texture, the surface is also still alive, and we're called before the
* view releases that reference. */
surface->wined3d_rtv = NULL;
list_remove(&surface->rtv_entry);
}
static const struct wined3d_parent_ops d3d8_view_wined3d_parent_ops =
{
view_wined3d_object_destroyed,
};
struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8_surface *surface)
{
HRESULT hr;
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)))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
return NULL;
}
if (surface->texture)
list_add_head(&surface->texture->rtv_list, &surface->rtv_entry);
return surface->wined3d_rtv;
}
struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
{
if (!iface)

View File

@ -65,8 +65,14 @@ static ULONG WINAPI d3d8_texture_2d_AddRef(IDirect3DTexture8 *iface)
if (ref == 1)
{
struct d3d8_surface *surface;
IDirect3DDevice8_AddRef(texture->parent_device);
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
{
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
}
wined3d_texture_incref(texture->wined3d_texture);
wined3d_mutex_unlock();
}
@ -84,8 +90,13 @@ static ULONG WINAPI d3d8_texture_2d_Release(IDirect3DTexture8 *iface)
if (!ref)
{
IDirect3DDevice8 *parent_device = texture->parent_device;
struct d3d8_surface *surface;
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
{
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
}
wined3d_texture_decref(texture->wined3d_texture);
wined3d_mutex_unlock();
@ -413,8 +424,14 @@ static ULONG WINAPI d3d8_texture_cube_AddRef(IDirect3DCubeTexture8 *iface)
if (ref == 1)
{
struct d3d8_surface *surface;
IDirect3DDevice8_AddRef(texture->parent_device);
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
{
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
}
wined3d_texture_incref(texture->wined3d_texture);
wined3d_mutex_unlock();
}
@ -432,10 +449,15 @@ static ULONG WINAPI d3d8_texture_cube_Release(IDirect3DCubeTexture8 *iface)
if (!ref)
{
IDirect3DDevice8 *parent_device = texture->parent_device;
struct d3d8_surface *surface;
TRACE("Releasing child %p.\n", texture->wined3d_texture);
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
{
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
}
wined3d_texture_decref(texture->wined3d_texture);
wined3d_mutex_unlock();
@ -1133,6 +1155,7 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl;
d3d8_resource_init(&texture->resource);
list_init(&texture->rtv_list);
desc.resource_type = WINED3D_RTYPE_TEXTURE;
desc.format = wined3dformat_from_d3dformat(format);
@ -1174,6 +1197,7 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic
texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl;
d3d8_resource_init(&texture->resource);
list_init(&texture->rtv_list);
desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
desc.format = wined3dformat_from_d3dformat(format);
@ -1214,6 +1238,7 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev
texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl;
d3d8_resource_init(&texture->resource);
list_init(&texture->rtv_list);
desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
desc.format = wined3dformat_from_d3dformat(format);

View File

@ -214,12 +214,15 @@ struct d3d9_surface
IDirect3DSurface9 IDirect3DSurface9_iface;
struct d3d9_resource resource;
struct wined3d_surface *wined3d_surface;
struct list rtv_entry;
struct wined3d_rendertarget_view *wined3d_rtv;
IDirect3DDevice9Ex *parent_device;
IUnknown *container;
struct d3d9_texture *texture;
BOOL getdc_supported;
};
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,
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;
@ -256,6 +259,7 @@ struct d3d9_texture
struct d3d9_resource resource;
struct wined3d_texture *wined3d_texture;
IDirect3DDevice9Ex *parent_device;
struct list rtv_list;
};
HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,

View File

@ -1345,8 +1345,8 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO
}
wined3d_mutex_lock();
hr = wined3d_device_set_render_target(device->wined3d_device, idx,
surface_impl ? surface_impl->wined3d_surface : NULL, TRUE);
hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx,
surface_impl ? d3d9_surface_get_rendertarget_view(surface_impl) : NULL, TRUE);
wined3d_mutex_unlock();
return hr;
@ -1355,7 +1355,7 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO
static HRESULT WINAPI d3d9_device_GetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 **surface)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
struct wined3d_surface *wined3d_surface;
struct wined3d_rendertarget_view *wined3d_rtv;
struct d3d9_surface *surface_impl;
HRESULT hr = D3D_OK;
@ -1371,9 +1371,11 @@ static HRESULT WINAPI d3d9_device_GetRenderTarget(IDirect3DDevice9Ex *iface, DWO
}
wined3d_mutex_lock();
if ((wined3d_surface = wined3d_device_get_render_target(device->wined3d_device, idx)))
if ((wined3d_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, idx)))
{
surface_impl = wined3d_surface_get_parent(wined3d_surface);
/* We want the sub resource parent here, since the view itself may be
* internal to wined3d and may not have a parent. */
surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_rtv);
*surface = &surface_impl->IDirect3DSurface9_iface;
IDirect3DSurface9_AddRef(*surface);
}

View File

@ -69,6 +69,8 @@ static ULONG WINAPI d3d9_surface_AddRef(IDirect3DSurface9 *iface)
if (surface->parent_device)
IDirect3DDevice9Ex_AddRef(surface->parent_device);
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
wined3d_surface_incref(surface->wined3d_surface);
wined3d_mutex_unlock();
}
@ -97,6 +99,8 @@ static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
IDirect3DDevice9Ex *parent_device = surface->parent_device;
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
wined3d_surface_decref(surface->wined3d_surface);
wined3d_mutex_unlock();
@ -351,6 +355,7 @@ void surface_init(struct d3d9_surface *surface, IUnknown *container_parent,
d3d9_resource_init(&surface->resource);
surface->resource.refcount = 0;
surface->wined3d_surface = wined3d_surface;
list_init(&surface->rtv_entry);
surface->container = container_parent;
if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
@ -380,6 +385,48 @@ void surface_init(struct d3d9_surface *surface, IUnknown *container_parent,
*parent_ops = &d3d9_surface_wined3d_parent_ops;
}
static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent)
{
struct d3d9_surface *surface = parent;
/* If the surface reference count drops to zero, we release our reference
* to the view, but don't clear the pointer yet, in case e.g. a
* GetRenderTarget() call brings the surface back before the view is
* actually destroyed. When the view is destroyed, we need to clear the
* pointer, or a subsequent surface AddRef() would reference it again.
*
* This is safe because as long as the view still has a reference to the
* texture, the surface is also still alive, and we're called before the
* view releases that reference. */
surface->wined3d_rtv = NULL;
list_remove(&surface->rtv_entry);
}
static const struct wined3d_parent_ops d3d9_view_wined3d_parent_ops =
{
view_wined3d_object_destroyed,
};
struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface)
{
HRESULT hr;
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)))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
return NULL;
}
if (surface->texture)
list_add_head(&surface->texture->rtv_list, &surface->rtv_entry);
return surface->wined3d_rtv;
}
struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface)
{
if (!iface)

View File

@ -67,8 +67,14 @@ static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
if (ref == 1)
{
struct d3d9_surface *surface;
IDirect3DDevice9Ex_AddRef(texture->parent_device);
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
{
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
}
wined3d_texture_incref(texture->wined3d_texture);
wined3d_mutex_unlock();
}
@ -86,8 +92,13 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
if (!ref)
{
IDirect3DDevice9Ex *parent_device = texture->parent_device;
struct d3d9_surface *surface;
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
{
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
}
wined3d_texture_decref(texture->wined3d_texture);
wined3d_mutex_unlock();
@ -458,8 +469,14 @@ static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
if (ref == 1)
{
struct d3d9_surface *surface;
IDirect3DDevice9Ex_AddRef(texture->parent_device);
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
{
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
}
wined3d_texture_incref(texture->wined3d_texture);
wined3d_mutex_unlock();
}
@ -477,10 +494,15 @@ static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
if (!ref)
{
IDirect3DDevice9Ex *parent_device = texture->parent_device;
struct d3d9_surface *surface;
TRACE("Releasing child %p.\n", texture->wined3d_texture);
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
{
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
}
wined3d_texture_decref(texture->wined3d_texture);
wined3d_mutex_unlock();
@ -1257,6 +1279,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
d3d9_resource_init(&texture->resource);
list_init(&texture->rtv_list);
desc.resource_type = WINED3D_RTYPE_TEXTURE;
desc.format = wined3dformat_from_d3dformat(format);
@ -1298,6 +1321,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
d3d9_resource_init(&texture->resource);
list_init(&texture->rtv_list);
desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
desc.format = wined3dformat_from_d3dformat(format);
@ -1338,6 +1362,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
d3d9_resource_init(&texture->resource);
list_init(&texture->rtv_list);
desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
desc.format = wined3dformat_from_d3dformat(format);

View File

@ -767,8 +767,9 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
DWORD cooplevel, BOOL restore_mode_on_normal)
{
struct wined3d_surface *rt = NULL, *ds = NULL;
struct wined3d_rendertarget_view *rtv = NULL;
struct wined3d_stateblock *stateblock;
struct wined3d_surface *ds = NULL;
BOOL restore_state = FALSE;
HRESULT hr;
@ -918,11 +919,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
}
wined3d_stateblock_capture(stateblock);
rt = wined3d_device_get_render_target(ddraw->wined3d_device, 0);
if (rt == ddraw->wined3d_frontbuffer)
rt = NULL;
else if (rt)
wined3d_surface_incref(rt);
rtv = wined3d_device_get_rendertarget_view(ddraw->wined3d_device, 0);
/* Rendering to ddraw->wined3d_frontbuffer. */
if (rtv && !wined3d_rendertarget_view_get_sub_resource_parent(rtv))
rtv = NULL;
else if (rtv)
wined3d_rendertarget_view_incref(rtv);
if ((ds = wined3d_device_get_depth_stencil(ddraw->wined3d_device)))
wined3d_surface_incref(ds);
@ -942,10 +944,10 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
wined3d_surface_decref(ds);
}
if (rt)
if (rtv)
{
wined3d_device_set_render_target(ddraw->wined3d_device, 0, rt, FALSE);
wined3d_surface_decref(rt);
wined3d_device_set_rendertarget_view(ddraw->wined3d_device, 0, rtv, FALSE);
wined3d_rendertarget_view_decref(rtv);
}
wined3d_stateblock_apply(stateblock);

View File

@ -158,6 +158,7 @@ struct ddraw_surface
struct ddraw *ddraw;
struct wined3d_surface *wined3d_surface;
struct wined3d_texture *wined3d_texture;
struct wined3d_rendertarget_view *wined3d_rtv;
struct wined3d_private_store private_store;
struct d3d_device *device1;
@ -205,6 +206,7 @@ struct ddraw_texture
HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc,
struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN;
struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN;
HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN;

View File

@ -246,7 +246,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
if (This->vertex_buffer)
wined3d_buffer_decref(This->vertex_buffer);
wined3d_device_set_render_target(This->wined3d_device, 0, NULL, FALSE);
wined3d_device_set_rendertarget_view(This->wined3d_device, 0, NULL, FALSE);
/* Release the wined3d device. This won't destroy it. */
if (!wined3d_device_decref(This->wined3d_device))
@ -1818,8 +1818,8 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device,
return DDERR_INVALIDPARAMS;
}
if (FAILED(hr = wined3d_device_set_render_target(device->wined3d_device,
0, target->wined3d_surface, FALSE)))
if (FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device,
0, ddraw_surface_get_rendertarget_view(target), FALSE)))
return hr;
IUnknown_AddRef(rt_iface);
@ -6818,8 +6818,8 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
wined3d_device_incref(ddraw->wined3d_device);
/* Render to the back buffer */
hr = wined3d_device_set_render_target(ddraw->wined3d_device, 0, target->wined3d_surface, TRUE);
if (FAILED(hr))
if (FAILED(hr = wined3d_device_set_rendertarget_view(ddraw->wined3d_device,
0, ddraw_surface_get_rendertarget_view(target), TRUE)))
{
ERR("Failed to set render target, hr %#x.\n", hr);
ddraw_handle_table_destroy(&device->handle_table);

View File

@ -322,6 +322,8 @@ static void ddraw_surface_add_iface(struct ddraw_surface *surface)
if (surface->ifaceToRelease)
IUnknown_AddRef(surface->ifaceToRelease);
wined3d_mutex_lock();
if (surface->wined3d_rtv)
wined3d_rendertarget_view_incref(surface->wined3d_rtv);
if (surface->wined3d_surface)
wined3d_surface_incref(surface->wined3d_surface);
if (surface->wined3d_texture)
@ -526,6 +528,8 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface)
surface, surface->ref7, surface->ref4, surface->ref3, surface->ref2, surface->ref1);
}
if (surface->wined3d_rtv)
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
if (surface->wined3d_texture)
wined3d_texture_decref(surface->wined3d_texture);
if (surface->wined3d_surface)
@ -1208,11 +1212,12 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra
{
struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src);
struct wined3d_rendertarget_view *tmp_rtv, *src_rtv, *rtv;
struct ddraw_texture *ddraw_texture, *prev_ddraw_texture;
DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, 0};
struct wined3d_surface *tmp, *rt;
struct wined3d_texture *texture;
IDirectDrawSurface7 *current;
struct wined3d_surface *tmp;
HRESULT hr;
TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
@ -1225,9 +1230,10 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra
wined3d_mutex_lock();
tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl);
tmp = dst_impl->wined3d_surface;
texture = dst_impl->wined3d_texture;
rt = wined3d_device_get_render_target(dst_impl->ddraw->wined3d_device, 0);
rtv = wined3d_device_get_rendertarget_view(dst_impl->ddraw->wined3d_device, 0);
ddraw_texture = wined3d_texture_get_parent(dst_impl->wined3d_texture);
if (src_impl)
@ -1249,8 +1255,11 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra
}
}
if (rt == dst_impl->wined3d_surface)
wined3d_device_set_render_target(dst_impl->ddraw->wined3d_device, 0, src_impl->wined3d_surface, FALSE);
src_rtv = ddraw_surface_get_rendertarget_view(src_impl);
if (rtv == dst_impl->wined3d_rtv)
wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
dst_impl->wined3d_rtv = src_rtv;
wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl);
dst_impl->wined3d_surface = src_impl->wined3d_surface;
prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture);
@ -1276,8 +1285,11 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra
}
src_impl = impl_from_IDirectDrawSurface7(current);
if (rt == dst_impl->wined3d_surface)
wined3d_device_set_render_target(dst_impl->ddraw->wined3d_device, 0, src_impl->wined3d_surface, FALSE);
src_rtv = ddraw_surface_get_rendertarget_view(src_impl);
if (rtv == dst_impl->wined3d_rtv)
wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
dst_impl->wined3d_rtv = src_rtv;
wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl);
dst_impl->wined3d_surface = src_impl->wined3d_surface;
prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture);
@ -1290,8 +1302,10 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra
/* We don't have to worry about potential texture bindings, since
* flippable surfaces can never be textures. */
if (rt == src_impl->wined3d_surface)
wined3d_device_set_render_target(dst_impl->ddraw->wined3d_device, 0, tmp, FALSE);
if (rtv == src_impl->wined3d_rtv)
wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE);
wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl);
src_impl->wined3d_rtv = tmp_rtv;
wined3d_resource_set_parent(wined3d_surface_get_resource(tmp), src_impl);
src_impl->wined3d_surface = tmp;
wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture);
@ -6227,3 +6241,41 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
return DD_OK;
}
static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent)
{
struct ddraw_surface *surface = parent;
/* If the surface reference count drops to zero, we release our reference
* to the view, but don't clear the pointer yet, in case e.g. a
* GetRenderTarget() call brings the surface back before the view is
* actually destroyed. When the view is destroyed, we need to clear the
* pointer, or a subsequent surface AddRef() would reference it again.
*
* This is safe because as long as the view still has a reference to the
* texture, the surface is also still alive, and we're called before the
* view releases that reference. */
surface->wined3d_rtv = NULL;
}
static const struct wined3d_parent_ops ddraw_view_wined3d_parent_ops =
{
view_wined3d_object_destroyed,
};
struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface)
{
HRESULT hr;
if (surface->wined3d_rtv)
return surface->wined3d_rtv;
if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(surface->wined3d_surface,
surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv)))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
return NULL;
}
return surface->wined3d_rtv;
}

View File

@ -706,7 +706,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv,
{
const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog;
UINT rt_height = state->fb->render_targets[0]->resource.height;
UINT rt_height = state->fb->render_targets[0]->height;
/* Load DirectX 9 float constants for pixel shader */
priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
@ -4673,7 +4673,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context
}
else
{
UINT rt_height = state->fb->render_targets[0]->resource.height;
UINT rt_height = state->fb->render_targets[0]->height;
shader_arb_ps_local_constants(compiled, context, state, rt_height);
}

View File

@ -2281,7 +2281,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
}
static BOOL context_validate_rt_config(UINT rt_count,
struct wined3d_surface * const *rts, const struct wined3d_surface *ds)
struct wined3d_rendertarget_view * const *rts, const struct wined3d_surface *ds)
{
unsigned int i;
@ -2289,7 +2289,7 @@ static BOOL context_validate_rt_config(UINT rt_count,
for (i = 0; i < rt_count; ++i)
{
if (rts[i] && rts[i]->resource.format->id != WINED3DFMT_NULL)
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
return TRUE;
}
@ -2301,10 +2301,10 @@ static BOOL context_validate_rt_config(UINT rt_count,
BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device,
UINT rt_count, const struct wined3d_fb_state *fb)
{
struct wined3d_rendertarget_view **rts = fb->render_targets;
const struct wined3d_gl_info *gl_info = context->gl_info;
DWORD rt_mask = 0, *cur_mask;
UINT i;
struct wined3d_surface **rts = fb->render_targets;
if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb
|| rt_count != context->gl_info->limits.buffers)
@ -2316,12 +2316,12 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
{
context_validate_onscreen_formats(context, fb->depth_stencil);
if (!rt_count || wined3d_resource_is_offscreen(&rts[0]->resource))
if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
{
for (i = 0; i < rt_count; ++i)
{
context->blit_targets[i] = rts[i];
if (rts[i] && rts[i]->resource.format->id != WINED3DFMT_NULL)
context->blit_targets[i] = wined3d_rendertarget_view_get_surface(rts[i]);
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
rt_mask |= (1 << i);
}
while (i < context->gl_info->limits.buffers)
@ -2330,12 +2330,12 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
++i;
}
context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, fb->depth_stencil,
rt_count ? rts[0]->container->resource.draw_binding : WINED3D_LOCATION_TEXTURE_RGB);
rt_count ? rts[0]->resource->draw_binding : WINED3D_LOCATION_TEXTURE_RGB);
}
else
{
context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, WINED3D_LOCATION_DRAWABLE);
rt_mask = context_generate_rt_mask_from_surface(rts[0]);
rt_mask = context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0]));
}
/* If the framebuffer is not the device's fb the device's fb has to be reapplied
@ -2345,20 +2345,23 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
}
else
{
rt_mask = context_generate_rt_mask_no_fbo(device, rt_count ? rts[0] : NULL);
rt_mask = context_generate_rt_mask_no_fbo(device,
rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL);
}
}
else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
&& (!rt_count || wined3d_resource_is_offscreen(&rts[0]->resource)))
&& (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource)))
{
for (i = 0; i < rt_count; ++i)
{
if (rts[i] && rts[i]->resource.format->id != WINED3DFMT_NULL) rt_mask |= (1 << i);
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
rt_mask |= (1 << i);
}
}
else
{
rt_mask = context_generate_rt_mask_no_fbo(device, rt_count ? rts[0] : NULL);
rt_mask = context_generate_rt_mask_no_fbo(device,
rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL);
}
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
@ -2395,13 +2398,15 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device)
{
const struct wined3d_state *state = &device->state;
struct wined3d_surface **rts = state->fb->render_targets;
struct wined3d_rendertarget_view **rts = state->fb->render_targets;
struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL];
DWORD rt_mask, rt_mask_bits;
unsigned int i;
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return context_generate_rt_mask_no_fbo(device, rts[0]);
else if (!context->render_offscreen) return context_generate_rt_mask_from_surface(rts[0]);
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
return context_generate_rt_mask_no_fbo(device, wined3d_rendertarget_view_get_surface(rts[0]));
else if (!context->render_offscreen)
return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0]));
rt_mask = ps ? ps->reg_maps.rt_mask : 1;
rt_mask &= context->d3d_info->valid_rt_mask;
@ -2410,7 +2415,7 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const
while (rt_mask_bits)
{
rt_mask_bits &= ~(1 << i);
if (!rts[i] || rts[i]->resource.format->id == WINED3DFMT_NULL)
if (!rts[i] || rts[i]->format->id == WINED3DFMT_NULL)
rt_mask &= ~(1 << i);
i++;
@ -2435,8 +2440,14 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
}
else
{
context_apply_fbo_state(context, GL_FRAMEBUFFER, fb->render_targets, fb->depth_stencil,
fb->render_targets[0]->container->resource.draw_binding);
unsigned int i;
for (i = 0; i < context->gl_info->limits.buffers; ++i)
{
context->blit_targets[i] = wined3d_rendertarget_view_get_surface(fb->render_targets[i]);
}
context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, fb->depth_stencil,
fb->render_targets[0]->resource->draw_binding);
}
}

View File

@ -31,7 +31,7 @@ enum wined3d_cs_op
WINED3D_CS_OP_DRAW,
WINED3D_CS_OP_SET_VIEWPORT,
WINED3D_CS_OP_SET_SCISSOR_RECT,
WINED3D_CS_OP_SET_RENDER_TARGET,
WINED3D_CS_OP_SET_RENDERTARGET_VIEW,
WINED3D_CS_OP_SET_DEPTH_STENCIL,
WINED3D_CS_OP_SET_VERTEX_DECLARATION,
WINED3D_CS_OP_SET_STREAM_SOURCE,
@ -95,11 +95,11 @@ struct wined3d_cs_set_scissor_rect
const RECT *rect;
};
struct wined3d_cs_set_render_target
struct wined3d_cs_set_rendertarget_view
{
enum wined3d_cs_op opcode;
UINT render_target_idx;
struct wined3d_surface *render_target;
unsigned int view_idx;
struct wined3d_rendertarget_view *view;
};
struct wined3d_cs_set_depth_stencil
@ -346,23 +346,23 @@ void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
cs->ops->submit(cs);
}
static void wined3d_cs_exec_set_render_target(struct wined3d_cs *cs, const void *data)
static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_set_render_target *op = data;
const struct wined3d_cs_set_rendertarget_view *op = data;
cs->state.fb->render_targets[op->render_target_idx] = op->render_target;
cs->state.fb->render_targets[op->view_idx] = op->view;
device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
}
void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx,
struct wined3d_surface *render_target)
void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx,
struct wined3d_rendertarget_view *view)
{
struct wined3d_cs_set_render_target *op;
struct wined3d_cs_set_rendertarget_view *op;
op = cs->ops->require_space(cs, sizeof(*op));
op->opcode = WINED3D_CS_OP_SET_RENDER_TARGET;
op->render_target_idx = render_target_idx;
op->render_target = render_target;
op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW;
op->view_idx = view_idx;
op->view = view;
cs->ops->submit(cs);
}
@ -851,7 +851,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
/* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
/* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
/* WINED3D_CS_OP_SET_RENDER_TARGET */ wined3d_cs_exec_set_render_target,
/* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
/* WINED3D_CS_OP_SET_DEPTH_STENCIL */ wined3d_cs_exec_set_depth_stencil,
/* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
/* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source,

View File

@ -286,8 +286,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color,
float depth, DWORD stencil)
{
struct wined3d_surface *target = rt_count ? wined3d_rendertarget_view_get_surface(fb->render_targets[0]) : NULL;
const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL;
struct wined3d_surface *target = rt_count ? fb->render_targets[0] : NULL;
const struct wined3d_gl_info *gl_info;
UINT drawable_width, drawable_height;
struct wined3d_context *context;
@ -308,7 +308,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
{
for (i = 0; i < rt_count; ++i)
{
struct wined3d_surface *rt = fb->render_targets[i];
struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]);
if (rt)
surface_load_location(rt, rt->container->resource.draw_binding);
}
@ -386,7 +386,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
{
for (i = 0; i < rt_count; ++i)
{
struct wined3d_surface *rt = fb->render_targets[i];
struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]);
if (rt)
{
@ -851,11 +851,10 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi
{
for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
{
wined3d_device_set_render_target(device, i, NULL, FALSE);
wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
}
if (swapchain->back_buffers && swapchain->back_buffers[0])
wined3d_device_set_render_target(device, 0,
surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)), TRUE);
if (device->back_buffer_view)
wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, TRUE);
}
wined3d_device_set_depth_stencil(device, ds_enable ? device->auto_depth_stencil : NULL);
@ -904,6 +903,14 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
goto err_out;
}
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);
goto err_out;
}
device->swapchain_count = 1;
device->swapchains = HeapAlloc(GetProcessHeap(), 0, device->swapchain_count * sizeof(*device->swapchains));
if (!device->swapchains)
@ -964,6 +971,8 @@ err_out:
HeapFree(GetProcessHeap(), 0, device->fb.render_targets);
HeapFree(GetProcessHeap(), 0, device->swapchains);
device->swapchain_count = 0;
if (device->back_buffer_view)
wined3d_rendertarget_view_decref(device->back_buffer_view);
if (swapchain)
wined3d_swapchain_decref(swapchain);
if (device->blit_priv)
@ -1083,7 +1092,12 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
for (i = 0; i < gl_info->limits.buffers; ++i)
{
wined3d_device_set_render_target(device, i, NULL, FALSE);
wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
}
if (device->back_buffer_view)
{
wined3d_rendertarget_view_decref(device->back_buffer_view);
device->back_buffer_view = NULL;
}
context_release(context);
@ -3213,8 +3227,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou
}
else if (flags & WINED3DCLEAR_TARGET)
{
if (ds->resource.width < device->fb.render_targets[0]->resource.width
|| ds->resource.height < device->fb.render_targets[0]->resource.height)
if (ds->resource.width < device->fb.render_targets[0]->width
|| ds->resource.height < device->fb.render_targets[0]->height)
{
WARN("Silently ignoring depth and target clear with mismatching sizes\n");
return WINED3D_OK;
@ -3532,11 +3546,10 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device
if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE]
|| state->render_states[WINED3D_RS_STENCILENABLE])
{
struct wined3d_rendertarget_view *rt = device->fb.render_targets[0];
struct wined3d_surface *ds = device->fb.depth_stencil;
struct wined3d_surface *target = device->fb.render_targets[0];
if(ds && target
&& (ds->resource.width < target->resource.width || ds->resource.height < target->resource.height))
if(ds && rt && (ds->resource.width < rt->width || ds->resource.height < rt->height))
{
WARN("Depth stencil is smaller than the color buffer, returning D3DERR_CONFLICTINGRENDERSTATE\n");
return WINED3DERR_CONFLICTINGRENDERSTATE;
@ -3769,18 +3782,18 @@ void CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
ERR("Color fill failed, hr %#x.\n", hr);
}
struct wined3d_surface * CDECL wined3d_device_get_render_target(const struct wined3d_device *device,
UINT render_target_idx)
struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device,
unsigned int view_idx)
{
TRACE("device %p, render_target_idx %u.\n", device, render_target_idx);
TRACE("device %p, view_idx %u.\n", device, view_idx);
if (render_target_idx >= device->adapter->gl_info.limits.buffers)
if (view_idx >= device->adapter->gl_info.limits.buffers)
{
WARN("Only %u render targets are supported.\n", device->adapter->gl_info.limits.buffers);
return NULL;
}
return device->fb.render_targets[render_target_idx];
return device->fb.render_targets[view_idx];
}
struct wined3d_surface * CDECL wined3d_device_get_depth_stencil(const struct wined3d_device *device)
@ -3790,61 +3803,61 @@ struct wined3d_surface * CDECL wined3d_device_get_depth_stencil(const struct win
return device->fb.depth_stencil;
}
HRESULT CDECL wined3d_device_set_render_target(struct wined3d_device *device,
UINT render_target_idx, struct wined3d_surface *render_target, BOOL set_viewport)
HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device,
unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport)
{
struct wined3d_surface *prev;
struct wined3d_rendertarget_view *prev;
TRACE("device %p, render_target_idx %u, render_target %p, set_viewport %#x.\n",
device, render_target_idx, render_target, set_viewport);
TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n",
device, view_idx, view, set_viewport);
if (render_target_idx >= device->adapter->gl_info.limits.buffers)
if (view_idx >= device->adapter->gl_info.limits.buffers)
{
WARN("Only %u render targets are supported.\n", device->adapter->gl_info.limits.buffers);
return WINED3DERR_INVALIDCALL;
}
if (render_target && !(render_target->resource.usage & WINED3DUSAGE_RENDERTARGET))
if (view && !(view->resource->usage & WINED3DUSAGE_RENDERTARGET))
{
WARN("Surface %p doesn't have render target usage.\n", render_target);
WARN("View resource %p doesn't have render target usage.\n", view->resource);
return WINED3DERR_INVALIDCALL;
}
/* Set the viewport and scissor rectangles, if requested. Tests show that
* stateblock recording is ignored, the change goes directly into the
* primary stateblock. */
if (!render_target_idx && set_viewport)
if (!view_idx && set_viewport)
{
struct wined3d_state *state = &device->state;
state->viewport.x = 0;
state->viewport.y = 0;
state->viewport.width = render_target->resource.width;
state->viewport.height = render_target->resource.height;
state->viewport.width = view->width;
state->viewport.height = view->height;
state->viewport.min_z = 0.0f;
state->viewport.max_z = 1.0f;
wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
state->scissor_rect.top = 0;
state->scissor_rect.left = 0;
state->scissor_rect.right = render_target->resource.width;
state->scissor_rect.bottom = render_target->resource.height;
state->scissor_rect.right = view->width;
state->scissor_rect.bottom = view->height;
wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
}
prev = device->fb.render_targets[render_target_idx];
if (render_target == prev)
prev = device->fb.render_targets[view_idx];
if (view == prev)
return WINED3D_OK;
if (render_target)
wined3d_surface_incref(render_target);
device->fb.render_targets[render_target_idx] = render_target;
wined3d_cs_emit_set_render_target(device->cs, render_target_idx, render_target);
if (view)
wined3d_rendertarget_view_incref(view);
device->fb.render_targets[view_idx] = view;
wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view);
/* Release after the assignment, to prevent device_resource_released()
* from seeing the surface as still in use. */
if (prev)
wined3d_surface_decref(prev);
wined3d_rendertarget_view_decref(prev);
return WINED3D_OK;
}
@ -4242,11 +4255,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
{
for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
{
wined3d_device_set_render_target(device, i, NULL, FALSE);
wined3d_device_set_rendertarget_view(device, i, NULL, FALSE);
}
if (swapchain->back_buffers && swapchain->back_buffers[0])
wined3d_device_set_render_target(device, 0,
surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)), FALSE);
}
wined3d_device_set_depth_stencil(device, NULL);
@ -4439,6 +4449,19 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
}
}
if (device->back_buffer_view)
{
wined3d_rendertarget_view_decref(device->back_buffer_view);
device->back_buffer_view = NULL;
}
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
|| DisplayModeChanged)
{
@ -4521,22 +4544,24 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
device_init_swapchain_state(device, swapchain);
}
else
else if (device->back_buffer_view)
{
struct wined3d_surface *rt = device->fb.render_targets[0];
struct wined3d_rendertarget_view *view = device->back_buffer_view;
struct wined3d_state *state = &device->state;
wined3d_device_set_rendertarget_view(device, 0, view, FALSE);
/* Note the min_z / max_z is not reset. */
state->viewport.x = 0;
state->viewport.y = 0;
state->viewport.width = rt->resource.width;
state->viewport.height = rt->resource.height;
state->viewport.width = view->width;
state->viewport.height = view->height;
wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
state->scissor_rect.top = 0;
state->scissor_rect.left = 0;
state->scissor_rect.right = rt->resource.width;
state->scissor_rect.bottom = rt->resource.height;
state->scissor_rect.right = view->width;
state->scissor_rect.bottom = view->height;
wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
}
@ -4627,7 +4652,7 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
{
if (device->fb.render_targets[i] == surface)
if (wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]) == surface)
{
ERR("Surface %p is still in use as render target %u.\n", surface, i);
device->fb.render_targets[i] = NULL;

View File

@ -613,7 +613,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
/* 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 = device->fb.render_targets[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);
@ -622,7 +622,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
}
}
context = context_acquire(device, device->fb.render_targets[0]);
context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]));
if (!context->valid)
{
context_release(context);

View File

@ -1257,7 +1257,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
{
float ycorrection[] =
{
context->render_offscreen ? 0.0f : fb->render_targets[0]->resource.height,
context->render_offscreen ? 0.0f : fb->render_targets[0]->height,
context->render_offscreen ? 1.0f : -1.0f,
0.0f,
0.0f,

View File

@ -2036,8 +2036,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE])
{
const struct wined3d_surface *rt = state->fb->render_targets[0];
if (rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
const struct wined3d_format *rt_format = state->fb->render_targets[0]->format;
if (rt_format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
{
static unsigned int warned = 0;

View File

@ -381,7 +381,7 @@ static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_fo
static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_surface *target = state->fb->render_targets[0];
const struct wined3d_format *rt_format = state->fb->render_targets[0]->format;
const struct wined3d_gl_info *gl_info = context->gl_info;
GLenum srcBlend, dstBlend;
enum wined3d_blend d3d_blend;
@ -395,8 +395,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
/* Disable blending in all cases even without pixelshaders.
* With blending on we could face a big performance penalty.
* The d3d9 visual test confirms the behavior. */
if (context->render_offscreen
&& !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
if (context->render_offscreen && !(rt_format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
{
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
checkGLcall("glDisable GL_BLEND");
@ -432,9 +431,8 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
}
else
{
srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
target->resource.format);
srcBlend = gl_blend_factor(d3d_blend, rt_format);
dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND], rt_format);
}
if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
@ -484,9 +482,8 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
}
else
{
srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
target->resource.format);
srcBlendAlpha = gl_blend_factor(d3d_blend, rt_format);
dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA], rt_format);
}
GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
@ -4637,14 +4634,14 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta
static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_surface *target = state->fb->render_targets[0];
const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_viewport vp = state->viewport;
if (vp.width > target->resource.width)
vp.width = target->resource.width;
if (vp.height > target->resource.height)
vp.height = target->resource.height;
if (vp.width > target->width)
vp.width = target->width;
if (vp.height > target->height)
vp.height = target->height;
gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
checkGLcall("glDepthRange");
@ -4658,7 +4655,7 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
{
UINT width, height;
surface_get_drawable_size(target, context, &width, &height);
surface_get_drawable_size(wined3d_rendertarget_view_get_surface(target), context, &width, &height);
gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
vp.width, vp.height);
}
@ -4817,11 +4814,11 @@ static void scissorrect(struct wined3d_context *context, const struct wined3d_st
}
else
{
const struct wined3d_surface *target = state->fb->render_targets[0];
const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
UINT height;
UINT width;
surface_get_drawable_size(target, context, &width, &height);
surface_get_drawable_size(wined3d_rendertarget_view_get_surface(target), context, &width, &height);
gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
}
checkGLcall("glScissor");
@ -4884,13 +4881,13 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state
void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_format *rt_format = state->fb->render_targets[0]->format;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_surface *rt = state->fb->render_targets[0];
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
&& rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
&& rt_format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
else
gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);

View File

@ -3977,6 +3977,7 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
enum wined3d_texture_filter_type filter)
{
struct wined3d_device *device = dst_surface->resource.device;
const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]);
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_swapchain *src_swapchain, *dst_swapchain;
@ -4009,9 +4010,7 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
}
/* Early sort out of cases where no render target is used */
if (!dst_swapchain && !src_swapchain
&& src_surface != device->fb.render_targets[0]
&& dst_surface != device->fb.render_targets[0])
if (!dst_swapchain && !src_swapchain && src_surface != rt && dst_surface != rt)
{
TRACE("No surface is render target, not using hardware blit.\n");
return WINED3DERR_INVALIDCALL;
@ -4040,16 +4039,16 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
if (dst_swapchain)
{
/* Handled with regular texture -> swapchain blit */
if (src_surface == device->fb.render_targets[0])
if (src_surface == rt)
TRACE("Blit from active render target to a swapchain\n");
}
else if (src_swapchain && dst_surface == device->fb.render_targets[0])
else if (src_swapchain && dst_surface == rt)
{
FIXME("Implement blit from a swapchain to the active render target\n");
return WINED3DERR_INVALIDCALL;
}
if ((src_swapchain || src_surface == device->fb.render_targets[0]) && !dst_swapchain)
if ((src_swapchain || src_surface == rt) && !dst_swapchain)
{
/* Blit from render target to texture */
BOOL stretchx;
@ -4899,9 +4898,19 @@ static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d
const RECT *dst_rect, const struct wined3d_color *color)
{
const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height};
struct wined3d_fb_state fb = {&dst_surface, NULL};
struct wined3d_rendertarget_view *view;
struct wined3d_fb_state fb = {&view, NULL};
HRESULT hr;
if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface,
NULL, &wined3d_null_parent_ops, &view)))
{
ERR("Failed to create rendertarget view, hr %#x.\n", hr);
return hr;
}
device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0);
wined3d_rendertarget_view_decref(view);
return WINED3D_OK;
}
@ -5901,7 +5910,7 @@ cpu:
}
static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container,
const struct wined3d_resource_desc *desc, GLenum target, GLint level, DWORD flags)
const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer, DWORD flags)
{
struct wined3d_device *device = container->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@ -5983,6 +5992,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
surface->resource.map_binding = WINED3D_LOCATION_SYSMEM;
surface->texture_target = target;
surface->texture_level = level;
surface->texture_layer = layer;
/* Call the private setup routine */
if (FAILED(hr = surface->surface_ops->surface_private_setup(surface)))
@ -6010,7 +6020,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
}
HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
GLenum target, GLint level, DWORD flags, struct wined3d_surface **surface)
GLenum target, unsigned int level, unsigned int layer, DWORD flags, struct wined3d_surface **surface)
{
struct wined3d_device_parent *device_parent = container->resource.device->device_parent;
const struct wined3d_parent_ops *parent_ops;
@ -6019,15 +6029,15 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w
HRESULT hr;
TRACE("container %p, width %u, height %u, format %s, usage %s (%#x), pool %s, "
"multisample_type %#x, multisample_quality %u, target %#x, level %d, flags %#x, surface %p.\n",
"multisample_type %#x, multisample_quality %u, target %#x, level %u, layer %u, flags %#x, surface %p.\n",
container, desc->width, desc->height, debug_d3dformat(desc->format),
debug_d3dusage(desc->usage), desc->usage, debug_d3dpool(desc->pool),
desc->multisample_type, desc->multisample_quality, target, level, flags, surface);
desc->multisample_type, desc->multisample_quality, target, level, layer, flags, surface);
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = surface_init(object, container, desc, target, level, flags)))
if (FAILED(hr = surface_init(object, container, desc, target, level, layer, flags)))
{
WARN("Failed to initialize surface, returning %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);

View File

@ -907,7 +907,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
struct wined3d_surface *surface;
if (FAILED(hr = wined3d_surface_create(texture, &surface_desc,
cube_targets[j], i, surface_flags, &surface)))
cube_targets[j], i, j, surface_flags, &surface)))
{
WARN("Failed to create surface, hr %#x.\n", hr);
wined3d_texture_cleanup(texture);
@ -1061,7 +1061,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
struct wined3d_surface *surface;
if (FAILED(hr = wined3d_surface_create(texture, &surface_desc,
texture->target, i, surface_flags, &surface)))
texture->target, i, 0, surface_flags, &surface)))
{
WARN("Failed to create surface, hr %#x.\n", hr);
wined3d_texture_cleanup(texture);

View File

@ -3213,7 +3213,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
unsigned int i;
DWORD ttff;
DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
const struct wined3d_surface *rt = state->fb->render_targets[0];
const struct wined3d_format *rt_format = state->fb->render_targets[0]->format;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
@ -3427,7 +3427,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
}
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
&& state->render_states[WINED3D_RS_SRGBWRITEENABLE]
&& rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
&& rt_format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
{
settings->sRGB_write = 1;
} else {

View File

@ -41,6 +41,9 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v
if (!refcount)
{
/* Call wined3d_object_destroyed() before releasing the resource,
* since releasing the resource may end up destroying the parent. */
view->parent_ops->wined3d_object_destroyed(view->parent);
wined3d_resource_decref(view->resource);
HeapFree(GetProcessHeap(), 0, view);
}
@ -55,6 +58,29 @@ void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertar
return view->parent;
}
void * CDECL wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view *view)
{
struct wined3d_resource *sub_resource;
TRACE("view %p.\n", view);
if (view->resource->type == WINED3D_RTYPE_BUFFER)
return wined3d_buffer_get_parent(buffer_from_resource(view->resource));
if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(view->resource),
view->sub_resource_idx)))
return NULL;
return wined3d_resource_get_parent(sub_resource);
}
void CDECL wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent)
{
TRACE("view %p, parent %p.\n", view, parent);
view->parent = parent;
}
struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view)
{
TRACE("view %p.\n", view);
@ -63,7 +89,8 @@ struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const str
}
static void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
const struct wined3d_rendertarget_view_desc *desc, struct wined3d_resource *resource, void *parent)
const struct wined3d_rendertarget_view_desc *desc, struct wined3d_resource *resource,
void *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info;
@ -71,6 +98,7 @@ static void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *vie
view->resource = resource;
wined3d_resource_incref(resource);
view->parent = parent;
view->parent_ops = parent_ops;
view->format = wined3d_get_format(gl_info, desc->format_id);
if (resource->type == WINED3D_RTYPE_BUFFER)
@ -97,7 +125,8 @@ static void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *vie
}
HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc,
struct wined3d_resource *resource, void *parent, struct wined3d_rendertarget_view **view)
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view)
{
struct wined3d_rendertarget_view *object;
@ -107,10 +136,25 @@ HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_rendertarget
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
wined3d_rendertarget_view_init(object, desc, resource, parent);
wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops);
TRACE("Created render target view %p.\n", object);
*view = object;
return WINED3D_OK;
}
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)
{
struct wined3d_rendertarget_view_desc desc;
TRACE("surface %p, view %p.\n", surface, view);
desc.format_id = surface->resource.format->id;
desc.u.texture.level_idx = surface->texture_level;
desc.u.texture.layer_idx = surface->texture_layer;
desc.u.texture.layer_count = 1;
return wined3d_rendertarget_view_create(&desc, &surface->container->resource, parent, parent_ops, view);
}

View File

@ -75,7 +75,7 @@
@ cdecl wined3d_device_get_ps_sampler(ptr long)
@ cdecl wined3d_device_get_raster_status(ptr long ptr)
@ cdecl wined3d_device_get_render_state(ptr long)
@ cdecl wined3d_device_get_render_target(ptr long)
@ cdecl wined3d_device_get_rendertarget_view(ptr long)
@ cdecl wined3d_device_get_sampler_state(ptr long long)
@ cdecl wined3d_device_get_scissor_rect(ptr ptr)
@ cdecl wined3d_device_get_software_vertex_processing(ptr)
@ -130,7 +130,7 @@
@ cdecl wined3d_device_set_ps_consts_i(ptr long ptr long)
@ cdecl wined3d_device_set_ps_sampler(ptr long ptr)
@ cdecl wined3d_device_set_render_state(ptr long long)
@ cdecl wined3d_device_set_render_target(ptr long ptr long)
@ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long)
@ cdecl wined3d_device_set_sampler_state(ptr long long long)
@ cdecl wined3d_device_set_scissor_rect(ptr ptr)
@ cdecl wined3d_device_set_software_vertex_processing(ptr long)
@ -177,11 +177,14 @@
@ cdecl wined3d_resource_set_parent(ptr ptr)
@ cdecl wined3d_resource_set_priority(ptr long)
@ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr)
@ 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_decref(ptr)
@ cdecl wined3d_rendertarget_view_get_parent(ptr)
@ cdecl wined3d_rendertarget_view_get_resource(ptr)
@ cdecl wined3d_rendertarget_view_get_sub_resource_parent(ptr)
@ cdecl wined3d_rendertarget_view_incref(ptr)
@ cdecl wined3d_rendertarget_view_set_parent(ptr ptr)
@ cdecl wined3d_sampler_create(ptr ptr)
@ cdecl wined3d_sampler_decref(ptr)

View File

@ -1175,7 +1175,7 @@ struct wined3d_context
struct wined3d_fb_state
{
struct wined3d_surface **render_targets;
struct wined3d_rendertarget_view **render_targets;
struct wined3d_surface *depth_stencil;
};
@ -1945,6 +1945,7 @@ struct wined3d_device
struct wined3d_device_creation_parameters create_parms;
HWND focus_window;
struct wined3d_rendertarget_view *back_buffer_view;
struct wined3d_swapchain **swapchains;
UINT swapchain_count;
@ -2262,8 +2263,9 @@ struct wined3d_surface
GLuint pbo;
GLuint rb_multisample;
GLuint rb_resolved;
GLint texture_level;
GLenum texture_target;
unsigned int texture_level;
unsigned int texture_layer;
RECT lockedRect;
int lockCount;
@ -2323,7 +2325,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
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,
GLenum target, GLint level, DWORD flags, struct wined3d_surface **surface) DECLSPEC_HIDDEN;
GLenum target, unsigned int level, unsigned int layer, DWORD flags,
struct wined3d_surface **surface) DECLSPEC_HIDDEN;
void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
@ -2509,8 +2512,8 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff
void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs,
enum wined3d_render_state state, DWORD value) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx,
struct wined3d_surface *render_target) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx,
struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
UINT sampler_idx, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx,
@ -2617,6 +2620,7 @@ struct wined3d_rendertarget_view
struct wined3d_resource *resource;
void *parent;
const struct wined3d_parent_ops *parent_ops;
const struct wined3d_format *format;
unsigned int sub_resource_idx;
@ -2627,6 +2631,25 @@ struct wined3d_rendertarget_view
unsigned int depth;
};
static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface(
const struct wined3d_rendertarget_view *view)
{
struct wined3d_resource *resource;
struct wined3d_texture *texture;
if (!view)
return NULL;
if (view->resource->type != WINED3D_RTYPE_TEXTURE && view->resource->type != WINED3D_RTYPE_CUBE_TEXTURE)
return NULL;
texture = wined3d_texture_from_resource(view->resource);
if (!(resource = wined3d_texture_get_sub_resource(texture, view->sub_resource_idx)))
return NULL;
return surface_from_resource(resource);
}
struct wined3d_swapchain_ops
{
void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect,

View File

@ -2154,8 +2154,8 @@ struct wined3d_sampler * __cdecl wined3d_device_get_ps_sampler(const struct wine
HRESULT __cdecl wined3d_device_get_raster_status(const struct wined3d_device *device,
UINT swapchain_idx, struct wined3d_raster_status *raster_status);
DWORD __cdecl wined3d_device_get_render_state(const struct wined3d_device *device, enum wined3d_render_state state);
struct wined3d_surface * __cdecl wined3d_device_get_render_target(const struct wined3d_device *device,
UINT render_target_idx);
struct wined3d_rendertarget_view * __cdecl wined3d_device_get_rendertarget_view(const struct wined3d_device *device,
unsigned int view_idx);
DWORD __cdecl wined3d_device_get_sampler_state(const struct wined3d_device *device,
UINT sampler_idx, enum wined3d_sampler_state state);
void __cdecl wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect);
@ -2238,8 +2238,8 @@ HRESULT __cdecl wined3d_device_set_ps_consts_i(struct wined3d_device *device,
void __cdecl wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler);
void __cdecl wined3d_device_set_render_state(struct wined3d_device *device,
enum wined3d_render_state state, DWORD value);
HRESULT __cdecl wined3d_device_set_render_target(struct wined3d_device *device,
UINT render_target_idx, struct wined3d_surface *render_target, BOOL set_viewport);
HRESULT __cdecl wined3d_device_set_rendertarget_view(struct wined3d_device *device,
unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport);
void __cdecl wined3d_device_set_sampler_state(struct wined3d_device *device,
UINT sampler_idx, enum wined3d_sampler_state state, DWORD value);
void __cdecl wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect);
@ -2377,11 +2377,16 @@ void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void
DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority);
HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc,
struct wined3d_resource *resource, void *parent, struct wined3d_rendertarget_view **view);
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);
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);
void * __cdecl wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view *view);
ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view);
void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent);
HRESULT __cdecl wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler);
ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler);