diff --git a/dlls/d3d11/view.c b/dlls/d3d11/view.c index a6eddf59ce3..40037989eb3 100644 --- a/dlls/d3d11/view.c +++ b/dlls/d3d11/view.c @@ -1216,6 +1216,11 @@ static void wined3d_depth_stencil_view_desc_from_d3d11(struct wined3d_view_desc FIXME("Unhandled depth stencil view flags %#x.\n", desc->Flags); wined3d_desc->flags = 0; + if (desc->Flags & D3D11_DSV_READ_ONLY_DEPTH) + wined3d_desc->flags |= WINED3D_VIEW_READ_ONLY_DEPTH; + if (desc->Flags & D3D11_DSV_READ_ONLY_STENCIL) + wined3d_desc->flags |= WINED3D_VIEW_READ_ONLY_STENCIL; + wined3d_desc->u.texture.level_count = 1; switch (desc->ViewDimension) { diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e9750c41c50..f4c0d46f8e6 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3696,7 +3696,7 @@ static void context_preload_texture(struct wined3d_context *context, if (!(texture = state->textures[idx])) return; - if (wined3d_resource_check_fbo_attached(state, &texture->resource)) + if (wined3d_resource_check_fbo_attached(state, &texture->resource, NULL)) context->uses_fbo_attached_resources = 1; wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[idx])); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b2aa33af41f..2a4d3778486 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2239,7 +2239,7 @@ static void wined3d_device_set_shader_resource_view(struct wined3d_device *devic if (view == prev) return; - if (view && wined3d_resource_check_fbo_attached(&device->state, view->resource)) + if (view && wined3d_resource_check_fbo_attached(&device->state, view->resource, view->format)) { WARN("Application is trying to bind resource which is attached as render target.\n"); view = NULL; @@ -4991,7 +4991,7 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(c } static void wined3d_unbind_srv_for_rtv(struct wined3d_device *device, - const struct wined3d_rendertarget_view *view) + const struct wined3d_rendertarget_view *view, BOOL dsv) { if (view && view->resource->srv_bind_count_device) { @@ -5003,7 +5003,8 @@ static void wined3d_unbind_srv_for_rtv(struct wined3d_device *device, for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j) - if ((srv = device->state.shader_resource_view[i][j]) && srv->resource == resource) + if ((srv = device->state.shader_resource_view[i][j]) && srv->resource == resource + && (!dsv || wined3d_dsv_srv_conflict(view, srv->format))) wined3d_device_set_shader_resource_view(device, i, j, NULL); } } @@ -5066,7 +5067,7 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device if (prev) wined3d_rendertarget_view_decref(prev); - wined3d_unbind_srv_for_rtv(device, view); + wined3d_unbind_srv_for_rtv(device, view, FALSE); return WINED3D_OK; } @@ -5098,7 +5099,7 @@ HRESULT CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *devic if (prev) wined3d_rendertarget_view_decref(prev); - wined3d_unbind_srv_for_rtv(device, view); + wined3d_unbind_srv_for_rtv(device, view, TRUE); return WINED3D_OK; } diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index cc217c73224..ac821ce732a 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3785,18 +3785,27 @@ static BOOL init_typeless_formats(const struct wined3d_adapter *adapter) typeless_format->flags[j] &= ~(WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); } - if ((format_id = typeless_depth_stencil_formats[i].depth_view_id) - && typeless_depth_stencil_formats[i].separate_depth_view_format) + if ((format_id = typeless_depth_stencil_formats[i].depth_view_id)) { if (!(depth_view_format = get_format_internal(adapter, format_id))) return FALSE; - copy_format(adapter, depth_view_format, ds_format); + if (typeless_depth_stencil_formats[i].separate_depth_view_format) + { + copy_format(adapter, depth_view_format, ds_format); + depth_view_format->stencil_size = 0; + } + else + { + depth_view_format->depth_size = ds_format->depth_size; + } } if ((format_id = typeless_depth_stencil_formats[i].stencil_view_id)) { if (!(stencil_view_format = get_format_internal(adapter, format_id))) return FALSE; copy_format(adapter, stencil_view_format, ds_format); + if (typeless_depth_stencil_formats[i].separate_depth_view_format) + stencil_view_format->depth_size = 0; } } diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 6710abb270f..eeca7c868bf 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -65,11 +65,13 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D}, {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY}, }; + unsigned int flags = desc->flags & (WINED3D_VIEW_BUFFER_RAW | WINED3D_VIEW_BUFFER_APPEND + | WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY); unsigned int i; for (i = 0; i < ARRAY_SIZE(view_types); ++i) { - if (view_types[i].texture_target != texture_gl->target || view_types[i].view_flags != desc->flags) + if (view_types[i].texture_target != texture_gl->target || view_types[i].view_flags != flags) continue; if (gl_info->supported[view_types[i].extension]) return view_types[i].view_target; @@ -77,7 +79,7 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info, FIXME("Extension %#x not supported.\n", view_types[i].extension); } - FIXME("Unhandled view flags %#x for texture target %#x.\n", desc->flags, texture_gl->target); + FIXME("Unhandled view flags %#x for texture target %#x.\n", flags, texture_gl->target); return texture_gl->target; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4f48687f7d6..82161c90340 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5289,14 +5289,23 @@ static inline void wined3d_context_copy_bo_address(struct wined3d_context *conte dst, dst_bind_flags, src, src_bind_flags, size); } +static inline BOOL wined3d_dsv_srv_conflict(const struct wined3d_rendertarget_view *dsv, + const struct wined3d_format *srv_format) +{ + return srv_format && ((srv_format->depth_size && !(dsv->desc.flags & WINED3D_VIEW_READ_ONLY_DEPTH)) + || (srv_format->stencil_size && !(dsv->desc.flags & WINED3D_VIEW_READ_ONLY_STENCIL))); +} + static inline BOOL wined3d_resource_check_fbo_attached(const struct wined3d_state *state, - const struct wined3d_resource *resource) + const struct wined3d_resource *resource, const struct wined3d_format *srv_format) { struct wined3d_rendertarget_view * const *rts = &state->fb->render_targets[0]; + const struct wined3d_rendertarget_view *dsv; unsigned int i; if ((resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL) - && state->fb->depth_stencil && state->fb->depth_stencil->resource == resource) + && (dsv = state->fb->depth_stencil) && dsv->resource == resource + && wined3d_dsv_srv_conflict(dsv, srv_format)) return TRUE; if (!(resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 27a0e58a28d..0b535475d0d 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1579,6 +1579,8 @@ enum wined3d_shader_type #define WINED3D_VIEW_BUFFER_COUNTER 0x00000004 #define WINED3D_VIEW_TEXTURE_CUBE 0x00000008 #define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010 +#define WINED3D_VIEW_READ_ONLY_DEPTH 0x00000020 +#define WINED3D_VIEW_READ_ONLY_STENCIL 0x00000040 #define WINED3D_MAX_VIEWPORTS 16