wined3d: Store render target info instead of surfaces in "blit_targets".
In preparation for extending render target views support. Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
90bf175f4d
commit
26b7baa0dd
|
@ -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,
|
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,
|
struct wined3d_surface *depth_stencil, DWORD color_location,
|
||||||
DWORD ds_location)
|
DWORD ds_location)
|
||||||
{
|
{
|
||||||
UINT i;
|
unsigned int i;
|
||||||
|
|
||||||
key->rb_namespace = 0;
|
key->rb_namespace = 0;
|
||||||
context_set_fbo_key_for_surface(context, key, 0, depth_stencil, ds_location);
|
context_set_fbo_key_for_surface(context, key, 0, depth_stencil, ds_location);
|
||||||
|
|
||||||
for (i = 0; i < context->gl_info->limits.buffers; ++i)
|
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,
|
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)
|
DWORD color_location, DWORD ds_location)
|
||||||
{
|
{
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
|
unsigned int object_count = gl_info->limits.buffers + 1;
|
||||||
struct fbo_entry *entry;
|
struct fbo_entry *entry;
|
||||||
UINT object_count = gl_info->limits.buffers + 1;
|
|
||||||
|
|
||||||
entry = HeapAlloc(GetProcessHeap(), 0,
|
entry = HeapAlloc(GetProcessHeap(), 0,
|
||||||
FIELD_OFFSET(struct fbo_entry, key.objects[object_count]));
|
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. */
|
/* Context activation is done by the caller. */
|
||||||
static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
|
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)
|
DWORD color_location, DWORD ds_location, struct fbo_entry *entry)
|
||||||
{
|
{
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
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. */
|
/* Context activation is done by the caller. */
|
||||||
static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
|
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)
|
DWORD color_location, DWORD ds_location)
|
||||||
{
|
{
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
unsigned int object_count = gl_info->limits.buffers + 1;
|
unsigned int object_count = gl_info->limits.buffers + 1;
|
||||||
struct wined3d_texture *rt_texture, *ds_texture;
|
struct wined3d_texture *rt_texture, *ds_texture;
|
||||||
struct fbo_entry *entry;
|
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;
|
ds_texture = depth_stencil->container;
|
||||||
|
|
||||||
if (wined3d_texture_get_level_width(ds_texture, depth_stencil->texture_level)
|
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(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");
|
WARN("Depth stencil is smaller than the primary color buffer, disabling.\n");
|
||||||
depth_stencil = NULL;
|
depth_stencil = NULL;
|
||||||
|
@ -535,7 +554,7 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
|
||||||
depth_stencil = NULL;
|
depth_stencil = NULL;
|
||||||
}
|
}
|
||||||
else
|
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,
|
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");
|
TRACE("Dumping FBO attachments:\n");
|
||||||
for (i = 0; i < gl_info->limits.buffers; ++i)
|
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;
|
unsigned int width, height;
|
||||||
TRACE(" Color attachment %u: %p format %s, %s %u, %ux%u, %u samples.\n",
|
const char *resource_type;
|
||||||
i, render_targets[i], debug_d3dformat(rt_texture->resource.format->id),
|
|
||||||
context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : "texture",
|
if (resource->type == WINED3D_RTYPE_BUFFER)
|
||||||
context->fbo_key->objects[i + 1].object,
|
{
|
||||||
wined3d_texture_get_level_pow2_width(rt_texture, render_targets[i]->texture_level),
|
width = resource->size;
|
||||||
wined3d_texture_get_level_pow2_height(rt_texture, render_targets[i]->texture_level),
|
height = 1;
|
||||||
rt_texture->resource.multisample_type);
|
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)
|
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. */
|
/* Context activation is done by the caller. */
|
||||||
static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
|
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)
|
DWORD color_location, DWORD ds_location)
|
||||||
{
|
{
|
||||||
struct fbo_entry *entry, *entry2;
|
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,
|
void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
|
||||||
struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
|
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);
|
memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof(*context->blit_targets));
|
||||||
|
if (render_target)
|
||||||
context->blit_targets[0] = render_target;
|
{
|
||||||
if (clear_size)
|
context->blit_targets[0].resource = &render_target->container->resource;
|
||||||
memset(&context->blit_targets[1], 0, clear_size);
|
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);
|
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;
|
struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
DWORD rt_mask = 0, *cur_mask;
|
DWORD rt_mask = 0, *cur_mask;
|
||||||
UINT i;
|
unsigned int i;
|
||||||
|
|
||||||
if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
|
if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
|
||||||
|| rt_count != gl_info->limits.buffers)
|
|| 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))
|
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)
|
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)
|
if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
|
||||||
rt_mask |= (1u << i);
|
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,
|
context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
|
||||||
wined3d_rendertarget_view_get_surface(dsv),
|
wined3d_rendertarget_view_get_surface(dsv),
|
||||||
rt_count ? rts[0]->resource->draw_binding : 0,
|
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;
|
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)
|
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,
|
context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
|
||||||
wined3d_rendertarget_view_get_surface(fb->depth_stencil),
|
wined3d_rendertarget_view_get_surface(fb->depth_stencil),
|
||||||
|
|
|
@ -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. */
|
* 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. */
|
/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
|
||||||
/* Context activation is done by the caller. */
|
/* 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;
|
const struct wined3d_gl_info *gl_info = &surface->container->resource.device->adapter->gl_info;
|
||||||
struct wined3d_renderbuffer_entry *entry;
|
struct wined3d_renderbuffer_entry *entry;
|
||||||
GLuint renderbuffer = 0;
|
|
||||||
unsigned int src_width, src_height;
|
unsigned int src_width, src_height;
|
||||||
unsigned int width, 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);
|
struct wined3d_texture *texture;
|
||||||
height = wined3d_texture_get_level_pow2_height(rt->container, rt->texture_level);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -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_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;
|
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
|
#define MAX_GL_FRAGMENT_SAMPLERS 32
|
||||||
|
|
||||||
struct wined3d_context
|
struct wined3d_context
|
||||||
|
@ -1728,7 +1734,7 @@ struct wined3d_context
|
||||||
struct fbo_entry *current_fbo;
|
struct fbo_entry *current_fbo;
|
||||||
GLuint fbo_read_binding;
|
GLuint fbo_read_binding;
|
||||||
GLuint fbo_draw_binding;
|
GLuint fbo_draw_binding;
|
||||||
struct wined3d_surface **blit_targets;
|
struct wined3d_rendertarget_info *blit_targets;
|
||||||
struct wined3d_fbo_entry_key *fbo_key;
|
struct wined3d_fbo_entry_key *fbo_key;
|
||||||
GLenum *draw_buffers;
|
GLenum *draw_buffers;
|
||||||
DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */
|
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 wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
|
||||||
const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
|
const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
struct wined3d_surface;
|
||||||
|
|
||||||
enum wined3d_blit_op
|
enum wined3d_blit_op
|
||||||
{
|
{
|
||||||
WINED3D_BLIT_OP_COLOR_BLIT,
|
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,
|
BOOL surface_load_location(struct wined3d_surface *surface,
|
||||||
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
|
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
|
||||||
void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
|
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;
|
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,
|
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;
|
struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue