From cbbdf8612d784faa0928208fd6599c6add2d0e48 Mon Sep 17 00:00:00 2001 From: Eduardo Lima Mitev Date: Tue, 22 Dec 2015 17:16:50 +0100 Subject: [PATCH] i965/formatquery: Add support for INTERNALFORMAT_PREFERRED query This pname is tricky. The spec states that an internal format should be returned, that is compatible with the passed internal format, and has at least the same precision. There is no clear API to resolve this. The closest we have (and what other drivers (i.e, NVidia proprietary) do, is to return the same internal format given as parameter. But we validate first that the passed internal format is supported by i965. To check for support, we have the TextureFormatSupported map'. But this map expects a 'mesa_format', which takes a format+typen. So, we must first "come up" with a generic type that is suited for this internal format, then get a mesa_format, and then do the validation. The cleanest solution here is to add a method that does exactly what the spec wants: a driver's preferred internal format from a given internal format. But at this point we lack a clear view of what defines this preference, and also there seems to be no API for it. Reviewed-by: Dave Airlie --- src/mesa/drivers/dri/i965/brw_formatquery.c | 73 +++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_formatquery.c b/src/mesa/drivers/dri/i965/brw_formatquery.c index 576e36fcae3..210109b39f7 100644 --- a/src/mesa/drivers/dri/i965/brw_formatquery.c +++ b/src/mesa/drivers/dri/i965/brw_formatquery.c @@ -22,7 +22,9 @@ */ #include "brw_context.h" +#include "brw_state.h" #include "main/formatquery.h" +#include "main/glformats.h" static size_t brw_query_samples_for_format(struct gl_context *ctx, GLenum target, @@ -63,6 +65,46 @@ brw_query_samples_for_format(struct gl_context *ctx, GLenum target, } } +/** + * Returns a generic GL type from an internal format, so that it can be used + * together with the base format to obtain a mesa_format by calling + * mesa_format_from_format_and_type(). + */ +static GLenum +get_generic_type_for_internal_format(GLenum internalFormat) +{ + if (_mesa_is_color_format(internalFormat)) { + if (_mesa_is_enum_format_unsigned_int(internalFormat)) + return GL_UNSIGNED_BYTE; + else if (_mesa_is_enum_format_signed_int(internalFormat)) + return GL_BYTE; + } else { + switch (internalFormat) { + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX8: + return GL_UNSIGNED_BYTE; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + return GL_UNSIGNED_SHORT; + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + return GL_UNSIGNED_INT; + case GL_DEPTH_COMPONENT32F: + return GL_FLOAT; + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return GL_UNSIGNED_INT_24_8; + case GL_DEPTH32F_STENCIL8: + return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; + default: + /* fall-through */ + break; + } + } + + return GL_FLOAT; +} + void brw_query_internal_format(struct gl_context *ctx, GLenum target, GLenum internalFormat, GLenum pname, GLint *params) @@ -87,6 +129,37 @@ brw_query_internal_format(struct gl_context *ctx, GLenum target, break; } + case GL_INTERNALFORMAT_PREFERRED: { + params[0] = GL_NONE; + + /* We need to resolve an internal format that is compatible with + * the passed internal format, and optimal to the driver. By now, + * we just validate that the passed internal format is supported by + * the driver, and if so return the same internal format, otherwise + * return GL_NONE. + * + * For validating the internal format, we use the + * ctx->TextureFormatSupported map to check that a BRW surface format + * exists, that can be derived from the internal format. But this + * expects a mesa_format, not an internal format. So we need to "come up" + * with a type that is generic enough, to resolve the mesa_format first. + */ + GLenum type = get_generic_type_for_internal_format(internalFormat); + + /* Get a mesa_format from the internal format and type. */ + GLint base_format = _mesa_base_tex_format(ctx, internalFormat); + if (base_format != -1) { + mesa_format mesa_format = + _mesa_format_from_format_and_type(base_format, type); + + if (mesa_format < MESA_FORMAT_COUNT && + ctx->TextureFormatSupported[mesa_format]) { + params[0] = internalFormat; + } + } + break; + } + default: /* By default, we call the driver hook's fallback function from the frontend, * which has generic implementation for all pnames. -- 2.30.2