Commit 9100fce2 authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

wined3d: Move draw_textured_quad() to context.c.

parent 4573903c
......@@ -7901,7 +7901,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
arbfp_blit_set(arbfp_blitter, context, src_texture, src_sub_resource_idx, color_key);
/* Draw a textured quad */
draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter);
context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter);
/* Leave the opengl state valid for blitting */
arbfp_blit_unset(context->gl_info);
......
......@@ -4986,3 +4986,63 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
context_release(context);
}
/* Context activation is done by the caller. */
void context_draw_textured_quad(struct wined3d_context *context, struct wined3d_texture *texture,
unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect,
enum wined3d_texture_filter_type filter)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_blt_info info;
unsigned int level;
texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
gl_info->gl_ops.gl.p_glEnable(info.bind_target);
checkGLcall("glEnable(bind_target)");
level = sub_resource_idx % texture->level_count;
context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
checkGLcall("glTexParameteri");
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER,
wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
checkGLcall("glTexParameteri");
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_BASE_LEVEL, level);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level);
gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
checkGLcall("glTexEnvi");
/* Draw a quad. */
gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom);
gl_info->gl_ops.gl.p_glEnd();
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
context_bind_texture(context, info.bind_target, 0);
/* We changed the filtering settings on the texture. Make sure they get
* reset on subsequent draws. */
texture->texture_rgb.sampler_desc.mag_filter = WINED3D_TEXF_POINT;
texture->texture_rgb.sampler_desc.min_filter = WINED3D_TEXF_POINT;
texture->texture_rgb.sampler_desc.mip_filter = WINED3D_TEXF_NONE;
texture->texture_rgb.sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
texture->texture_rgb.sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
texture->texture_rgb.sampler_desc.srgb_decode = FALSE;
texture->texture_rgb.base_level = level;
}
......@@ -36,199 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM
| WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER;
struct blt_info
{
GLenum bind_target;
struct wined3d_vec3 texcoords[4];
};
struct float_rect
{
float l;
float t;
float r;
float b;
};
static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f)
{
f->l = ((r->left * 2.0f) / w) - 1.0f;
f->t = ((r->top * 2.0f) / h) - 1.0f;
f->r = ((r->right * 2.0f) / w) - 1.0f;
f->b = ((r->bottom * 2.0f) / h) - 1.0f;
}
static void texture2d_get_blt_info(const struct wined3d_texture *texture,
unsigned int sub_resource_idx, const RECT *rect, struct blt_info *info)
{
struct wined3d_vec3 *coords = info->texcoords;
struct float_rect f;
unsigned int level;
GLenum target;
GLsizei w, h;
level = sub_resource_idx % texture->level_count;
w = wined3d_texture_get_level_pow2_width(texture, level);
h = wined3d_texture_get_level_pow2_height(texture, level);
target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
switch (target)
{
default:
FIXME("Unsupported texture target %#x.\n", target);
/* Fall back to GL_TEXTURE_2D */
case GL_TEXTURE_2D:
info->bind_target = GL_TEXTURE_2D;
coords[0].x = (float)rect->left / w;
coords[0].y = (float)rect->top / h;
coords[0].z = 0.0f;
coords[1].x = (float)rect->right / w;
coords[1].y = (float)rect->top / h;
coords[1].z = 0.0f;
coords[2].x = (float)rect->left / w;
coords[2].y = (float)rect->bottom / h;
coords[2].z = 0.0f;
coords[3].x = (float)rect->right / w;
coords[3].y = (float)rect->bottom / h;
coords[3].z = 0.0f;
break;
case GL_TEXTURE_RECTANGLE_ARB:
info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f;
coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f;
coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f;
coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l;
coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r;
coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l;
coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l;
coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r;
coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l;
coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t;
coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t;
coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b;
coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t;
coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t;
coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b;
coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f;
coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f;
coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f;
coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f;
coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f;
coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f;
coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f;
break;
}
}
/* Context activation is done by the caller. */
void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect,
enum wined3d_texture_filter_type filter)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct blt_info info;
unsigned int level;
texture2d_get_blt_info(texture, sub_resource_idx, src_rect, &info);
gl_info->gl_ops.gl.p_glEnable(info.bind_target);
checkGLcall("glEnable(bind_target)");
level = sub_resource_idx % texture->level_count;
context_bind_texture(context, info.bind_target, texture->texture_rgb.name);
/* Filtering for StretchRect */
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter));
checkGLcall("glTexParameteri");
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER,
wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE));
checkGLcall("glTexParameteri");
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_BASE_LEVEL, level);
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, level);
gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
checkGLcall("glTexEnvi");
/* Draw a quad */
gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom);
gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x);
gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom);
gl_info->gl_ops.gl.p_glEnd();
gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
/* Unbind the texture */
context_bind_texture(context, info.bind_target, 0);
/* We changed the filtering settings on the texture. Inform the
* container about this to get the filters reset properly next draw. */
texture->texture_rgb.sampler_desc.mag_filter = WINED3D_TEXF_POINT;
texture->texture_rgb.sampler_desc.min_filter = WINED3D_TEXF_POINT;
texture->texture_rgb.sampler_desc.mip_filter = WINED3D_TEXF_NONE;
texture->texture_rgb.sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
texture->texture_rgb.sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
texture->texture_rgb.sampler_desc.srgb_decode = FALSE;
texture->texture_rgb.base_level = level;
}
/* Works correctly only for <= 4 bpp formats. */
static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
{
......@@ -2632,7 +2439,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
checkGLcall("glAlphaFunc");
}
draw_textured_quad(src_texture, src_sub_resource_idx, context, src_rect, dst_rect, filter);
context_draw_textured_quad(context, src_texture, src_sub_resource_idx, src_rect, dst_rect, filter);
if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST || color_key)
{
......
......@@ -36,6 +36,14 @@ struct wined3d_texture_idx
unsigned int sub_resource_idx;
};
struct wined3d_rect_f
{
float l;
float t;
float r;
float b;
};
static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
{
return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU)
......@@ -133,6 +141,122 @@ static DWORD wined3d_resource_access_from_location(DWORD location)
}
}
static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct wined3d_rect_f *f)
{
f->l = ((r->left * 2.0f) / w) - 1.0f;
f->t = ((r->top * 2.0f) / h) - 1.0f;
f->r = ((r->right * 2.0f) / w) - 1.0f;
f->b = ((r->bottom * 2.0f) / h) - 1.0f;
}
void texture2d_get_blt_info(const struct wined3d_texture *texture,
unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info)
{
struct wined3d_vec3 *coords = info->texcoords;
struct wined3d_rect_f f;
unsigned int level;
GLenum target;
GLsizei w, h;
level = sub_resource_idx % texture->level_count;
w = wined3d_texture_get_level_pow2_width(texture, level);
h = wined3d_texture_get_level_pow2_height(texture, level);
target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
switch (target)
{
default:
FIXME("Unsupported texture target %#x.\n", target);
/* Fall back to GL_TEXTURE_2D */
case GL_TEXTURE_2D:
info->bind_target = GL_TEXTURE_2D;
coords[0].x = (float)rect->left / w;
coords[0].y = (float)rect->top / h;
coords[0].z = 0.0f;
coords[1].x = (float)rect->right / w;
coords[1].y = (float)rect->top / h;
coords[1].z = 0.0f;
coords[2].x = (float)rect->left / w;
coords[2].y = (float)rect->bottom / h;
coords[2].z = 0.0f;
coords[3].x = (float)rect->right / w;
coords[3].y = (float)rect->bottom / h;
coords[3].z = 0.0f;
break;
case GL_TEXTURE_RECTANGLE_ARB:
info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f;
coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f;
coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f;
coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l;
coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r;
coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l;
coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l;
coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r;
coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l;
coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t;
coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t;
coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b;
coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t;
coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t;
coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b;
coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f;
coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f;
coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f;
coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
cube_coords_float(rect, w, h, &f);
coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f;
coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f;
coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f;
coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f;
break;
}
}
static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
{
struct wined3d_texture_sub_resource *sub_resource;
......
......@@ -2154,6 +2154,9 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, stru
const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN;
void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_draw_textured_quad(struct wined3d_context *context, struct wined3d_texture *texture,
unsigned int sub_resource_idx, const RECT *src_rect, const RECT *dst_rect,
enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN;
void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
......@@ -3074,6 +3077,12 @@ struct gl_texture
GLuint name;
};
struct wined3d_blt_info
{
GLenum bind_target;
struct wined3d_vec3 texcoords[4];
};
struct wined3d_texture_ops
{
BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
......@@ -3243,6 +3252,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
const struct wined3d_box *dst_box, struct wined3d_texture *src_texture,
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags,
const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
void texture2d_get_blt_info(const struct wined3d_texture *texture, unsigned int sub_resource_idx,
const RECT *rect, struct wined3d_blt_info *info) DECLSPEC_HIDDEN;
BOOL texture2d_load_drawable(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void texture2d_load_fb_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx,
......@@ -3333,10 +3344,6 @@ struct fbo_entry
} key;
};
void draw_textured_quad(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect,
enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
struct wined3d_sampler
{
struct wine_rb_entry entry;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment