From 5d3b8ad24bf1f8ff7682a1489630d234b7c31b6a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 12 Feb 2013 22:09:24 +0100 Subject: [PATCH] st/mesa: try to find exact format matching user format and type for DrawPixels Reviewed-by: Brian Paul --- src/mesa/state_tracker/st_cb_drawpixels.c | 28 ++++++++++++------ src/mesa/state_tracker/st_cb_texture.c | 30 ++----------------- src/mesa/state_tracker/st_format.c | 35 +++++++++++++++++++++++ src/mesa/state_tracker/st_format.h | 3 ++ 4 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index ba4f17a3da3..e282bf98dbf 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -484,19 +484,29 @@ make_texture(struct st_context *st, gl_format mformat; struct pipe_resource *pt; enum pipe_format pipeFormat; - GLenum baseInternalFormat, intFormat; - - intFormat = internal_format(ctx, format, type); - baseInternalFormat = _mesa_base_tex_format(ctx, intFormat); + GLenum baseInternalFormat; /* Choose a pixel format for the temp texture which will hold the * image to draw. */ - pipeFormat = st_choose_format(st, intFormat, format, type, - PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, - FALSE); - assert(pipeFormat != PIPE_FORMAT_NONE); - mformat = st_pipe_format_to_mesa_format(pipeFormat); + pipeFormat = st_choose_matching_format(pipe->screen, PIPE_BIND_SAMPLER_VIEW, + format, type, unpack->SwapBytes); + + if (pipeFormat != PIPE_FORMAT_NONE) { + mformat = st_pipe_format_to_mesa_format(pipeFormat); + baseInternalFormat = _mesa_get_format_base_format(mformat); + } + else { + /* Use the generic approach. */ + GLenum intFormat = internal_format(ctx, format, type); + + baseInternalFormat = _mesa_base_tex_format(ctx, intFormat); + pipeFormat = st_choose_format(st, intFormat, format, type, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, + FALSE); + assert(pipeFormat != PIPE_FORMAT_NONE); + mformat = st_pipe_format_to_mesa_format(pipeFormat); + } pixels = _mesa_map_pbo_source(ctx, unpack, pixels); if (!pixels) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index ac70e9292ea..f8ff024db0a 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -560,32 +560,6 @@ st_CompressedTexImage(struct gl_context *ctx, GLuint dims, } -static enum pipe_format -choose_matching_format(struct pipe_screen *screen, unsigned bind, - GLenum format, GLenum type, GLboolean swapBytes) -{ - gl_format mesa_format; - - for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) { - if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) { - continue; - } - - if (_mesa_format_matches_format_and_type(mesa_format, format, type, - swapBytes)) { - enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format); - - if (format && - screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, - bind)) { - return format; - } - /* It's unlikely to find 2 matching Mesa formats. */ - break; - } - } - return PIPE_FORMAT_NONE; -} /** @@ -683,8 +657,8 @@ st_GetTexImage(struct gl_context * ctx, /* Choose the destination format by finding the best match * for the format+type combo. */ - dst_format = choose_matching_format(screen, bind, format, type, - ctx->Pack.SwapBytes); + dst_format = st_choose_matching_format(screen, bind, format, type, + ctx->Pack.SwapBytes); if (dst_format == PIPE_FORMAT_NONE) { GLenum dst_glformat; diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 02969b99597..5fd44e76d6a 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -1674,6 +1674,41 @@ st_choose_renderbuffer_format(struct st_context *st, } +/** + * Given an OpenGL user-requested format and type, and swapBytes state, + * return the format which exactly matches those parameters, so that + * a memcpy-based transfer can be done. + * + * If no format is supported, return PIPE_FORMAT_NONE. + */ +enum pipe_format +st_choose_matching_format(struct pipe_screen *screen, unsigned bind, + GLenum format, GLenum type, GLboolean swapBytes) +{ + gl_format mesa_format; + + for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) { + if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) { + continue; + } + + if (_mesa_format_matches_format_and_type(mesa_format, format, type, + swapBytes)) { + enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format); + + if (format && + screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, + bind)) { + return format; + } + /* It's unlikely to find 2 matching Mesa formats. */ + break; + } + } + return PIPE_FORMAT_NONE; +} + + /** * Called via ctx->Driver.ChooseTextureFormat(). */ diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index aee624d2492..3db409b74e0 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -57,6 +57,9 @@ extern enum pipe_format st_choose_renderbuffer_format(struct st_context *st, GLenum internalFormat, unsigned sample_count); +extern enum pipe_format +st_choose_matching_format(struct pipe_screen *screen, unsigned bind, + GLenum format, GLenum type, GLboolean swapBytes); extern gl_format st_ChooseTextureFormat(struct gl_context * ctx, GLenum target, -- 2.30.2