On 06/20/2011 05:31 PM, Stéphane Marchesin wrote:
If possible, we want to match the hardware format to what the app uses. By
doing so, we avoid the need for pixel conversions and therefore greatly speed
up texture uploads.
---
src/mesa/state_tracker/st_atom_pixeltransfer.c | 2 +-
src/mesa/state_tracker/st_cb_drawpixels.c | 10 ++-
src/mesa/state_tracker/st_format.c | 94 +++++++++++++++++++++++-
src/mesa/state_tracker/st_format.h | 1 +
4 files changed, 99 insertions(+), 8 deletions(-)
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c
b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 95b706c..1f833d2 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -94,7 +94,7 @@ create_color_map_texture(struct gl_context *ctx)
const uint texSize = 256; /* simple, and usually perfect */
/* find an RGBA texture format */
- format = st_choose_format(pipe->screen, GL_RGBA,
+ format = st_choose_format(pipe->screen, GL_RGBA, GL_NONE, GL_NONE,
PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
/* create texture for color map/table */
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c
b/src/mesa/state_tracker/st_cb_drawpixels.c
index 965fbcd..c730975 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -989,8 +989,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
/* can we write to stencil if not fallback */
if (!pipe->screen->get_param(pipe->screen,
PIPE_CAP_SHADER_STENCIL_EXPORT))
goto stencil_fallback;
-
+
tex_format = st_choose_format(st->pipe->screen, base_format(format),
+ GL_NONE, GL_NONE,
PIPE_TEXTURE_2D,
0, PIPE_BIND_SAMPLER_VIEW);
if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
@@ -1399,13 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint
srcy,
/* srcFormat can't be used as a texture format */
if (type == GL_DEPTH) {
texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
- st->internal_target, sample_count,
- PIPE_BIND_DEPTH_STENCIL);
+ st->internal_target, GL_NONE, GL_NONE,
+ sample_count, PIPE_BIND_DEPTH_STENCIL);
assert(texFormat != PIPE_FORMAT_NONE);
}
else {
/* default color format */
- texFormat = st_choose_format(screen, GL_RGBA, st->internal_target,
+ texFormat = st_choose_format(screen, GL_RGBA,
+ st->internal_target, GL_NONE, GL_NONE,
sample_count, PIPE_BIND_SAMPLER_VIEW);
assert(texFormat != PIPE_FORMAT_NONE);
}
diff --git a/src/mesa/state_tracker/st_format.c
b/src/mesa/state_tracker/st_format.c
index 45e4766..6f43c03 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1124,6 +1124,87 @@ find_supported_format(struct pipe_screen *screen,
return PIPE_FORMAT_NONE;
}
+struct exact_format_mapping
+{
+ GLenum format;
+ GLenum type;
+ enum pipe_format pformat;
+};
+
+static struct exact_format_mapping rgba8888_tbl[] =
I'd put a const qualifier on these tables, just to be safe. I need to
do that on the main format table too.
+{
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8B8G8R8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_A8B8G8R8_UNORM },
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8A8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8A8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8R8G8B8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8A8_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 struct exact_format_mapping rgbx8888_tbl[] =
+{
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8B8G8R8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_X8B8G8R8_UNORM },
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8X8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8X8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8R8G8B8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8X8_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 }
+};
+
+static struct exact_format_mapping rgba1010102_tbl[] =
+{
+ { GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
PIPE_FORMAT_B10G10R10A2_UNORM },
+ { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV,
PIPE_FORMAT_R10G10B10A2_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2,
PIPE_FORMAT_R10G10B10A2_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT,
PIPE_FORMAT_R10G10B10A2_UNORM },
+ { 0, 0, 0
}
+};
+
+/**
+ * If there is an exact pipe_format match for {internalFormat, format, type}
+ * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching.
+ */
+static enum pipe_format
+find_exact_format(GLint internalFormat, GLenum format, GLenum type)
+{
+ uint i;
+ struct exact_format_mapping* tbl;
+
+ if ( format == GL_NONE || type == GL_NONE )
Minor whitespace nitpick:
if (format == GL_NONE || type == GL_NONE)
+ return PIPE_FORMAT_NONE;
+
+ switch (internalFormat) {
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA8:
+ tbl = rgba8888_tbl;
+ break;
+ case 3:
+ case GL_RGB:
+ case GL_RGB8:
+ tbl = rgbx8888_tbl;
+ break;
+ case GL_RGB10_A2:
+ tbl = rgba1010102_tbl;
+ break;
+ default:
+ return PIPE_FORMAT_NONE;
+ }
+
+ for(i = 0; tbl[i].format; i++)
Another whitespace nit:
for (i = 0; tbl[i].format; i++)
+ if (tbl[i].format == format&& tbl[i].type == type)
+ return tbl[i].pformat;
I don't see where you check if the chosen pipe format is actually
supported by the driver.
Looks good otherwise, assuming you've run piglit, etc. You might also
try demos/tests/packedpixels (press 'f' to cycle through all the formats).
Thanks for doing this!
-Brian
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev