diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 3807e892cd4..253fc52d130 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -43,6 +43,28 @@ struct private_data DWORD size; }; +static DWORD resource_access_from_pool(WINED3DPOOL pool) +{ + switch (pool) + { + case WINED3DPOOL_DEFAULT: + return WINED3D_RESOURCE_ACCESS_GPU; + + case WINED3DPOOL_MANAGED: + return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU; + + case WINED3DPOOL_SYSTEMMEM: + return WINED3D_RESOURCE_ACCESS_CPU; + + case WINED3DPOOL_SCRATCH: + return WINED3D_RESOURCE_ACCESS_SCRATCH; + + default: + FIXME("Unhandled pool %#x.\n", pool); + return 0; + } +} + HRESULT resource_init(struct wined3d_resource *resource, IWineD3DDeviceImpl *device, WINED3DRESOURCETYPE resource_type, const struct wined3d_format *format, WINED3DMULTISAMPLE_TYPE multisample_type, UINT multisample_quality, @@ -58,6 +80,9 @@ HRESULT resource_init(struct wined3d_resource *resource, IWineD3DDeviceImpl *dev resource->multisample_quality = multisample_quality; resource->usage = usage; resource->pool = pool; + resource->access_flags = resource_access_from_pool(pool); + if (usage & WINED3DUSAGE_DYNAMIC) + resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU; resource->width = width; resource->height = height; resource->depth = depth; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index f5245cce7a4..ff841022b78 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -5846,6 +5846,24 @@ void surface_modify_location(struct wined3d_surface *surface, DWORD flag, BOOL p } } +static DWORD resource_access_from_location(DWORD location) +{ + switch (location) + { + case SFLAG_INSYSMEM: + return WINED3D_RESOURCE_ACCESS_CPU; + + case SFLAG_INDRAWABLE: + case SFLAG_INSRGBTEX: + case SFLAG_INTEXTURE: + return WINED3D_RESOURCE_ACCESS_GPU; + + default: + FIXME("Unhandled location %#x.\n", location); + return 0; + } +} + HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const RECT *rect) { IWineD3DDeviceImpl *device = surface->resource.device; @@ -5902,6 +5920,14 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD flag, const return WINED3D_OK; } + if (WARN_ON(d3d_surface)) + { + DWORD required_access = resource_access_from_location(flag); + if ((surface->resource.access_flags & required_access) != required_access) + WARN("Operation requires %#x access, but surface only has %#x.\n", + required_access, surface->resource.access_flags); + } + if (!(surface->flags & SFLAG_LOCATIONS)) { ERR("Surface %p does not have any up to date location.\n", surface); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 199d7ef0d14..549f827ab88 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1798,6 +1798,12 @@ static inline BOOL isStateDirty(struct wined3d_context *context, DWORD state) return context->isStateDirty[idx] & (1 << shift); } +#define WINED3D_RESOURCE_ACCESS_GPU 0x1 +#define WINED3D_RESOURCE_ACCESS_CPU 0x2 +/* SCRATCH is mostly the same as CPU, but can't be used by the GPU at all, + * not even for resource uploads. */ +#define WINED3D_RESOURCE_ACCESS_SCRATCH 0x4 + struct wined3d_resource_ops { void (*resource_unload)(struct wined3d_resource *resource); @@ -1813,6 +1819,7 @@ struct wined3d_resource UINT multisample_quality; DWORD usage; WINED3DPOOL pool; + DWORD access_flags; UINT width; UINT height; UINT depth;