From 26b7baa0dd5c5e511231c0022a9ff495459d0458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 6 Apr 2017 11:47:50 +0200 Subject: [PATCH] wined3d: Store render target info instead of surfaces in "blit_targets". MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for extending render target views support. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/context.c | 112 ++++++++++++++++++++++----------- dlls/wined3d/surface.c | 21 +++++-- dlls/wined3d/wined3d_private.h | 12 +++- 3 files changed, 102 insertions(+), 43 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 2e9b38ae300..a472a1ed87b 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -427,26 +427,44 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context } static void context_generate_fbo_key(const struct wined3d_context *context, - struct wined3d_fbo_entry_key *key, struct wined3d_surface **render_targets, + struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { - UINT i; + unsigned int i; key->rb_namespace = 0; context_set_fbo_key_for_surface(context, key, 0, depth_stencil, ds_location); for (i = 0; i < context->gl_info->limits.buffers; ++i) - context_set_fbo_key_for_surface(context, key, i + 1, render_targets[i], color_location); + { + struct wined3d_surface *surface = NULL; + struct wined3d_resource *resource; + + if ((resource = render_targets[i].resource)) + { + if (resource->type == WINED3D_RTYPE_TEXTURE_2D) + { + struct wined3d_texture *texture = wined3d_texture_from_resource(resource); + surface = texture->sub_resources[render_targets[i].sub_resource_idx].u.surface; + } + else + { + FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + } + } + + context_set_fbo_key_for_surface(context, key, i + 1, surface, color_location); + } } static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int object_count = gl_info->limits.buffers + 1; struct fbo_entry *entry; - UINT object_count = gl_info->limits.buffers + 1; entry = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(struct fbo_entry, key.objects[object_count])); @@ -470,7 +488,7 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context * /* Context activation is done by the caller. */ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location, struct fbo_entry *entry) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -504,24 +522,25 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb /* Context activation is done by the caller. */ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int object_count = gl_info->limits.buffers + 1; struct wined3d_texture *rt_texture, *ds_texture; struct fbo_entry *entry; - unsigned int i; + unsigned int i, level; - if (depth_stencil && render_targets[0]) + if (depth_stencil && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER) { - rt_texture = render_targets[0]->container; + rt_texture = wined3d_texture_from_resource(render_targets[0].resource); + level = render_targets[0].sub_resource_idx % rt_texture->level_count; ds_texture = depth_stencil->container; if (wined3d_texture_get_level_width(ds_texture, depth_stencil->texture_level) - < wined3d_texture_get_level_width(rt_texture, render_targets[0]->texture_level) + < wined3d_texture_get_level_width(rt_texture, level) || wined3d_texture_get_level_height(ds_texture, depth_stencil->texture_level) - < wined3d_texture_get_level_height(rt_texture, render_targets[0]->texture_level)) + < wined3d_texture_get_level_height(rt_texture, level)) { WARN("Depth stencil is smaller than the primary color buffer, disabling.\n"); depth_stencil = NULL; @@ -535,7 +554,7 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, depth_stencil = NULL; } else - surface_set_compatible_renderbuffer(depth_stencil, render_targets[0]); + surface_set_compatible_renderbuffer(depth_stencil, &render_targets[0]); } context_generate_fbo_key(context, context->fbo_key, render_targets, depth_stencil, color_location, @@ -546,16 +565,31 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, TRACE("Dumping FBO attachments:\n"); for (i = 0; i < gl_info->limits.buffers; ++i) { - if (render_targets[i]) + struct wined3d_resource *resource; + if ((resource = render_targets[i].resource)) { - rt_texture = render_targets[i]->container; - TRACE(" Color attachment %u: %p format %s, %s %u, %ux%u, %u samples.\n", - i, render_targets[i], debug_d3dformat(rt_texture->resource.format->id), - context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : "texture", - context->fbo_key->objects[i + 1].object, - wined3d_texture_get_level_pow2_width(rt_texture, render_targets[i]->texture_level), - wined3d_texture_get_level_pow2_height(rt_texture, render_targets[i]->texture_level), - rt_texture->resource.multisample_type); + unsigned int width, height; + const char *resource_type; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + width = resource->size; + height = 1; + resource_type = "buffer"; + } + else + { + rt_texture = wined3d_texture_from_resource(resource); + level = render_targets[i].sub_resource_idx % rt_texture->level_count; + width = wined3d_texture_get_level_pow2_width(rt_texture, level); + height = wined3d_texture_get_level_pow2_height(rt_texture, level); + resource_type = "texture"; + } + + TRACE(" Color attachment %u: %p, %u format %s, %s %u, %ux%u, %u samples.\n", + i, resource, render_targets[i].sub_resource_idx, debug_d3dformat(resource->format->id), + context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : resource_type, + context->fbo_key->objects[i + 1].object, width, height, resource->multisample_type); } } if (depth_stencil) @@ -642,7 +676,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ /* Context activation is done by the caller. */ static void context_apply_fbo_state(struct wined3d_context *context, GLenum target, - struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, + struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil, DWORD color_location, DWORD ds_location) { struct fbo_entry *entry, *entry2; @@ -675,11 +709,12 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) { - UINT clear_size = (context->gl_info->limits.buffers - 1) * sizeof(*context->blit_targets); - - context->blit_targets[0] = render_target; - if (clear_size) - memset(&context->blit_targets[1], 0, clear_size); + memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof(*context->blit_targets)); + if (render_target) + { + context->blit_targets[0].resource = &render_target->container->resource; + context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target); + } context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location); } @@ -2664,7 +2699,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win struct wined3d_rendertarget_view *dsv = fb->depth_stencil; const struct wined3d_gl_info *gl_info = context->gl_info; DWORD rt_mask = 0, *cur_mask; - UINT i; + unsigned int i; if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb || rt_count != gl_info->limits.buffers) @@ -2678,17 +2713,17 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource)) { + memset(context->blit_targets, 0, gl_info->limits.buffers * sizeof(*context->blit_targets)); for (i = 0; i < rt_count; ++i) { - context->blit_targets[i] = wined3d_rendertarget_view_get_surface(rts[i]); + if (rts[i]) + { + context->blit_targets[i].resource = rts[i]->resource; + context->blit_targets[i].sub_resource_idx = rts[i]->sub_resource_idx; + } if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL) rt_mask |= (1u << i); } - while (i < gl_info->limits.buffers) - { - context->blit_targets[i] = NULL; - ++i; - } context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, wined3d_rendertarget_view_get_surface(dsv), rt_count ? rts[0]->resource->draw_binding : 0, @@ -2811,9 +2846,14 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat { unsigned int i; + memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof (*context->blit_targets)); for (i = 0; i < context->gl_info->limits.buffers; ++i) { - context->blit_targets[i] = wined3d_rendertarget_view_get_surface(fb->render_targets[i]); + if (fb->render_targets[i]) + { + context->blit_targets[i].resource = fb->render_targets[i]->resource; + context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx; + } } context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, wined3d_rendertarget_view_get_surface(fb->depth_stencil), diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index cc5444bb598..8a1ad4e44e3 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -980,18 +980,29 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P * render target dimensions. With FBOs, the dimensions have to be an exact match. */ /* TODO: We should synchronize the renderbuffer's content with the texture's content. */ /* Context activation is done by the caller. */ -void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_surface *rt) +void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt) { const struct wined3d_gl_info *gl_info = &surface->container->resource.device->adapter->gl_info; struct wined3d_renderbuffer_entry *entry; - GLuint renderbuffer = 0; unsigned int src_width, src_height; unsigned int width, height; + GLuint renderbuffer = 0; - if (rt && rt->container->resource.format->id != WINED3DFMT_NULL) + if (rt && rt->resource->format->id != WINED3DFMT_NULL) { - width = wined3d_texture_get_level_pow2_width(rt->container, rt->texture_level); - height = wined3d_texture_get_level_pow2_height(rt->container, rt->texture_level); + struct wined3d_texture *texture; + unsigned int level; + + if (rt->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type)); + return; + } + texture = wined3d_texture_from_resource(rt->resource); + level = rt->sub_resource_idx % texture->level_count; + + width = wined3d_texture_get_level_pow2_width(texture, level); + height = wined3d_texture_get_level_pow2_height(texture, level); } else { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c824e2be094..4d7b9de12df 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1632,6 +1632,12 @@ struct wined3d_timestamp_query void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; +struct wined3d_rendertarget_info +{ + struct wined3d_resource *resource; + unsigned int sub_resource_idx; +}; + #define MAX_GL_FRAGMENT_SAMPLERS 32 struct wined3d_context @@ -1728,7 +1734,7 @@ struct wined3d_context struct fbo_entry *current_fbo; GLuint fbo_read_binding; GLuint fbo_draw_binding; - struct wined3d_surface **blit_targets; + struct wined3d_rendertarget_info *blit_targets; struct wined3d_fbo_entry_key *fbo_key; GLenum *draw_buffers; DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */ @@ -1858,6 +1864,8 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN; +struct wined3d_surface; + enum wined3d_blit_op { WINED3D_BLIT_OP_COLOR_BLIT, @@ -3064,7 +3072,7 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, - const struct wined3d_surface *rt) DECLSPEC_HIDDEN; + const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN; void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;