From b30589cbd3dd61a8bb27757fecd536cb559732ad Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 17 Sep 2019 12:39:23 -0700 Subject: [PATCH] mesa/st: Reuse st_choose_matching_format from st_choose_format(). We had this ad-hoc exact size matching for unsized internalformats, but st_choose_matching_format() can do exactly what we want. This means, that, for example, we'll now prefer the matching ordering for 565/565_REV if the driver supports both orders. We also pass Unpack.SwapBytes through from ChooseTextureFormat so that we can hit the memcpy path for 8888 formats when that flag is set. Some interesting format choice changes from this (on softpipe): intf/form/type before after ---------------------------------------------------- RGBA/RGBA/USHORT: R8G8B8A8_UNORM -> RGBA_UNORM16 RGB/RGBA/8888: X8B8G8R8_UNORM -> R8G8B8X8_UNORM RGB/ABGR/8888_REV: X8B8G8R8_UNORM -> R8G8B8X8_UNORM RGBA/RGBA/5551: B5G5R5A1_UNORM -> A1B5G5R5_UNORM RGBA/RGBA/4444: R8G8B8A8_UNORM -> A4B4G4R4_UNORM RGBA/GL_RGBA/1010102: R8G8B8A8_UNORM -> A2B10G10R10_UNORM DEPTH/DEPTH/UINT: Z24X8 -> Z_UNORM32 DEPTH/DEPTH/USHORT: Z24X8 -> Z_UNORM16 v2: Make sure that the baseformat still matches. v1 would pick MESA_FORMAT_L16_UNORM for RED/LUMINANCE/SHORT, when we clearly want a red format. Reviewed-by: Kenneth Graunke --- src/mesa/state_tracker/st_cb_drawpixels.c | 15 +-- src/mesa/state_tracker/st_cb_texture.c | 3 +- src/mesa/state_tracker/st_format.c | 111 ++++++---------------- src/mesa/state_tracker/st_format.h | 2 +- src/mesa/state_tracker/st_texture.c | 2 +- 5 files changed, 39 insertions(+), 94 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 2a59566abef..6b47548d33b 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -642,7 +642,8 @@ make_texture(struct st_context *st, pipeFormat = st_choose_format(st, intFormat, format, type, st->internal_target, 0, 0, - PIPE_BIND_SAMPLER_VIEW, FALSE); + PIPE_BIND_SAMPLER_VIEW, + false, false); assert(pipeFormat != PIPE_FORMAT_NONE); } @@ -1772,7 +1773,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, if (type == GL_DEPTH) { srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE, GL_NONE, st->internal_target, 0, 0, - srcBind, FALSE); + srcBind, false, false); } else { assert(type == GL_COLOR); @@ -1780,27 +1781,27 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, if (util_format_is_float(srcFormat)) { srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE, GL_NONE, st->internal_target, 0, 0, - srcBind, FALSE); + srcBind, false, false); } else if (util_format_is_pure_sint(srcFormat)) { srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE, GL_NONE, st->internal_target, 0, 0, - srcBind, FALSE); + srcBind, false, false); } else if (util_format_is_pure_uint(srcFormat)) { srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE, GL_NONE, st->internal_target, 0, 0, - srcBind, FALSE); + srcBind, false, false); } else if (util_format_is_snorm(srcFormat)) { srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE, GL_NONE, st->internal_target, 0, 0, - srcBind, FALSE); + srcBind, false, false); } else { srcFormat = st_choose_format(st, GL_RGBA, GL_NONE, GL_NONE, st->internal_target, 0, 0, - srcBind, FALSE); + srcBind, false, false); } } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 5954d424249..ace19c59b0e 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -2090,7 +2090,8 @@ st_GetTexSubImage(struct gl_context * ctx, } dst_format = st_choose_format(st, dst_glformat, format, type, - pipe_target, 0, 0, bind, FALSE); + pipe_target, 0, 0, bind, + false, false); if (dst_format == PIPE_FORMAT_NONE) { /* unable to get an rgba format!?! */ diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 396254afbea..c0e9e25c71d 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -1078,78 +1078,6 @@ find_supported_format(struct pipe_screen *screen, return PIPE_FORMAT_NONE; } - -struct exact_format_mapping -{ - GLenum format; - GLenum type; - enum pipe_format pformat; -}; - -static const struct exact_format_mapping rgba8888_tbl[] = -{ - { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_ABGR8888_UNORM }, - { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_ABGR8888_UNORM }, - { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_RGBA8888_UNORM }, - { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_RGBA8888_UNORM }, - { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_ARGB8888_UNORM }, - { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_BGRA8888_UNORM }, - { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8A8_UNORM }, - { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_A8B8G8R8_UNORM }, - { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8A8_UNORM }, - { 0, 0, 0 } -}; - -static const struct exact_format_mapping rgbx8888_tbl[] = -{ - { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_XBGR8888_UNORM }, - { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_XBGR8888_UNORM }, - { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_RGBX8888_UNORM }, - { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_RGBX8888_UNORM }, - { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_XRGB8888_UNORM }, - { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_BGRX8888_UNORM }, - { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8X8_UNORM }, - { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_X8B8G8R8_UNORM }, - { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8X8_UNORM }, - { 0, 0, 0 } -}; - - -/** - * For unsized/base internal formats, we may choose a convenient effective - * internal format for {format, type}. If one exists, return that, otherwise - * return PIPE_FORMAT_NONE. - */ -static enum pipe_format -find_exact_format(GLint internalFormat, GLenum format, GLenum type) -{ - uint i; - const struct exact_format_mapping* tbl; - - if (format == GL_NONE || type == GL_NONE) - return PIPE_FORMAT_NONE; - - switch (internalFormat) { - case 4: - case GL_RGBA: - tbl = rgba8888_tbl; - break; - case 3: - case GL_RGB: - tbl = rgbx8888_tbl; - break; - default: - return PIPE_FORMAT_NONE; - } - - for (i = 0; tbl[i].format; i++) - if (tbl[i].format == format && tbl[i].type == type) - return tbl[i].pformat; - - return PIPE_FORMAT_NONE; -} - - /** * Given an OpenGL internalFormat value for a texture or surface, return * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match. @@ -1172,7 +1100,7 @@ st_choose_format(struct st_context *st, GLenum internalFormat, GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, unsigned storage_sample_count, - unsigned bindings, boolean allow_dxt) + unsigned bindings, bool swap_bytes, bool allow_dxt) { struct pipe_screen *screen = st->pipe->screen; unsigned i; @@ -1185,12 +1113,23 @@ st_choose_format(struct st_context *st, GLenum internalFormat, return PIPE_FORMAT_NONE; } - /* search for exact matches */ - pf = find_exact_format(internalFormat, format, type); - if (pf != PIPE_FORMAT_NONE && - screen->is_format_supported(screen, pf, target, sample_count, - storage_sample_count, bindings)) { - goto success; + /* If we have an unsized internalFormat, and the driver supports a format + * that exactly matches format/type such that we can just memcpy, pick that + * (unless the format wouldn't still be unorm, which is the expectation for + * unsized formats). + */ + if (_mesa_is_enum_format_unsized(internalFormat) && format != 0 && + _mesa_is_type_unsigned(type)) { + pf = st_choose_matching_format(st, bindings, format, type, + swap_bytes); + + if (pf != PIPE_FORMAT_NONE && + screen->is_format_supported(screen, pf, target, sample_count, + storage_sample_count, bindings) && + _mesa_get_format_base_format(st_pipe_format_to_mesa_format(pf)) == + internalFormat) { + goto success; + } } /* For an unsized GL_RGB but a 2_10_10_10 type, try to pick one of the @@ -1261,7 +1200,8 @@ st_choose_renderbuffer_format(struct st_context *st, bindings = PIPE_BIND_RENDER_TARGET; return st_choose_format(st, internalFormat, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, sample_count, - storage_sample_count, bindings, FALSE); + storage_sample_count, bindings, + false, false); } @@ -1382,13 +1322,14 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target, } pFormat = st_choose_format(st, internalFormat, format, type, - pTarget, 0, 0, bindings, GL_TRUE); + pTarget, 0, 0, bindings, + ctx->Unpack.SwapBytes, true); if (pFormat == PIPE_FORMAT_NONE && !is_renderbuffer) { /* try choosing format again, this time without render target bindings */ pFormat = st_choose_format(st, internalFormat, format, type, pTarget, 0, 0, PIPE_BIND_SAMPLER_VIEW, - GL_TRUE); + ctx->Unpack.SwapBytes, true); } if (pFormat == PIPE_FORMAT_NONE) { @@ -1445,7 +1386,8 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target, /* Set sample counts in descending order. */ for (i = 16; i > 1; i--) { format = st_choose_format(st, internalFormat, GL_NONE, GL_NONE, - PIPE_TEXTURE_2D, i, i, bind, FALSE); + PIPE_TEXTURE_2D, i, i, bind, + false, false); if (format != PIPE_FORMAT_NONE) { samples[num_sample_counts++] = i; @@ -1505,7 +1447,8 @@ st_QueryInternalFormat(struct gl_context *ctx, GLenum target, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, 0, - bindings, FALSE); + bindings, + false, false); if (pformat) params[0] = internalFormat; break; diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 036d3378286..0a8e3bc921f 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -55,7 +55,7 @@ st_choose_format(struct st_context *st, GLenum internalFormat, GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, unsigned storage_sample_count, - unsigned bindings, boolean allow_dxt); + unsigned bindings, bool swap_bytes, bool allow_dxt); extern enum pipe_format st_choose_renderbuffer_format(struct st_context *st, diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 72fc4a0c09b..a2a310daab4 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -416,7 +416,7 @@ st_create_color_map_texture(struct gl_context *ctx) /* find an RGBA texture format */ format = st_choose_format(st, GL_RGBA, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW, - FALSE); + false, false); /* create texture for color map/table */ pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0, -- 2.30.2