From 507bd1ae169f6304810baabc190a25c12ad33896 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Wed, 17 Mar 2021 19:45:17 -0500 Subject: [PATCH] wined3d: Introduce wined3d_device_context_set_rendertarget_view(). Signed-off-by: Zebediah Figura Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/device.c | 171 ++++++++++++++++++++++++---------------------- dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 2 + 3 files changed, 93 insertions(+), 81 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 382e72055a4..e7b57a34595 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2284,6 +2284,94 @@ void CDECL wined3d_device_context_set_unordered_access_view(struct wined3d_devic wined3d_unordered_access_view_decref(prev); } +static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_context *context, + const struct wined3d_rendertarget_view *view, BOOL dsv) +{ + struct wined3d_state *state = context->state; + + if (view && wined3d_is_rtv_srv_bound(view)) + { + const struct wined3d_resource *resource = view->resource; + const struct wined3d_shader_resource_view *srv; + unsigned int i, j; + + WARN("Application sets bound resource as render target.\n"); + + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j) + if ((srv = state->shader_resource_view[i][j]) && srv->resource == resource + && ((!dsv && wined3d_is_srv_rtv_bound(srv)) + || (dsv && wined3d_dsv_srv_conflict(view, srv->format)))) + wined3d_device_context_set_shader_resource_view(context, i, j, NULL); + } +} + +HRESULT CDECL wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, + unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) +{ + struct wined3d_state *state = context->state; + struct wined3d_rendertarget_view *prev; + unsigned int max_rt_count; + + TRACE("context %p, view_idx %u, view %p, set_viewport %#x.\n", + context, view_idx, view, set_viewport); + + max_rt_count = context->device->adapter->d3d_info.limits.max_rt_count; + if (view_idx >= max_rt_count) + { + WARN("Only %u render targets are supported.\n", max_rt_count); + return WINED3DERR_INVALIDCALL; + } + + if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) + { + WARN("View resource %p doesn't have render target bind flags.\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 (!view_idx && set_viewport) + { + state->viewports[0].x = 0; + state->viewports[0].y = 0; + state->viewports[0].width = view->width; + state->viewports[0].height = view->height; + state->viewports[0].min_z = 0.0f; + state->viewports[0].max_z = 1.0f; + state->viewport_count = 1; + wined3d_device_context_emit_set_viewports(context, 1, state->viewports); + + SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); + state->scissor_rect_count = 1; + wined3d_device_context_emit_set_scissor_rects(context, 1, state->scissor_rects); + } + + prev = state->fb.render_targets[view_idx]; + if (view == prev) + return WINED3D_OK; + + if (view) + { + wined3d_rendertarget_view_incref(view); + wined3d_rtv_bind_count_inc(view); + } + state->fb.render_targets[view_idx] = view; + wined3d_device_context_emit_set_rendertarget_view(context, view_idx, view); + /* Release after the assignment, to prevent device_resource_released() + * from seeing the surface as still in use. */ + if (prev) + { + wined3d_rtv_bind_count_dec(prev); + wined3d_rendertarget_view_decref(prev); + } + + wined3d_device_context_unbind_srv_for_rtv(context, view, FALSE); + + return WINED3D_OK; +} + void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { TRACE("device %p, shader %p.\n", device, shader); @@ -5172,92 +5260,13 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(c return device->cs->c.state->fb.depth_stencil; } -static void wined3d_unbind_srv_for_rtv(struct wined3d_device *device, - const struct wined3d_rendertarget_view *view, BOOL dsv) -{ - struct wined3d_state *state = device->cs->c.state; - - if (view && wined3d_is_rtv_srv_bound(view)) - { - const struct wined3d_resource *resource = view->resource; - const struct wined3d_shader_resource_view *srv; - unsigned int i, j; - - WARN("Application sets bound resource as render target.\n"); - - for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) - for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j) - if ((srv = state->shader_resource_view[i][j]) && srv->resource == resource - && ((!dsv && wined3d_is_srv_rtv_bound(srv)) - || (dsv && wined3d_dsv_srv_conflict(view, srv->format)))) - wined3d_device_context_set_shader_resource_view(&device->cs->c, i, j, NULL); - } -} - 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_state *state = device->cs->c.state; - struct wined3d_rendertarget_view *prev; - unsigned int max_rt_count; - TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", device, view_idx, view, set_viewport); - max_rt_count = device->adapter->d3d_info.limits.max_rt_count; - if (view_idx >= max_rt_count) - { - WARN("Only %u render targets are supported.\n", max_rt_count); - return WINED3DERR_INVALIDCALL; - } - - if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) - { - WARN("View resource %p doesn't have render target bind flags.\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 (!view_idx && set_viewport) - { - state->viewports[0].x = 0; - state->viewports[0].y = 0; - state->viewports[0].width = view->width; - state->viewports[0].height = view->height; - state->viewports[0].min_z = 0.0f; - state->viewports[0].max_z = 1.0f; - state->viewport_count = 1; - wined3d_device_context_emit_set_viewports(&device->cs->c, 1, state->viewports); - - SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); - state->scissor_rect_count = 1; - wined3d_device_context_emit_set_scissor_rects(&device->cs->c, 1, state->scissor_rects); - } - - prev = state->fb.render_targets[view_idx]; - if (view == prev) - return WINED3D_OK; - - if (view) - { - wined3d_rendertarget_view_incref(view); - wined3d_rtv_bind_count_inc(view); - } - state->fb.render_targets[view_idx] = view; - wined3d_device_context_emit_set_rendertarget_view(&device->cs->c, view_idx, view); - /* Release after the assignment, to prevent device_resource_released() - * from seeing the surface as still in use. */ - if (prev) - { - wined3d_rtv_bind_count_dec(prev); - wined3d_rendertarget_view_decref(prev); - } - - wined3d_unbind_srv_for_rtv(device, view, FALSE); - - return WINED3D_OK; + return wined3d_device_context_set_rendertarget_view(&device->cs->c, view_idx, view, set_viewport); } HRESULT CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, @@ -5287,7 +5296,7 @@ HRESULT CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *devic wined3d_cs_emit_set_depth_stencil_view(device->cs, view); if (prev) wined3d_rendertarget_view_decref(prev); - wined3d_unbind_srv_for_rtv(device, view, TRUE); + wined3d_device_context_unbind_srv_for_rtv(&device->cs->c, view, TRUE); return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 9655c1a65f2..ad66cef0f9c 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -170,6 +170,7 @@ @ cdecl wined3d_device_context_set_constant_buffer(ptr long long ptr) @ cdecl wined3d_device_context_set_depth_stencil_state(ptr ptr long) @ cdecl wined3d_device_context_set_rasterizer_state(ptr ptr) +@ cdecl wined3d_device_context_set_rendertarget_view(ptr long ptr long) @ cdecl wined3d_device_context_set_sampler(ptr long long ptr) @ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_context_set_shader(ptr long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 38b4d8d792d..e066e688125 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2563,6 +2563,8 @@ void __cdecl wined3d_device_context_set_depth_stencil_state(struct wined3d_devic struct wined3d_depth_stencil_state *depth_stencil_state, unsigned int stencil_ref); void __cdecl wined3d_device_context_set_rasterizer_state(struct wined3d_device_context *context, struct wined3d_rasterizer_state *rasterizer_state); +HRESULT __cdecl wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, + unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport); void __cdecl wined3d_device_context_set_sampler(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int idx, struct wined3d_sampler *sampler); void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_context *context, unsigned int rect_count, -- 2.11.4.GIT