summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/u_caps.c28
-rw-r--r--src/gallium/auxiliary/util/u_caps.h4
-rw-r--r--src/gallium/auxiliary/util/u_format.c56
-rw-r--r--src/gallium/auxiliary/util/u_format.h42
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h1
-rw-r--r--src/gallium/auxiliary/util/u_linear.h1
6 files changed, 117 insertions, 15 deletions
diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c
index 94d5bd3027..e209a98b70 100644
--- a/src/gallium/auxiliary/util/u_caps.c
+++ b/src/gallium/auxiliary/util/u_caps.c
@@ -75,6 +75,14 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
return FALSE;
}
break;
+ case UTIL_CAPS_CHECK_SHADER:
+ tmpi = screen->get_shader_param(screen, list[i] >> 24, list[i] & ((1 << 24) - 1));
+ ++i;
+ if (tmpi < (int)list[i++]) {
+ *out = i - 3;
+ return FALSE;
+ }
+ break;
case UTIL_CAPS_CHECK_UNIMPLEMENTED:
*out = i - 1;
return FALSE;
@@ -188,17 +196,17 @@ static unsigned caps_opengl_2_1[] = {
/* Shader Model 3 */
static unsigned caps_sm3[] = {
- UTIL_CHECK_INT(MAX_FS_INSTRUCTIONS, 512),
- UTIL_CHECK_INT(MAX_FS_INPUTS, 10),
- UTIL_CHECK_INT(MAX_FS_TEMPS, 32),
- UTIL_CHECK_INT(MAX_FS_ADDRS, 1),
- UTIL_CHECK_INT(MAX_FS_CONSTS, 224),
+ UTIL_CHECK_SHADER(FRAGMENT, MAX_INSTRUCTIONS, 512),
+ UTIL_CHECK_SHADER(FRAGMENT, MAX_INPUTS, 10),
+ UTIL_CHECK_SHADER(FRAGMENT, MAX_TEMPS, 32),
+ UTIL_CHECK_SHADER(FRAGMENT, MAX_ADDRS, 1),
+ UTIL_CHECK_SHADER(FRAGMENT, MAX_CONSTS, 224),
- UTIL_CHECK_INT(MAX_VS_INSTRUCTIONS, 512),
- UTIL_CHECK_INT(MAX_VS_INPUTS, 16),
- UTIL_CHECK_INT(MAX_VS_TEMPS, 32),
- UTIL_CHECK_INT(MAX_VS_ADDRS, 2),
- UTIL_CHECK_INT(MAX_VS_CONSTS, 256),
+ UTIL_CHECK_SHADER(VERTEX, MAX_INSTRUCTIONS, 512),
+ UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16),
+ UTIL_CHECK_SHADER(VERTEX, MAX_TEMPS, 32),
+ UTIL_CHECK_SHADER(VERTEX, MAX_ADDRS, 2),
+ UTIL_CHECK_SHADER(VERTEX, MAX_CONSTS, 256),
UTIL_CHECK_TERMINATE
};
diff --git a/src/gallium/auxiliary/util/u_caps.h b/src/gallium/auxiliary/util/u_caps.h
index b1074f9eb2..7bd2380041 100644
--- a/src/gallium/auxiliary/util/u_caps.h
+++ b/src/gallium/auxiliary/util/u_caps.h
@@ -38,6 +38,7 @@ enum u_caps_check_enum {
UTIL_CAPS_CHECK_INT,
UTIL_CAPS_CHECK_FLOAT,
UTIL_CAPS_CHECK_FORMAT,
+ UTIL_CAPS_CHECK_SHADER,
UTIL_CAPS_CHECK_UNIMPLEMENTED,
};
@@ -54,6 +55,9 @@ enum u_caps_check_enum {
#define UTIL_CHECK_FORMAT(format) \
UTIL_CAPS_CHECK_FORMAT, PIPE_FORMAT_##format
+#define UTIL_CHECK_SHADER(shader, cap, higher) \
+ UTIL_CAPS_CHECK_SHADER, (PIPE_SHADER_##shader << 24) | PIPE_SHADER_CAP_##cap, (unsigned)(higher)
+
#define UTIL_CHECK_UNIMPLEMENTED \
UTIL_CAPS_CHECK_UNIMPLEMENTED
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index 43d09f1960..a4ee91b0cf 100644
--- a/src/gallium/auxiliary/util/u_format.c
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -121,6 +121,54 @@ util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_
boolean
+util_is_format_compatible(const struct util_format_description *src_desc,
+ const struct util_format_description *dst_desc)
+{
+ unsigned chan;
+
+ if (src_desc->format == dst_desc->format) {
+ return TRUE;
+ }
+
+ if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
+ dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
+ return FALSE;
+ }
+
+ if (src_desc->block.bits != dst_desc->block.bits ||
+ src_desc->nr_channels != dst_desc->nr_channels ||
+ src_desc->colorspace != dst_desc->colorspace) {
+ return FALSE;
+ }
+
+ for (chan = 0; chan < 4; ++chan) {
+ if (src_desc->channel[chan].size !=
+ dst_desc->channel[chan].size) {
+ return FALSE;
+ }
+ }
+
+ for (chan = 0; chan < 4; ++chan) {
+ enum util_format_swizzle swizzle = dst_desc->swizzle[chan];
+
+ if (swizzle < 4) {
+ if (src_desc->swizzle[chan] != swizzle) {
+ return FALSE;
+ }
+ if ((src_desc->channel[swizzle].type !=
+ dst_desc->channel[swizzle].type) ||
+ (src_desc->channel[swizzle].normalized !=
+ dst_desc->channel[swizzle].normalized)) {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+boolean
util_format_fits_8unorm(const struct util_format_description *format_desc)
{
unsigned chan;
@@ -193,7 +241,10 @@ util_format_translate(enum pipe_format dst_format,
unsigned dst_step;
unsigned src_step;
- if (dst_format == src_format) {
+ dst_format_desc = util_format_description(dst_format);
+ src_format_desc = util_format_description(src_format);
+
+ if (util_is_format_compatible(src_format_desc, dst_format_desc)) {
/*
* Trivial case.
*/
@@ -204,9 +255,6 @@ util_format_translate(enum pipe_format dst_format,
return;
}
- dst_format_desc = util_format_description(dst_format);
- src_format_desc = util_format_description(src_format);
-
assert(dst_x % dst_format_desc->block.width == 0);
assert(dst_y % dst_format_desc->block.height == 0);
assert(src_x % src_format_desc->block.width == 0);
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 8e786a390a..03b73c0e98 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -440,6 +440,48 @@ util_format_is_depth_and_stencil(enum pipe_format format)
desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
}
+
+/**
+ * Give the RGBA colormask of the channels that can be represented in this
+ * format.
+ *
+ * That is, the channels whose values are preserved.
+ */
+static INLINE unsigned
+util_format_colormask(const struct util_format_description *desc)
+{
+ unsigned colormask;
+ unsigned chan;
+
+ switch (desc->colorspace) {
+ case UTIL_FORMAT_COLORSPACE_RGB:
+ case UTIL_FORMAT_COLORSPACE_SRGB:
+ case UTIL_FORMAT_COLORSPACE_YUV:
+ colormask = 0;
+ for (chan = 0; chan < 4; ++chan) {
+ if (desc->swizzle[chan] < 4) {
+ colormask |= (1 << chan);
+ }
+ }
+ return colormask;
+ case UTIL_FORMAT_COLORSPACE_ZS:
+ return 0;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
+/**
+ * Whether the src format can be blitted to destation format with a simple
+ * memcpy.
+ */
+boolean
+util_is_format_compatible(const struct util_format_description *src_desc,
+ const struct util_format_description *dst_desc);
+
+
/**
* Whether this format is a rgab8 variant.
*
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 78473bf35a..6ed39561fb 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -399,7 +399,6 @@ static INLINE boolean util_get_offset(
}
}
-
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_linear.h b/src/gallium/auxiliary/util/u_linear.h
index 42c40b2aa7..81ffc9fb27 100644
--- a/src/gallium/auxiliary/util/u_linear.h
+++ b/src/gallium/auxiliary/util/u_linear.h
@@ -33,6 +33,7 @@
#ifndef U_LINEAR_H
#define U_LINEAR_H
+#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
struct u_linear_format_block