When selecting a mesa_format to use for a texture, we are constrained by the user's requested internalFormat. If the requested internalFormat is generic (e.g. GL_RGBA) it imposes no preferred type or layout and so we are free to choose any compatible mesa_format. In this case, we can inspect the incoming pixelformat and see if the hardware natively supports it, and if so use that for the texture format as then uploads/downloads are conversion free (implying no loss of fidelity and should be fastest), utilizing the hardware samplers to do the conversion and filtering as required (which again should be faster and both higher and controllable accuracy).
A trivial demonstration using mesa-demos/teximage on the puny byt: Before: GetTexImage(RGB/ubyte 256 x 256): 269.2 images/sec, 50.5 MB/sec GetTexImage(RGB/565 256 x 256): 99.5 images/sec, 12.4 MB/sec GetTexImage(BGRA/ubyte 256 x 256): 252.0 images/sec, 63.0 MB/sec GetTexImage(BGRA/8888r 256 x 256): 229.2 images/sec, 57.3 MB/sec GetTexImage(RGBA/float 256 x 256): 1059.5 images/sec, 1059.5 MB/sec After: GetTexImage(RGB/ubyte 256 x 256): 279.6 images/sec, 52.4 MB/sec GetTexImage(RGB/565 256 x 256): 6681.9 images/sec, 835.2 MB/sec GetTexImage(BGRA/ubyte 256 x 256): 4262.2 images/sec, 1065.6 MB/sec GetTexImage(BGRA/8888r 256 x 256): 4262.2 images/sec, 1065.6 MB/sec GetTexImage(RGBA/float 256 x 256): 1061.7 images/sec, 1061.7 MB/sec Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> Cc: Ilia Mirkin <imir...@alum.mit.edu> Cc: Ian Romanick <ian.d.roman...@intel.com> --- src/mesa/main/texformat.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 866c7b3..0882763 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -37,6 +37,7 @@ #include "enums.h" #include "mtypes.h" #include "texcompress.h" +#include "teximage.h" #include "texformat.h" #include "glformats.h" @@ -64,8 +65,26 @@ mesa_format _mesa_choose_tex_format(struct gl_context *ctx, GLenum target, GLint internalFormat, GLenum format, GLenum type) { - (void) format; + /* We use the user's pixel format and type as a guide for the texture + * format preferrring to store the texels in a matching format to the + * incoming pixels. This ideally allows for a conversion free upload + * and download path - but only if the requested internalFormat + * requires no conversion. + */ + if (_mesa_is_enum_format_unsized(internalFormat)) { + /* unsized also implies no preferred internal datatype */ + mesa_format tex_format = _mesa_format_from_format_and_type(format, type); + if (_mesa_format_is_mesa_array_format(tex_format)) + tex_format = _mesa_format_from_array_format(tex_format); + if (_mesa_base_tex_format(ctx, internalFormat) == + _mesa_get_format_base_format(tex_format)) { + RETURN_IF_SUPPORTED(tex_format); + } + } + /* Could not find an exacting match for a generic internalFormat, pick + * from a list of preferred texture formats for each type. + */ switch (internalFormat) { /* shallow RGBA formats */ case 4: -- 2.5.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev