From: Stian Low <wineryyyyy@gmail.com> --- dlls/wined3d/adapter_gl.c | 33 ++++++++++----- dlls/wined3d/context_gl.c | 8 ++-- dlls/wined3d/view.c | 86 +++++++++++++++++++++++++++------------ dlls/wined3d/wined3d_gl.h | 2 +- 4 files changed, 88 insertions(+), 41 deletions(-) diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 085c6ac48bb..60ce15e47b1 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4564,12 +4564,16 @@ static HRESULT adapter_gl_create_rendertarget_view(const struct wined3d_view_des struct wined3d_rendertarget_view **view) { struct wined3d_rendertarget_view_gl *view_gl; + unsigned int count = 1; HRESULT hr; TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); - if (!(view_gl = calloc(1, sizeof(*view_gl)))) + if (resource->type == WINED3D_RTYPE_TEXTURE_2D && texture_from_resource(resource)->swapchain) + count = texture_from_resource(resource)->swapchain->state.desc.backbuffer_count;; + + if (!(view_gl = calloc(1, offsetof(struct wined3d_rendertarget_view_gl, gl_view[count])))) return E_OUTOFMEMORY; if (FAILED(hr = wined3d_rendertarget_view_gl_init(view_gl, desc, resource, parent, parent_ops))) @@ -4588,7 +4592,7 @@ static HRESULT adapter_gl_create_rendertarget_view(const struct wined3d_view_des struct wined3d_view_gl_destroy_ctx { struct wined3d_device *device; - const struct wined3d_gl_view *gl_view; + GLuint name; struct wined3d_bo_user *bo_user; struct wined3d_bo_gl *counter_bo; void *object; @@ -4608,14 +4612,14 @@ static void wined3d_view_gl_destroy_object(void *object) device = ctx->device; counter_id = ctx->counter_bo ? ctx->counter_bo->id : 0; - if (ctx->gl_view->name || counter_id) + if (ctx->name || counter_id) { context = context_acquire(device, NULL, 0); gl_info = wined3d_context_gl(context)->gl_info; - if (ctx->gl_view->name) + if (ctx->name) { - context_gl_resource_released(device, ctx->gl_view->name, FALSE); - gl_info->gl_ops.gl.p_glDeleteTextures(1, &ctx->gl_view->name); + context_gl_resource_released(device, ctx->name, FALSE); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &ctx->name); } if (counter_id) wined3d_context_gl_destroy_bo(wined3d_context_gl(context), ctx->counter_bo); @@ -4629,7 +4633,7 @@ static void wined3d_view_gl_destroy_object(void *object) free(ctx->free); } -static void wined3d_view_gl_destroy(struct wined3d_device *device, const struct wined3d_gl_view *gl_view, +static void wined3d_view_gl_destroy(struct wined3d_device *device, GLuint name, struct wined3d_bo_user *bo_user, struct wined3d_bo_gl *counter_bo, void *object) { struct wined3d_view_gl_destroy_ctx *ctx, c; @@ -4637,7 +4641,7 @@ static void wined3d_view_gl_destroy(struct wined3d_device *device, const struct if (!(ctx = malloc(sizeof(*ctx)))) ctx = &c; ctx->device = device; - ctx->gl_view = gl_view; + ctx->name = name; ctx->bo_user = bo_user; ctx->counter_bo = counter_bo; ctx->object = object; @@ -4656,7 +4660,14 @@ static void adapter_gl_destroy_rendertarget_view(struct wined3d_rendertarget_vie TRACE("view_gl %p.\n", view_gl); wined3d_rendertarget_view_cleanup(&view_gl->v); - wined3d_view_gl_destroy(resource->device, &view_gl->gl_view, NULL, NULL, view_gl); + if (resource->type == WINED3D_RTYPE_TEXTURE_2D && texture_from_resource(resource)->swapchain) + { + unsigned int i; + for (i = 1; i < texture_from_resource(resource)->swapchain->state.desc.backbuffer_count; i++) + wined3d_view_gl_destroy(resource->device, view_gl->gl_view[i].name, NULL, NULL, NULL); + } + + wined3d_view_gl_destroy(resource->device, view_gl->gl_view[0].name, NULL, NULL, view_gl); } static HRESULT adapter_gl_create_shader_resource_view(const struct wined3d_view_desc *desc, @@ -4693,7 +4704,7 @@ static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resour TRACE("view_gl %p.\n", view_gl); wined3d_shader_resource_view_cleanup(&view_gl->v); - wined3d_view_gl_destroy(resource->device, &view_gl->gl_view, &view_gl->bo_user, NULL, view_gl); + wined3d_view_gl_destroy(resource->device, view_gl->gl_view.name, &view_gl->bo_user, NULL, view_gl); } static HRESULT adapter_gl_create_unordered_access_view(const struct wined3d_view_desc *desc, @@ -4730,7 +4741,7 @@ static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_ac TRACE("view_gl %p.\n", view_gl); wined3d_unordered_access_view_cleanup(&view_gl->v); - wined3d_view_gl_destroy(resource->device, &view_gl->gl_view, &view_gl->bo_user, &view_gl->counter_bo, view_gl); + wined3d_view_gl_destroy(resource->device, view_gl->gl_view.name, &view_gl->bo_user, &view_gl->counter_bo, view_gl); } static HRESULT adapter_gl_create_video_decoder_output_view(const struct wined3d_view_desc *desc, diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index e5b41ffc783..33cf754475d 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3235,7 +3235,7 @@ BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, if (rts[i]) { struct wined3d_rendertarget_view_gl *rtv_gl = wined3d_rendertarget_view_gl(rts[i]); - context_gl->blit_targets[i].gl_view = rtv_gl->gl_view; + context_gl->blit_targets[i].gl_view = rtv_gl->gl_view[0]; context_gl->blit_targets[i].resource = rtv_gl->v.resource; context_gl->blit_targets[i].sub_resource_idx = rtv_gl->v.sub_resource_idx; context_gl->blit_targets[i].layer_count = rtv_gl->v.layer_count; @@ -3247,7 +3247,7 @@ BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, if (dsv) { struct wined3d_rendertarget_view_gl *dsv_gl = wined3d_rendertarget_view_gl(dsv); - ds_info.gl_view = dsv_gl->gl_view; + ds_info.gl_view = dsv_gl->gl_view[0]; ds_info.resource = dsv_gl->v.resource; ds_info.sub_resource_idx = dsv_gl->v.sub_resource_idx; ds_info.layer_count = dsv_gl->v.layer_count; @@ -3400,7 +3400,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat continue; view_gl = wined3d_rendertarget_view_gl(fb->render_targets[i]); - context_gl->blit_targets[i].gl_view = view_gl->gl_view; + context_gl->blit_targets[i].gl_view = view_gl->gl_view[0]; context_gl->blit_targets[i].resource = view_gl->v.resource; context_gl->blit_targets[i].sub_resource_idx = view_gl->v.sub_resource_idx; context_gl->blit_targets[i].layer_count = view_gl->v.layer_count; @@ -3412,7 +3412,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat if (fb->depth_stencil) { view_gl = wined3d_rendertarget_view_gl(fb->depth_stencil); - ds_info.gl_view = view_gl->gl_view; + ds_info.gl_view = view_gl->gl_view[0]; ds_info.resource = view_gl->v.resource; ds_info.sub_resource_idx = view_gl->v.sub_resource_idx; ds_info.layer_count = view_gl->v.layer_count; diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index d5bc3492c1e..3b0ca915ecd 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -605,45 +605,81 @@ static void wined3d_render_target_view_gl_cs_init(void *object) struct wined3d_rendertarget_view_gl *view_gl = object; struct wined3d_resource *resource = view_gl->v.resource; const struct wined3d_view_desc *desc = &view_gl->v.desc; + struct wined3d_swapchain_rendertarget_view *lview; + struct wined3d_texture_gl *texture_gl; + struct wined3d_swapchain *swapchain; + unsigned int depth_or_layer_count; + GLenum resource_class, view_class; + struct wined3d_context *context; + unsigned int i; TRACE("view_gl %p.\n", view_gl); if (resource->type == WINED3D_RTYPE_BUFFER) { FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type)); + return; } + + texture_gl = wined3d_texture_gl(texture_from_resource(resource)); + if (resource->type == WINED3D_RTYPE_TEXTURE_3D) + depth_or_layer_count = wined3d_texture_get_level_depth(&texture_gl->t, desc->u.texture.level_idx); else + depth_or_layer_count = texture_gl->t.layer_count; + + if (resource->format->id == view_gl->v.format->id + && (view_gl->v.layer_count == 1 && view_gl->v.layer_count == depth_or_layer_count)) { - struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource)); - unsigned int depth_or_layer_count; + TRACE("Skipping view init because format and layer_count matches underlying texture\n"); + return; + } - if (resource->type == WINED3D_RTYPE_TEXTURE_3D) - depth_or_layer_count = wined3d_texture_get_level_depth(&texture_gl->t, desc->u.texture.level_idx); - else - depth_or_layer_count = texture_gl->t.layer_count; + resource_class = wined3d_format_gl(resource->format)->view_class; + view_class = wined3d_format_gl(view_gl->v.format)->view_class; + if (resource_class != view_class) + { + FIXME("Render target view not supported, resource format %s, view format %s.\n", + debug_d3dformat(resource->format->id), debug_d3dformat(view_gl->v.format->id)); + return; + } - if (resource->format->id != view_gl->v.format->id - || (view_gl->v.layer_count != 1 && view_gl->v.layer_count != depth_or_layer_count)) - { - GLenum resource_class, view_class; + context = context_acquire(resource->device, NULL, 0); + create_texture_view(&view_gl->gl_view[0], texture_gl->target, desc, texture_gl, view_gl->v.format); + context_release(context); - resource_class = wined3d_format_gl(resource->format)->view_class; - view_class = wined3d_format_gl(view_gl->v.format)->view_class; - if (resource_class != view_class) - { - FIXME("Render target view not supported, resource format %s, view format %s.\n", - debug_d3dformat(resource->format->id), debug_d3dformat(view_gl->v.format->id)); - return; - } - if (texture_gl->t.swapchain && texture_gl->t.swapchain->state.desc.backbuffer_count > 1) - { - FIXME("Swapchain views not supported.\n"); - return; - } + if (!view_gl->gl_view[0].name) + { + FIXME("Failed to create render target view for resource %p\n", resource); + /* TODO: cleanup? */ + return; + } - create_texture_view(&view_gl->gl_view, texture_gl->target, desc, texture_gl, view_gl->v.format); - } + if (!(swapchain = texture_gl->t.swapchain)) + return; + + context = context_acquire(resource->device, NULL, 0); + for (i = 1; i < swapchain->state.desc.backbuffer_count; i++) + { + texture_gl = wined3d_texture_gl(swapchain->back_buffers[i]); + create_texture_view(&view_gl->gl_view[i], texture_gl->target, desc, texture_gl, view_gl->v.format); + if (view_gl->gl_view[i].name) + continue; + + ERR("Failed to create render target view for swapchain %p backbuffer[%u]\n", swapchain, i); + /* TODO: cleanup? */ + break; } + context_release(context); + + if (!(lview = calloc(1, sizeof(*lview)))) + { + ERR("Out of memory.\n"); + /* TODO: cleanup? */ + return; + } + + list_add_head(&swapchain->back_buffer_rendertarget_views, &lview->entry); + lview->view = &view_gl->v; } static HRESULT wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index c9c7118c59e..d4cf258d363 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -1081,7 +1081,7 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined struct wined3d_rendertarget_view_gl { struct wined3d_rendertarget_view v; - struct wined3d_gl_view gl_view; + struct wined3d_gl_view gl_view[1]; }; static inline struct wined3d_rendertarget_view_gl *wined3d_rendertarget_view_gl( -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10567