st/mesa: try to find exact format matching user format and type for DrawPixels

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Marek Olšák 2013-02-12 22:09:24 +01:00
parent 2b9659c9e6
commit 5d3b8ad24b
4 changed files with 59 additions and 37 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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().
*/

View file

@ -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,