From: Marek Olšák Date: Mon, 11 Apr 2011 04:23:00 +0000 (+0200) Subject: gallium: add and use generic function for querying patented format support (v2) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=75fa5c99a86c1ae0f8a4fecc016a5f82da9ae80a;p=mesa.git gallium: add and use generic function for querying patented format support (v2) v2: Unsigned floats are allowed regardless of the configure switch. --- diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c index 4896faa12bf..9cbdd0a5b99 100644 --- a/src/gallium/auxiliary/util/u_format.c +++ b/src/gallium/auxiliary/util/u_format.c @@ -36,6 +36,55 @@ #include "u_memory.h" #include "u_rect.h" #include "u_format.h" +#include "u_format_s3tc.h" + +#include "pipe/p_defines.h" + + +boolean +util_format_is_float(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + unsigned i; + + assert(desc); + if (!desc) { + return FALSE; + } + + /* Find the first non-void channel. */ + for (i = 0; i < 4; i++) { + if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { + break; + } + } + + if (i == 4) { + return FALSE; + } + + return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE; +} + + +boolean +util_format_is_supported(enum pipe_format format, unsigned bind) +{ + if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) { + return FALSE; + } + +#ifndef TEXTURE_FLOAT_ENABLED + if ((bind & PIPE_BIND_RENDER_TARGET) && + format != PIPE_FORMAT_R9G9B9E5_FLOAT && + format != PIPE_FORMAT_R11G11B10_FLOAT && + util_format_is_float(format)) { + return FALSE; + } +#endif + + return TRUE; +} void diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 7659a802a41..bb3ed72e932 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -473,6 +473,10 @@ util_format_colormask(const struct util_format_description *desc) } +boolean +util_format_is_float(enum pipe_format format); + + /** * Whether the src format can be blitted to destation format with a simple * memcpy. @@ -481,6 +485,12 @@ boolean util_is_format_compatible(const struct util_format_description *src_desc, const struct util_format_description *dst_desc); +/** + * Whether the format is supported by Gallium for the given bindings. + * This covers S3TC textures and floating-point render targets. + */ +boolean +util_format_is_supported(enum pipe_format format, unsigned bind); /** * Whether this format is a rgab8 variant. diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index e62b609eb5a..6f6a342791a 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -285,6 +285,9 @@ i915_is_format_supported(struct pipe_screen *screen, const enum pipe_format *list; uint i; + if (!util_format_is_supported(format, tex_usage)) + return FALSE; + if (sample_count > 1) return FALSE; diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index 25204fd088d..5353ae23250 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -333,6 +333,9 @@ brw_is_format_supported(struct pipe_screen *screen, const enum pipe_format *list; uint i; + if (!util_format_is_supported(format, tex_usage)) + return FALSE; + if (sample_count > 1) return FALSE; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 46622b4be76..e0eea3ed750 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -45,17 +45,8 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, if (sample_count > 1) return FALSE; - if (!util_format_s3tc_enabled) { - switch (format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - return FALSE; - default: - break; - } - } + if (!util_format_is_supported(format, bindings)) + return FALSE; switch (format) { case PIPE_FORMAT_Z16_UNORM: diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 31133f0cc6c..c4cdface502 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -39,17 +39,8 @@ nvc0_screen_is_format_supported(struct pipe_screen *pscreen, if (sample_count > 1) return FALSE; - if (!util_format_s3tc_enabled) { - switch (format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - return FALSE; - default: - break; - } - } + if (!util_format_is_supported(format, bindings)) + return FALSE; /* transfers & shared are always supported */ bindings &= ~(PIPE_BIND_TRANSFER_READ | diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 0c8d33fb0aa..abbed9651ee 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -208,6 +208,9 @@ nvfx_screen_is_format_supported(struct pipe_screen *pscreen, { struct nvfx_screen *screen = nvfx_screen(pscreen); + if (!util_format_is_supported(format, bind)) + return FALSE; + if (sample_count > 1) return FALSE; diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index e1f5a9fd221..acb7d9f02d2 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -334,6 +334,9 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, format == PIPE_FORMAT_R16G16B16_FLOAT || format == PIPE_FORMAT_R16G16B16A16_FLOAT; + if (!util_format_is_supported(format, usage)) + return FALSE; + /* Check multisampling support. */ switch (sample_count) { case 0: diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index b4d45f5eee0..afc1451183d 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -741,25 +741,6 @@ static uint32_t r300_get_border_color(enum pipe_format format, return uc.ui; } -static boolean util_format_is_float(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - unsigned i; - - if (!format) - return FALSE; - - /* Find the first non-void channel. */ - for (i = 0; i < 4; i++) - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) - break; - - if (i == 4) - return FALSE; - - return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE; -} - static void r300_merge_textures_and_samplers(struct r300_context* r300) { struct r300_textures_state *state = diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 5f95540a479..066768f9c38 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -523,6 +523,9 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, return FALSE; } + if (!util_format_is_supported(format, usage)) + return FALSE; + /* Multisample */ if (sample_count > 1) return FALSE;