diff options
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r-- | mesalib/src/mesa/main/imports.c | 13 | ||||
-rw-r--r-- | mesalib/src/mesa/main/imports.h | 13 | ||||
-rw-r--r-- | mesalib/src/mesa/program/sampler.cpp | 275 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_sampler.c | 46 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_clear.c | 22 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 116 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_draw.c | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.c | 2249 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.h | 6 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_gen_mipmap.c | 14 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_exec.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_exec_api.c | 177 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_exec_draw.c | 25 |
13 files changed, 1540 insertions, 1425 deletions
diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c index f98098230..3f856402f 100644 --- a/mesalib/src/mesa/main/imports.c +++ b/mesalib/src/mesa/main/imports.c @@ -453,6 +453,7 @@ _mesa_inv_sqrtf(float n) #endif
}
+#ifndef __GNUC__
/**
* Find the first bit set in a word.
*/
@@ -496,9 +497,6 @@ _mesa_ffs(int32_t i) int
_mesa_ffsll(int64_t val)
{
-#ifdef ffsll
- return ffsll(val);
-#else
int bit;
assert(sizeof(val) == 8);
@@ -512,27 +510,24 @@ _mesa_ffsll(int64_t val) return 32 + bit;
return 0;
-#endif
}
+#if ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) || __GNUC__ < 4)
/**
* Return number of bits set in given GLuint.
*/
unsigned int
_mesa_bitcount(unsigned int n)
{
-#if defined(__GNUC__) && \
- ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
- return __builtin_popcount(n);
-#else
unsigned int bits;
for (bits = 0; n > 0; n = n >> 1) {
bits += (n & 1);
}
return bits;
-#endif
}
+#endif
+#endif
/**
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index af7a8cc00..9922f43e3 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -539,6 +539,18 @@ _mesa_inv_sqrtf(float x); extern void
_mesa_init_sqrt_table(void);
+#ifdef __GNUC__
+#define _mesa_ffs(i) ffs(i)
+#define _mesa_ffsll(i) ffsll(i)
+
+#if ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+#define _mesa_bitcount(i) __builtin_popcount(i)
+#else
+extern unsigned int
+_mesa_bitcount(unsigned int n);
+#endif
+
+#else
extern int
_mesa_ffs(int32_t i);
@@ -547,6 +559,7 @@ _mesa_ffsll(int64_t i); extern unsigned int
_mesa_bitcount(unsigned int n);
+#endif
extern GLhalfARB
_mesa_float_to_half(float f);
diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp index 12c4a40a2..b219d7016 100644 --- a/mesalib/src/mesa/program/sampler.cpp +++ b/mesalib/src/mesa/program/sampler.cpp @@ -1,138 +1,137 @@ -/* - * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, Inc. All Rights Reserved. - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <cstdio> -#include "ir.h" -#include "glsl_types.h" -#include "ir_visitor.h" - -extern "C" { -#include "main/compiler.h" -#include "main/mtypes.h" -#include "program/prog_parameter.h" -} - -static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); - -static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - ralloc_vasprintf_append(&prog->InfoLog, fmt, args); - va_end(args); - - prog->LinkStatus = GL_FALSE; -} - -class get_sampler_name : public ir_hierarchical_visitor -{ -public: - get_sampler_name(ir_dereference *last, - struct gl_shader_program *shader_program) - { - this->mem_ctx = ralloc_context(NULL); - this->shader_program = shader_program; - this->name = NULL; - this->offset = 0; - this->last = last; - } - - ~get_sampler_name() - { - ralloc_free(this->mem_ctx); - } - - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - this->name = ir->var->name; - return visit_continue; - } - - virtual ir_visitor_status visit_leave(ir_dereference_record *ir) - { - this->name = ralloc_asprintf(mem_ctx, "%s.%s", name, ir->field); - return visit_continue; - } - - virtual ir_visitor_status visit_leave(ir_dereference_array *ir) - { - ir_constant *index = ir->array_index->as_constant(); - int i; - - if (index) { - i = index->value.i[0]; - } else { - /* GLSL 1.10 and 1.20 allowed variable sampler array indices, - * while GLSL 1.30 requires that the array indices be - * constant integer expressions. We don't expect any driver - * to actually work with a really variable array index, so - * all that would work would be an unrolled loop counter that ends - * up being constant above. - */ - ralloc_strcat(&shader_program->InfoLog, - "warning: Variable sampler array index unsupported.\n" - "This feature of the language was removed in GLSL 1.20 " - "and is unlikely to be supported for 1.10 in Mesa.\n"); - i = 0; - } - if (ir != last) { - this->name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i); - } else { - offset = i; - } - return visit_continue; - } - - struct gl_shader_program *shader_program; - const char *name; - void *mem_ctx; - int offset; - ir_dereference *last; -}; - -extern "C" { -int -_mesa_get_sampler_uniform_value(class ir_dereference *sampler, - struct gl_shader_program *shader_program, - const struct gl_program *prog) -{ - get_sampler_name getname(sampler, shader_program); - - sampler->accept(&getname); - - GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, - getname.name); - - if (index < 0) { - fail_link(shader_program, - "failed to find sampler named %s.\n", getname.name); - return 0; - } - - index += getname.offset; - - return prog->Parameters->ParameterValues[index][0]; -} -} +/*
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ir.h"
+#include "glsl_types.h"
+#include "ir_visitor.h"
+
+extern "C" {
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "program/prog_parameter.h"
+}
+
+static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
+
+static void fail_link(struct gl_shader_program *prog, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ ralloc_vasprintf_append(&prog->InfoLog, fmt, args);
+ va_end(args);
+
+ prog->LinkStatus = GL_FALSE;
+}
+
+class get_sampler_name : public ir_hierarchical_visitor
+{
+public:
+ get_sampler_name(ir_dereference *last,
+ struct gl_shader_program *shader_program)
+ {
+ this->mem_ctx = ralloc_context(NULL);
+ this->shader_program = shader_program;
+ this->name = NULL;
+ this->offset = 0;
+ this->last = last;
+ }
+
+ ~get_sampler_name()
+ {
+ ralloc_free(this->mem_ctx);
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ this->name = ir->var->name;
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
+ {
+ this->name = ralloc_asprintf(mem_ctx, "%s.%s", name, ir->field);
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
+ {
+ ir_constant *index = ir->array_index->as_constant();
+ int i;
+
+ if (index) {
+ i = index->value.i[0];
+ } else {
+ /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
+ * while GLSL 1.30 requires that the array indices be
+ * constant integer expressions. We don't expect any driver
+ * to actually work with a really variable array index, so
+ * all that would work would be an unrolled loop counter that ends
+ * up being constant above.
+ */
+ ralloc_strcat(&shader_program->InfoLog,
+ "warning: Variable sampler array index unsupported.\n"
+ "This feature of the language was removed in GLSL 1.20 "
+ "and is unlikely to be supported for 1.10 in Mesa.\n");
+ i = 0;
+ }
+ if (ir != last) {
+ this->name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
+ } else {
+ offset = i;
+ }
+ return visit_continue;
+ }
+
+ struct gl_shader_program *shader_program;
+ const char *name;
+ void *mem_ctx;
+ int offset;
+ ir_dereference *last;
+};
+
+extern "C" {
+int
+_mesa_get_sampler_uniform_value(class ir_dereference *sampler,
+ struct gl_shader_program *shader_program,
+ const struct gl_program *prog)
+{
+ get_sampler_name getname(sampler, shader_program);
+
+ sampler->accept(&getname);
+
+ GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
+ getname.name);
+
+ if (index < 0) {
+ fail_link(shader_program,
+ "failed to find sampler named %s.\n", getname.name);
+ return 0;
+ }
+
+ index += getname.offset;
+
+ return prog->Parameters->ParameterValues[index][0];
+}
+}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c index c9dfe248f..17596d4c8 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c +++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c @@ -36,6 +36,7 @@ #include "st_context.h"
#include "st_cb_texture.h"
+#include "st_format.h"
#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -117,49 +118,6 @@ gl_filter_to_img_filter(GLenum filter) }
-static void
-xlate_border_color(const GLfloat *colorIn, GLenum baseFormat, GLfloat *colorOut)
-{
- switch (baseFormat) {
- case GL_RED:
- colorOut[0] = colorIn[0];
- colorOut[1] = 0.0F;
- colorOut[2] = 0.0F;
- colorOut[3] = 1.0F;
- break;
- case GL_RG:
- colorOut[0] = colorIn[0];
- colorOut[1] = colorIn[1];
- colorOut[2] = 0.0F;
- colorOut[3] = 1.0F;
- break;
- case GL_RGB:
- colorOut[0] = colorIn[0];
- colorOut[1] = colorIn[1];
- colorOut[2] = colorIn[2];
- colorOut[3] = 1.0F;
- break;
- case GL_ALPHA:
- colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
- colorOut[3] = colorIn[3];
- break;
- case GL_LUMINANCE:
- colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
- colorOut[3] = 1.0;
- break;
- case GL_LUMINANCE_ALPHA:
- colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
- colorOut[3] = colorIn[3];
- break;
- case GL_INTENSITY:
- colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
- break;
- default:
- COPY_4V(colorOut, colorIn);
- }
-}
-
-
static void
update_samplers(struct st_context *st)
{
@@ -223,7 +181,7 @@ update_samplers(struct st_context *st) assert(sampler->min_lod <= sampler->max_lod);
}
- xlate_border_color(texobj->BorderColor.f,
+ st_translate_color(texobj->BorderColor.f,
teximg ? teximg->_BaseFormat : GL_RGBA,
sampler->border_color);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 461f4e315..79e58182f 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -42,6 +42,7 @@ #include "st_cb_accum.h"
#include "st_cb_clear.h"
#include "st_cb_fbo.h"
+#include "st_format.h"
#include "st_program.h"
#include "pipe/p_context.h"
@@ -204,6 +205,7 @@ clear_with_quad(struct gl_context *ctx, const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
+ float clearColor[4];
/*
printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
@@ -298,9 +300,14 @@ clear_with_quad(struct gl_context *ctx, cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
- /* draw quad matching scissor rect (XXX verify coord round-off) */
- draw_quad(st, x0, y0, x1, y1,
- (GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor);
+ if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
+ st_translate_color(ctx->Color.ClearColor,
+ ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+ clearColor);
+ }
+
+ /* draw quad matching scissor rect */
+ draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor);
/* Restore pipe state */
cso_restore_blend(st->cso_context);
@@ -541,12 +548,21 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) * required from the visual. Hence fix this up to avoid potential
* read-modify-write in the driver.
*/
+ float clearColor[4];
+
if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) &&
((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
(depthRb == stencilRb) &&
(ctx->DrawBuffer->Visual.depthBits == 0 ||
ctx->DrawBuffer->Visual.stencilBits == 0))
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+
+ if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
+ st_translate_color(ctx->Color.ClearColor,
+ ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+ clearColor);
+ }
+
st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor,
ctx->Depth.Clear, ctx->Stencil.Clear);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index c0d1bd94a..708aa1290 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -260,6 +260,55 @@ get_texture_dims(GLenum target) /**
+ * Given the size of a mipmap image, try to compute the size of the level=0
+ * mipmap image.
+ *
+ * Note that this isn't always accurate for odd-sized, non-POW textures.
+ * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
+ *
+ * \return GL_TRUE for success, GL_FALSE for failure
+ */
+static GLboolean
+guess_base_level_size(GLenum target,
+ GLuint width, GLuint height, GLuint depth, GLuint level,
+ GLuint *width0, GLuint *height0, GLuint *depth0)
+{
+ const GLuint dims = get_texture_dims(target);
+
+ assert(width >= 1);
+ assert(height >= 1);
+ assert(depth >= 1);
+
+ if (level > 0) {
+ /* Depending on the image's size, we can't always make a guess here */
+ if ((dims >= 1 && width == 1) ||
+ (dims >= 2 && height == 1) ||
+ (dims >= 3 && depth == 1)) {
+ /* we can't determine the image size at level=0 */
+ return GL_FALSE;
+ }
+
+ /* grow the image size until we hit level = 0 */
+ while (level > 0) {
+ if (width > 1)
+ width <<= 1;
+ if (height > 1)
+ height <<= 1;
+ if (depth > 1)
+ depth <<= 1;
+ level--;
+ }
+ }
+
+ *width0 = width;
+ *height0 = height;
+ *depth0 = depth;
+
+ return GL_TRUE;
+}
+
+
+/**
* Try to allocate a pipe_resource object for the given st_texture_object.
*
* We use the given st_texture_image as a clue to determine the size of the
@@ -272,8 +321,7 @@ guess_and_alloc_texture(struct st_context *st, struct st_texture_object *stObj,
const struct st_texture_image *stImage)
{
- const GLuint dims = get_texture_dims(stObj->base.Target);
- GLuint level, lastLevel, width, height, depth;
+ GLuint lastLevel, width, height, depth;
GLuint bindings;
GLuint ptWidth, ptHeight, ptDepth, ptLayers;
enum pipe_format fmt;
@@ -282,41 +330,18 @@ guess_and_alloc_texture(struct st_context *st, assert(!stObj->pt);
- level = stImage->level;
- width = stImage->base.Width2; /* size w/out border */
- height = stImage->base.Height2;
- depth = stImage->base.Depth2;
-
- assert(width > 0);
- assert(height > 0);
- assert(depth > 0);
-
- /* Depending on the image's size, we can't always make a guess here.
- */
- if (level > 0) {
- if ( (dims >= 1 && width == 1) ||
- (dims >= 2 && height == 1) ||
- (dims >= 3 && depth == 1) ) {
- /* we can't determine the image size at level=0 */
- stObj->width0 = stObj->height0 = stObj->depth0 = 0;
- /* this is not an out of memory error */
- return GL_TRUE;
- }
+ if (!guess_base_level_size(stObj->base.Target,
+ stImage->base.Width2,
+ stImage->base.Height2,
+ stImage->base.Depth2,
+ stImage->level,
+ &width, &height, &depth)) {
+ /* we can't determine the image size at level=0 */
+ stObj->width0 = stObj->height0 = stObj->depth0 = 0;
+ /* this is not an out of memory error */
+ return GL_TRUE;
}
- /* grow the image size until we hit level = 0 */
- while (level > 0) {
- if (width != 1)
- width <<= 1;
- if (height != 1)
- height <<= 1;
- if (depth != 1)
- depth <<= 1;
- level--;
- }
-
- assert(level == 0);
-
/* At this point, (width x height x depth) is the expected size of
* the level=0 mipmap image.
*/
@@ -1721,9 +1746,24 @@ st_finalize_texture(struct gl_context *ctx, /* Find gallium format for the Mesa texture */
firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
- st_gl_texture_dims_to_pipe_dims(stObj->base.Target, stObj->width0,
- stObj->height0, stObj->depth0,
- &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+
+ /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
+ {
+ GLuint width, height, depth;
+ if (!guess_base_level_size(stObj->base.Target,
+ firstImage->base.Width2,
+ firstImage->base.Height2,
+ firstImage->base.Depth2,
+ stObj->base.BaseLevel,
+ &width, &height, &depth)) {
+ width = stObj->width0;
+ height = stObj->height0;
+ depth = stObj->depth0;
+ }
+ /* convert GL dims to Gallium dims */
+ st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+ }
/* If we already have a gallium texture, check that it matches the texture
* object's format, target, size, num_levels, etc.
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 564d63483..7f661d529 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -249,6 +249,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp, const struct gl_buffer_object *firstBufObj = NULL;
GLint firstStride = -1;
const GLubyte *client_addr = NULL;
+ GLboolean user_memory;
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
@@ -257,6 +258,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp, if (firstStride < 0) {
firstStride = stride;
+ user_memory = !bufObj || !bufObj->Name;
}
else if (firstStride != stride) {
return GL_FALSE;
@@ -266,6 +268,9 @@ is_interleaved_arrays(const struct st_vertex_program *vp, /* Try to detect if the client-space arrays are
* "close" to each other.
*/
+ if (!user_memory) {
+ return GL_FALSE;
+ }
if (!client_addr) {
client_addr = arrays[mesaAttr]->Ptr;
}
@@ -275,6 +280,9 @@ is_interleaved_arrays(const struct st_vertex_program *vp, }
}
else if (!firstBufObj) {
+ if (user_memory) {
+ return GL_FALSE;
+ }
firstBufObj = bufObj;
}
else if (bufObj != firstBufObj) {
diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index a532e089c..3620d0cb6 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1,1100 +1,1149 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright (c) 2008-2010 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Mesa / Gallium format conversion and format selection code. - * \author Brian Paul - */ - -#include "main/imports.h" -#include "main/context.h" -#include "main/texstore.h" -#include "main/image.h" -#include "main/macros.h" -#include "main/mfeatures.h" - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_screen.h" -#include "util/u_format.h" -#include "st_context.h" -#include "st_format.h" - - -static GLuint -format_max_bits(enum pipe_format format) -{ - GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0); - - size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)); - size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)); - size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)); - size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)); - size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)); - return size; -} - - -/** - * Return basic GL datatype for the given gallium format. - */ -GLenum -st_format_datatype(enum pipe_format format) -{ - const struct util_format_description *desc; - - desc = util_format_description(format); - assert(desc); - - if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) { - if (format == PIPE_FORMAT_B5G5R5A1_UNORM || - format == PIPE_FORMAT_B5G6R5_UNORM) { - return GL_UNSIGNED_SHORT; - } - else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || - format == PIPE_FORMAT_S8_USCALED_Z24_UNORM || - format == PIPE_FORMAT_Z24X8_UNORM || - format == PIPE_FORMAT_X8Z24_UNORM) { - return GL_UNSIGNED_INT_24_8; - } - else { - const GLuint size = format_max_bits(format); - if (size == 8) { - if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) - return GL_UNSIGNED_BYTE; - else - return GL_BYTE; - } - else if (size == 16) { - if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) - return GL_UNSIGNED_SHORT; - else - return GL_SHORT; - } - else { - assert( size <= 32 ); - if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) - return GL_UNSIGNED_INT; - else - return GL_INT; - } - } - } - else if (format == PIPE_FORMAT_UYVY) { - return GL_UNSIGNED_SHORT; - } - else if (format == PIPE_FORMAT_YUYV) { - return GL_UNSIGNED_SHORT; - } - else { - /* compressed format? */ - assert(0); - } - - assert(0); - return GL_NONE; -} - - -/** - * Translate Mesa format to Gallium format. - */ -enum pipe_format -st_mesa_format_to_pipe_format(gl_format mesaFormat) -{ - switch (mesaFormat) { - case MESA_FORMAT_RGBA8888: - return PIPE_FORMAT_A8B8G8R8_UNORM; - case MESA_FORMAT_RGBA8888_REV: - return PIPE_FORMAT_R8G8B8A8_UNORM; - case MESA_FORMAT_ARGB8888: - return PIPE_FORMAT_B8G8R8A8_UNORM; - case MESA_FORMAT_ARGB8888_REV: - return PIPE_FORMAT_A8R8G8B8_UNORM; - case MESA_FORMAT_XRGB8888: - return PIPE_FORMAT_B8G8R8X8_UNORM; - case MESA_FORMAT_XRGB8888_REV: - return PIPE_FORMAT_X8R8G8B8_UNORM; - case MESA_FORMAT_ARGB1555: - return PIPE_FORMAT_B5G5R5A1_UNORM; - case MESA_FORMAT_ARGB4444: - return PIPE_FORMAT_B4G4R4A4_UNORM; - case MESA_FORMAT_RGB565: - return PIPE_FORMAT_B5G6R5_UNORM; - case MESA_FORMAT_RGB332: - return PIPE_FORMAT_B2G3R3_UNORM; - case MESA_FORMAT_ARGB2101010: - return PIPE_FORMAT_B10G10R10A2_UNORM; - case MESA_FORMAT_AL44: - return PIPE_FORMAT_L4A4_UNORM; - case MESA_FORMAT_AL88: - return PIPE_FORMAT_L8A8_UNORM; - case MESA_FORMAT_AL1616: - return PIPE_FORMAT_L16A16_UNORM; - case MESA_FORMAT_A8: - return PIPE_FORMAT_A8_UNORM; - case MESA_FORMAT_A16: - return PIPE_FORMAT_A16_UNORM; - case MESA_FORMAT_L8: - return PIPE_FORMAT_L8_UNORM; - case MESA_FORMAT_L16: - return PIPE_FORMAT_L16_UNORM; - case MESA_FORMAT_I8: - return PIPE_FORMAT_I8_UNORM; - case MESA_FORMAT_I16: - return PIPE_FORMAT_I16_UNORM; - case MESA_FORMAT_Z16: - return PIPE_FORMAT_Z16_UNORM; - case MESA_FORMAT_Z32: - return PIPE_FORMAT_Z32_UNORM; - case MESA_FORMAT_Z24_S8: - return PIPE_FORMAT_S8_USCALED_Z24_UNORM; - case MESA_FORMAT_S8_Z24: - return PIPE_FORMAT_Z24_UNORM_S8_USCALED; - case MESA_FORMAT_Z24_X8: - return PIPE_FORMAT_X8Z24_UNORM; - case MESA_FORMAT_X8_Z24: - return PIPE_FORMAT_Z24X8_UNORM; - case MESA_FORMAT_S8: - return PIPE_FORMAT_S8_USCALED; - case MESA_FORMAT_YCBCR: - return PIPE_FORMAT_UYVY; -#if FEATURE_texture_s3tc - case MESA_FORMAT_RGB_DXT1: - return PIPE_FORMAT_DXT1_RGB; - case MESA_FORMAT_RGBA_DXT1: - return PIPE_FORMAT_DXT1_RGBA; - case MESA_FORMAT_RGBA_DXT3: - return PIPE_FORMAT_DXT3_RGBA; - case MESA_FORMAT_RGBA_DXT5: - return PIPE_FORMAT_DXT5_RGBA; -#if FEATURE_EXT_texture_sRGB - case MESA_FORMAT_SRGB_DXT1: - return PIPE_FORMAT_DXT1_SRGB; - case MESA_FORMAT_SRGBA_DXT1: - return PIPE_FORMAT_DXT1_SRGBA; - case MESA_FORMAT_SRGBA_DXT3: - return PIPE_FORMAT_DXT3_SRGBA; - case MESA_FORMAT_SRGBA_DXT5: - return PIPE_FORMAT_DXT5_SRGBA; -#endif -#endif -#if FEATURE_EXT_texture_sRGB - case MESA_FORMAT_SLA8: - return PIPE_FORMAT_L8A8_SRGB; - case MESA_FORMAT_SL8: - return PIPE_FORMAT_L8_SRGB; - case MESA_FORMAT_SRGB8: - return PIPE_FORMAT_R8G8B8_SRGB; - case MESA_FORMAT_SRGBA8: - return PIPE_FORMAT_A8B8G8R8_SRGB; - case MESA_FORMAT_SARGB8: - return PIPE_FORMAT_B8G8R8A8_SRGB; -#endif - case MESA_FORMAT_R8: - return PIPE_FORMAT_R8_UNORM; - case MESA_FORMAT_R16: - return PIPE_FORMAT_R16_UNORM; - case MESA_FORMAT_RG88: - return PIPE_FORMAT_R8G8_UNORM; - case MESA_FORMAT_RG1616: - return PIPE_FORMAT_R16G16_UNORM; - case MESA_FORMAT_RGBA_16: - return PIPE_FORMAT_R16G16B16A16_UNORM; - - /* signed int formats */ - case MESA_FORMAT_RGBA_INT8: - return PIPE_FORMAT_R8G8B8A8_SSCALED; - case MESA_FORMAT_RGBA_INT16: - return PIPE_FORMAT_R16G16B16A16_SSCALED; - case MESA_FORMAT_RGBA_INT32: - return PIPE_FORMAT_R32G32B32A32_SSCALED; - - /* unsigned int formats */ - case MESA_FORMAT_RGBA_UINT8: - return PIPE_FORMAT_R8G8B8A8_USCALED; - case MESA_FORMAT_RGBA_UINT16: - return PIPE_FORMAT_R16G16B16A16_USCALED; - case MESA_FORMAT_RGBA_UINT32: - return PIPE_FORMAT_R32G32B32A32_USCALED; - - default: - assert(0); - return PIPE_FORMAT_NONE; - } -} - - -/** - * Translate Gallium format to Mesa format. - */ -gl_format -st_pipe_format_to_mesa_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8B8G8R8_UNORM: - return MESA_FORMAT_RGBA8888; - case PIPE_FORMAT_R8G8B8A8_UNORM: - return MESA_FORMAT_RGBA8888_REV; - case PIPE_FORMAT_B8G8R8A8_UNORM: - return MESA_FORMAT_ARGB8888; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return MESA_FORMAT_ARGB8888_REV; - case PIPE_FORMAT_B8G8R8X8_UNORM: - return MESA_FORMAT_XRGB8888; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return MESA_FORMAT_XRGB8888_REV; - case PIPE_FORMAT_B5G5R5A1_UNORM: - return MESA_FORMAT_ARGB1555; - case PIPE_FORMAT_B4G4R4A4_UNORM: - return MESA_FORMAT_ARGB4444; - case PIPE_FORMAT_B5G6R5_UNORM: - return MESA_FORMAT_RGB565; - case PIPE_FORMAT_B2G3R3_UNORM: - return MESA_FORMAT_RGB332; - case PIPE_FORMAT_B10G10R10A2_UNORM: - return MESA_FORMAT_ARGB2101010; - case PIPE_FORMAT_L4A4_UNORM: - return MESA_FORMAT_AL44; - case PIPE_FORMAT_L8A8_UNORM: - return MESA_FORMAT_AL88; - case PIPE_FORMAT_L16A16_UNORM: - return MESA_FORMAT_AL1616; - case PIPE_FORMAT_A8_UNORM: - return MESA_FORMAT_A8; - case PIPE_FORMAT_A16_UNORM: - return MESA_FORMAT_A16; - case PIPE_FORMAT_L8_UNORM: - return MESA_FORMAT_L8; - case PIPE_FORMAT_L16_UNORM: - return MESA_FORMAT_L16; - case PIPE_FORMAT_I8_UNORM: - return MESA_FORMAT_I8; - case PIPE_FORMAT_I16_UNORM: - return MESA_FORMAT_I16; - case PIPE_FORMAT_S8_USCALED: - return MESA_FORMAT_S8; - - case PIPE_FORMAT_R16G16B16A16_UNORM: - return MESA_FORMAT_RGBA_16; - case PIPE_FORMAT_R16G16B16A16_SNORM: - return MESA_FORMAT_SIGNED_RGBA_16; - - case PIPE_FORMAT_Z16_UNORM: - return MESA_FORMAT_Z16; - case PIPE_FORMAT_Z32_UNORM: - return MESA_FORMAT_Z32; - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return MESA_FORMAT_Z24_S8; - case PIPE_FORMAT_X8Z24_UNORM: - return MESA_FORMAT_Z24_X8; - case PIPE_FORMAT_Z24X8_UNORM: - return MESA_FORMAT_X8_Z24; - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - return MESA_FORMAT_S8_Z24; - - case PIPE_FORMAT_UYVY: - return MESA_FORMAT_YCBCR; - case PIPE_FORMAT_YUYV: - return MESA_FORMAT_YCBCR_REV; - -#if FEATURE_texture_s3tc - case PIPE_FORMAT_DXT1_RGB: - return MESA_FORMAT_RGB_DXT1; - case PIPE_FORMAT_DXT1_RGBA: - return MESA_FORMAT_RGBA_DXT1; - case PIPE_FORMAT_DXT3_RGBA: - return MESA_FORMAT_RGBA_DXT3; - case PIPE_FORMAT_DXT5_RGBA: - return MESA_FORMAT_RGBA_DXT5; -#if FEATURE_EXT_texture_sRGB - case PIPE_FORMAT_DXT1_SRGB: - return MESA_FORMAT_SRGB_DXT1; - case PIPE_FORMAT_DXT1_SRGBA: - return MESA_FORMAT_SRGBA_DXT1; - case PIPE_FORMAT_DXT3_SRGBA: - return MESA_FORMAT_SRGBA_DXT3; - case PIPE_FORMAT_DXT5_SRGBA: - return MESA_FORMAT_SRGBA_DXT5; -#endif -#endif - -#if FEATURE_EXT_texture_sRGB - case PIPE_FORMAT_L8A8_SRGB: - return MESA_FORMAT_SLA8; - case PIPE_FORMAT_L8_SRGB: - return MESA_FORMAT_SL8; - case PIPE_FORMAT_R8G8B8_SRGB: - return MESA_FORMAT_SRGB8; - case PIPE_FORMAT_A8B8G8R8_SRGB: - return MESA_FORMAT_SRGBA8; - case PIPE_FORMAT_B8G8R8A8_SRGB: - return MESA_FORMAT_SARGB8; -#endif - - case PIPE_FORMAT_R8_UNORM: - return MESA_FORMAT_R8; - case PIPE_FORMAT_R16_UNORM: - return MESA_FORMAT_R16; - case PIPE_FORMAT_R8G8_UNORM: - return MESA_FORMAT_RG88; - case PIPE_FORMAT_R16G16_UNORM: - return MESA_FORMAT_RG1616; - - /* signed int formats */ - case PIPE_FORMAT_R8G8B8A8_SSCALED: - return MESA_FORMAT_RGBA_INT8; - case PIPE_FORMAT_R16G16B16A16_SSCALED: - return MESA_FORMAT_RGBA_INT16; - case PIPE_FORMAT_R32G32B32A32_SSCALED: - return MESA_FORMAT_RGBA_INT32; - - /* unsigned int formats */ - case PIPE_FORMAT_R8G8B8A8_USCALED: - return MESA_FORMAT_RGBA_UINT8; - case PIPE_FORMAT_R16G16B16A16_USCALED: - return MESA_FORMAT_RGBA_UINT16; - case PIPE_FORMAT_R32G32B32A32_USCALED: - return MESA_FORMAT_RGBA_UINT32; - - default: - assert(0); - return MESA_FORMAT_NONE; - } -} - - -/** - * Return first supported format from the given list. - */ -static enum pipe_format -find_supported_format(struct pipe_screen *screen, - const enum pipe_format formats[], - uint num_formats, - enum pipe_texture_target target, - unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) -{ - uint i; - for (i = 0; i < num_formats; i++) { - if (screen->is_format_supported(screen, formats[i], target, - sample_count, tex_usage, geom_flags)) { - return formats[i]; - } - } - return PIPE_FORMAT_NONE; -} - - -/** - * Find an RGBA format supported by the context/winsys. - */ -static enum pipe_format -default_rgba_format(struct pipe_screen *screen, - enum pipe_texture_target target, - unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) -{ - static const enum pipe_format colorFormats[] = { - PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_A8B8G8R8_UNORM, - PIPE_FORMAT_B5G6R5_UNORM - }; - return find_supported_format(screen, colorFormats, Elements(colorFormats), - target, sample_count, tex_usage, geom_flags); -} - - -/** - * Find an RGB format supported by the context/winsys. - */ -static enum pipe_format -default_rgb_format(struct pipe_screen *screen, - enum pipe_texture_target target, - unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) -{ - static const enum pipe_format colorFormats[] = { - PIPE_FORMAT_B8G8R8X8_UNORM, - PIPE_FORMAT_X8R8G8B8_UNORM, - PIPE_FORMAT_X8B8G8R8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_A8B8G8R8_UNORM, - PIPE_FORMAT_B5G6R5_UNORM - }; - return find_supported_format(screen, colorFormats, Elements(colorFormats), - target, sample_count, tex_usage, geom_flags); -} - -/** - * Find an sRGBA format supported by the context/winsys. - */ -static enum pipe_format -default_srgba_format(struct pipe_screen *screen, - enum pipe_texture_target target, - unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) -{ - static const enum pipe_format colorFormats[] = { - PIPE_FORMAT_B8G8R8A8_SRGB, - PIPE_FORMAT_A8R8G8B8_SRGB, - PIPE_FORMAT_A8B8G8R8_SRGB, - }; - return find_supported_format(screen, colorFormats, Elements(colorFormats), - target, sample_count, tex_usage, geom_flags); -} - - -/** - * Given an OpenGL internalFormat value for a texture or surface, return - * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match. - * This is called during glTexImage2D, for example. - * - * The bindings parameter typically has PIPE_BIND_SAMPLER_VIEW set, plus - * either PIPE_BINDING_RENDER_TARGET or PIPE_BINDING_DEPTH_STENCIL if - * we want render-to-texture ability. - * - * \param internalFormat the user value passed to glTexImage2D - * \param target one of PIPE_TEXTURE_x - * \param bindings bitmask of PIPE_BIND_x flags. - */ -enum pipe_format -st_choose_format(struct pipe_screen *screen, GLenum internalFormat, - enum pipe_texture_target target, unsigned sample_count, - unsigned bindings) -{ - unsigned geom_flags = 0; /* we don't care about POT vs. NPOT here, yet */ - - switch (internalFormat) { - case GL_RGB10: - case GL_RGB10_A2: - if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B10G10R10A2_UNORM; - /* Pass through. */ - case 4: - case GL_RGBA: - case GL_RGBA8: - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_BGRA: - if (screen->is_format_supported( screen, PIPE_FORMAT_B8G8R8A8_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B8G8R8A8_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case 3: - case GL_RGB: - case GL_RGB8: - return default_rgb_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_RGB12: - case GL_RGB16: - case GL_RGBA12: - case GL_RGBA16: - if (screen->is_format_supported( screen, PIPE_FORMAT_R16G16B16A16_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_R16G16B16A16_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_RGBA4: - case GL_RGBA2: - if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B4G4R4A4_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_RGB5_A1: - if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B5G5R5A1_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_R3_G3_B2: - if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B2G3R3_UNORM; - /* Pass through. */ - case GL_RGB5: - case GL_RGB4: - if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B5G6R5_UNORM; - if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM, - target, sample_count, bindings, - geom_flags )) - return PIPE_FORMAT_B5G5R5A1_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_ALPHA12: - case GL_ALPHA16: - if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_A16_UNORM; - /* Pass through. */ - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_COMPRESSED_ALPHA: - if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_A8_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_LUMINANCE12: - case GL_LUMINANCE16: - if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_L16_UNORM; - /* Pass through. */ - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_COMPRESSED_LUMINANCE: - if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_L8_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - if (screen->is_format_supported( screen, PIPE_FORMAT_L16A16_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_L16A16_UNORM; - /* Pass through. */ - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_COMPRESSED_LUMINANCE_ALPHA: - if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_L8A8_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_LUMINANCE4_ALPHA4: - if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_L4A4_UNORM; - if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_L8A8_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_INTENSITY12: - case GL_INTENSITY16: - if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_I16_UNORM; - /* Pass through. */ - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_COMPRESSED_INTENSITY: - if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target, - sample_count, bindings, geom_flags )) - return PIPE_FORMAT_I8_UNORM; - return default_rgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_YCBCR_MESA: - if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target, - sample_count, bindings, geom_flags)) { - return PIPE_FORMAT_UYVY; - } - if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target, - sample_count, bindings, geom_flags)) { - return PIPE_FORMAT_YUYV; - } - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_RED: - case GL_COMPRESSED_RG: - case GL_COMPRESSED_RGB: - /* can only sample from compressed formats */ - if (bindings & ~PIPE_BIND_SAMPLER_VIEW) - return PIPE_FORMAT_NONE; - else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB, - target, sample_count, bindings, - geom_flags)) - return PIPE_FORMAT_DXT1_RGB; - else - return default_rgb_format(screen, target, sample_count, bindings, - geom_flags); - - case GL_COMPRESSED_RGBA: - /* can only sample from compressed formats */ - if (bindings & ~PIPE_BIND_SAMPLER_VIEW) - return PIPE_FORMAT_NONE; - else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA, - target, sample_count, bindings, - geom_flags)) - return PIPE_FORMAT_DXT3_RGBA; - else - return default_rgba_format(screen, target, sample_count, bindings, - geom_flags); - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB, - target, sample_count, bindings, - geom_flags)) - return PIPE_FORMAT_DXT1_RGB; - else - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGBA, - target, sample_count, bindings, - geom_flags)) - return PIPE_FORMAT_DXT1_RGBA; - else - return PIPE_FORMAT_NONE; - - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA, - target, sample_count, bindings, - geom_flags)) - return PIPE_FORMAT_DXT3_RGBA; - else - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA, - target, sample_count, bindings, - geom_flags)) - return PIPE_FORMAT_DXT5_RGBA; - else - return PIPE_FORMAT_NONE; - -#if 0 - case GL_COMPRESSED_RGB_FXT1_3DFX: - return PIPE_FORMAT_RGB_FXT1; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return PIPE_FORMAT_RGB_FXT1; -#endif - - case GL_DEPTH_COMPONENT16: - if (screen->is_format_supported(screen, PIPE_FORMAT_Z16_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_Z16_UNORM; - /* fall-through */ - case GL_DEPTH_COMPONENT24: - if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, - target, sample_count, bindings, geom_flags)) - return PIPE_FORMAT_Z24_UNORM_S8_USCALED; - if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, - target, sample_count, bindings, geom_flags)) - return PIPE_FORMAT_S8_USCALED_Z24_UNORM; - /* fall-through */ - case GL_DEPTH_COMPONENT32: - if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_Z32_UNORM; - /* fall-through */ - case GL_DEPTH_COMPONENT: - { - static const enum pipe_format formats[] = { - PIPE_FORMAT_Z32_UNORM, - PIPE_FORMAT_Z24_UNORM_S8_USCALED, - PIPE_FORMAT_S8_USCALED_Z24_UNORM, - PIPE_FORMAT_Z16_UNORM - }; - return find_supported_format(screen, formats, Elements(formats), - target, sample_count, bindings, geom_flags); - } - - case GL_STENCIL_INDEX: - case GL_STENCIL_INDEX1_EXT: - case GL_STENCIL_INDEX4_EXT: - case GL_STENCIL_INDEX8_EXT: - case GL_STENCIL_INDEX16_EXT: - { - static const enum pipe_format formats[] = { - PIPE_FORMAT_S8_USCALED, - PIPE_FORMAT_Z24_UNORM_S8_USCALED, - PIPE_FORMAT_S8_USCALED_Z24_UNORM - }; - return find_supported_format(screen, formats, Elements(formats), - target, sample_count, bindings, geom_flags); - } - - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - { - static const enum pipe_format formats[] = { - PIPE_FORMAT_Z24_UNORM_S8_USCALED, - PIPE_FORMAT_S8_USCALED_Z24_UNORM - }; - return find_supported_format(screen, formats, Elements(formats), - target, sample_count, bindings, geom_flags); - } - - case GL_SRGB_EXT: - case GL_SRGB8_EXT: - case GL_SRGB_ALPHA_EXT: - case GL_SRGB8_ALPHA8_EXT: - return default_srgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_COMPRESSED_SRGB_EXT: - case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGB, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_DXT1_SRGB; - return default_srgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - return PIPE_FORMAT_DXT1_SRGBA; - - case GL_COMPRESSED_SRGB_ALPHA_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_SRGBA, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_DXT3_SRGBA; - return default_srgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - return PIPE_FORMAT_DXT5_SRGBA; - - case GL_SLUMINANCE_ALPHA_EXT: - case GL_SLUMINANCE8_ALPHA8_EXT: - case GL_COMPRESSED_SLUMINANCE_EXT: - case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_L8A8_SRGB; - return default_srgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_SLUMINANCE_EXT: - case GL_SLUMINANCE8_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_L8_SRGB; - return default_srgba_format( screen, target, sample_count, bindings, - geom_flags ); - - case GL_RED: - case GL_R8: - if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R8_UNORM; - return PIPE_FORMAT_NONE; - case GL_RG: - case GL_RG8: - if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R8G8_UNORM; - return PIPE_FORMAT_NONE; - - case GL_R16: - if (screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R16_UNORM; - return PIPE_FORMAT_NONE; - - case GL_RG16: - if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R16G16_UNORM; - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_RED_RGTC1: - if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_RGTC1_UNORM; - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_SIGNED_RED_RGTC1: - if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_SNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_RGTC1_SNORM; - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_RG_RGTC2: - if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_RGTC2_UNORM; - return PIPE_FORMAT_NONE; - - case GL_COMPRESSED_SIGNED_RG_RGTC2: - if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_SNORM, target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_RGTC2_SNORM; - return PIPE_FORMAT_NONE; - - /* signed/unsigned integer formats. - * XXX Mesa only has formats for RGBA signed/unsigned integer formats. - * If/when new formats are added this code should be updated. - */ - case GL_RED_INTEGER_EXT: - case GL_GREEN_INTEGER_EXT: - case GL_BLUE_INTEGER_EXT: - case GL_ALPHA_INTEGER_EXT: - case GL_RGB_INTEGER_EXT: - case GL_RGBA_INTEGER_EXT: - case GL_BGR_INTEGER_EXT: - case GL_BGRA_INTEGER_EXT: - case GL_LUMINANCE_INTEGER_EXT: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - /* fall-through */ - case GL_RGBA8I_EXT: - case GL_RGB8I_EXT: - case GL_ALPHA8I_EXT: - case GL_INTENSITY8I_EXT: - case GL_LUMINANCE8I_EXT: - case GL_LUMINANCE_ALPHA8I_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SSCALED, - target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R8G8B8A8_SSCALED; - return PIPE_FORMAT_NONE; - case GL_RGBA16I_EXT: - case GL_RGB16I_EXT: - case GL_ALPHA16I_EXT: - case GL_INTENSITY16I_EXT: - case GL_LUMINANCE16I_EXT: - case GL_LUMINANCE_ALPHA16I_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_SSCALED, - target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R16G16B16A16_SSCALED; - return PIPE_FORMAT_NONE; - case GL_RGBA32I_EXT: - case GL_RGB32I_EXT: - case GL_ALPHA32I_EXT: - case GL_INTENSITY32I_EXT: - case GL_LUMINANCE32I_EXT: - case GL_LUMINANCE_ALPHA32I_EXT: - /* xxx */ - if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_SSCALED, - target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R32G32B32A32_SSCALED; - return PIPE_FORMAT_NONE; - - case GL_RGBA8UI_EXT: - case GL_RGB8UI_EXT: - case GL_ALPHA8UI_EXT: - case GL_INTENSITY8UI_EXT: - case GL_LUMINANCE8UI_EXT: - case GL_LUMINANCE_ALPHA8UI_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_USCALED, - target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R8G8B8A8_USCALED; - return PIPE_FORMAT_NONE; - - case GL_RGBA16UI_EXT: - case GL_RGB16UI_EXT: - case GL_ALPHA16UI_EXT: - case GL_INTENSITY16UI_EXT: - case GL_LUMINANCE16UI_EXT: - case GL_LUMINANCE_ALPHA16UI_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_USCALED, - target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R16G16B16A16_USCALED; - return PIPE_FORMAT_NONE; - - case GL_RGBA32UI_EXT: - case GL_RGB32UI_EXT: - case GL_ALPHA32UI_EXT: - case GL_INTENSITY32UI_EXT: - case GL_LUMINANCE32UI_EXT: - case GL_LUMINANCE_ALPHA32UI_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_USCALED, - target, - sample_count, bindings, geom_flags)) - return PIPE_FORMAT_R32G32B32A32_USCALED; - return PIPE_FORMAT_NONE; - - default: - return PIPE_FORMAT_NONE; - } -} - - -/** - * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces. - */ -enum pipe_format -st_choose_renderbuffer_format(struct pipe_screen *screen, - GLenum internalFormat, unsigned sample_count) -{ - uint usage; - if (_mesa_is_depth_or_stencil_format(internalFormat)) - usage = PIPE_BIND_DEPTH_STENCIL; - else - usage = PIPE_BIND_RENDER_TARGET; - return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, - sample_count, usage); -} - - -/** - * Called via ctx->Driver.chooseTextureFormat(). - */ -gl_format -st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, - GLenum format, GLenum type, GLboolean renderable) -{ - struct pipe_screen *screen = st_context(ctx)->pipe->screen; - enum pipe_format pFormat; - uint bindings; - - (void) format; - (void) type; - - /* GL textures may wind up being render targets, but we don't know - * that in advance. Specify potential render target flags now. - */ - bindings = PIPE_BIND_SAMPLER_VIEW; - if (renderable == GL_TRUE) { - if (_mesa_is_depth_format(internalFormat) || - _mesa_is_depth_or_stencil_format(internalFormat)) - bindings |= PIPE_BIND_DEPTH_STENCIL; - else - bindings |= PIPE_BIND_RENDER_TARGET; - } - - pFormat = st_choose_format(screen, internalFormat, - PIPE_TEXTURE_2D, 0, bindings); - - if (pFormat == PIPE_FORMAT_NONE) { - /* try choosing format again, this time without render target bindings */ - pFormat = st_choose_format(screen, internalFormat, - PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); - } - - if (pFormat == PIPE_FORMAT_NONE) { - /* no luck at all */ - return MESA_FORMAT_NONE; - } - - return st_pipe_format_to_mesa_format(pFormat); -} - -gl_format -st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat, - GLenum format, GLenum type) -{ - boolean want_renderable = - internalFormat == 3 || internalFormat == 4 || - internalFormat == GL_RGB || internalFormat == GL_RGBA || - internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 || - internalFormat == GL_BGRA; - - return st_ChooseTextureFormat_renderable(ctx, internalFormat, - format, type, want_renderable); -} - -/** - * Test if a gallium format is equivalent to a GL format/type. - */ -GLboolean -st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type) -{ - switch (pFormat) { - case PIPE_FORMAT_A8B8G8R8_UNORM: - return format == GL_RGBA && type == GL_UNSIGNED_BYTE; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return format == GL_BGRA && type == GL_UNSIGNED_BYTE; - case PIPE_FORMAT_B5G6R5_UNORM: - return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5; - /* XXX more combos... */ - default: - return GL_FALSE; - } -} - -GLboolean -st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2) -{ - if (format1 == format2) - return GL_TRUE; - - if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM && - format2 == PIPE_FORMAT_B8G8R8X8_UNORM) - return GL_TRUE; - - if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM && - format2 == PIPE_FORMAT_B8G8R8A8_UNORM) - return GL_TRUE; - - if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM && - format2 == PIPE_FORMAT_X8B8G8R8_UNORM) - return GL_TRUE; - - if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM && - format2 == PIPE_FORMAT_A8B8G8R8_UNORM) - return GL_TRUE; - - if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM && - format2 == PIPE_FORMAT_X8R8G8B8_UNORM) - return GL_TRUE; - - if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM && - format2 == PIPE_FORMAT_A8R8G8B8_UNORM) - return GL_TRUE; - - return GL_FALSE; -} +/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright (c) 2008-2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * Mesa / Gallium format conversion and format selection code.
+ * \author Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/texstore.h"
+#include "main/image.h"
+#include "main/macros.h"
+#include "main/mfeatures.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+#include "util/u_format.h"
+#include "st_context.h"
+#include "st_format.h"
+
+
+static GLuint
+format_max_bits(enum pipe_format format)
+{
+ GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
+
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1));
+ return size;
+}
+
+
+/**
+ * Return basic GL datatype for the given gallium format.
+ */
+GLenum
+st_format_datatype(enum pipe_format format)
+{
+ const struct util_format_description *desc;
+
+ desc = util_format_description(format);
+ assert(desc);
+
+ if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
+ if (format == PIPE_FORMAT_B5G5R5A1_UNORM ||
+ format == PIPE_FORMAT_B5G6R5_UNORM) {
+ return GL_UNSIGNED_SHORT;
+ }
+ else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
+ format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
+ format == PIPE_FORMAT_Z24X8_UNORM ||
+ format == PIPE_FORMAT_X8Z24_UNORM) {
+ return GL_UNSIGNED_INT_24_8;
+ }
+ else {
+ const GLuint size = format_max_bits(format);
+ if (size == 8) {
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
+ return GL_UNSIGNED_BYTE;
+ else
+ return GL_BYTE;
+ }
+ else if (size == 16) {
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
+ return GL_UNSIGNED_SHORT;
+ else
+ return GL_SHORT;
+ }
+ else {
+ assert( size <= 32 );
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
+ return GL_UNSIGNED_INT;
+ else
+ return GL_INT;
+ }
+ }
+ }
+ else if (format == PIPE_FORMAT_UYVY) {
+ return GL_UNSIGNED_SHORT;
+ }
+ else if (format == PIPE_FORMAT_YUYV) {
+ return GL_UNSIGNED_SHORT;
+ }
+ else {
+ /* probably a compressed format, unsupported anyway */
+ return GL_NONE;
+ }
+}
+
+
+/**
+ * Translate Mesa format to Gallium format.
+ */
+enum pipe_format
+st_mesa_format_to_pipe_format(gl_format mesaFormat)
+{
+ switch (mesaFormat) {
+ case MESA_FORMAT_RGBA8888:
+ return PIPE_FORMAT_A8B8G8R8_UNORM;
+ case MESA_FORMAT_RGBA8888_REV:
+ return PIPE_FORMAT_R8G8B8A8_UNORM;
+ case MESA_FORMAT_ARGB8888:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ case MESA_FORMAT_ARGB8888_REV:
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ case MESA_FORMAT_XRGB8888:
+ return PIPE_FORMAT_B8G8R8X8_UNORM;
+ case MESA_FORMAT_XRGB8888_REV:
+ return PIPE_FORMAT_X8R8G8B8_UNORM;
+ case MESA_FORMAT_ARGB1555:
+ return PIPE_FORMAT_B5G5R5A1_UNORM;
+ case MESA_FORMAT_ARGB4444:
+ return PIPE_FORMAT_B4G4R4A4_UNORM;
+ case MESA_FORMAT_RGB565:
+ return PIPE_FORMAT_B5G6R5_UNORM;
+ case MESA_FORMAT_RGB332:
+ return PIPE_FORMAT_B2G3R3_UNORM;
+ case MESA_FORMAT_ARGB2101010:
+ return PIPE_FORMAT_B10G10R10A2_UNORM;
+ case MESA_FORMAT_AL44:
+ return PIPE_FORMAT_L4A4_UNORM;
+ case MESA_FORMAT_AL88:
+ return PIPE_FORMAT_L8A8_UNORM;
+ case MESA_FORMAT_AL1616:
+ return PIPE_FORMAT_L16A16_UNORM;
+ case MESA_FORMAT_A8:
+ return PIPE_FORMAT_A8_UNORM;
+ case MESA_FORMAT_A16:
+ return PIPE_FORMAT_A16_UNORM;
+ case MESA_FORMAT_L8:
+ return PIPE_FORMAT_L8_UNORM;
+ case MESA_FORMAT_L16:
+ return PIPE_FORMAT_L16_UNORM;
+ case MESA_FORMAT_I8:
+ return PIPE_FORMAT_I8_UNORM;
+ case MESA_FORMAT_I16:
+ return PIPE_FORMAT_I16_UNORM;
+ case MESA_FORMAT_Z16:
+ return PIPE_FORMAT_Z16_UNORM;
+ case MESA_FORMAT_Z32:
+ return PIPE_FORMAT_Z32_UNORM;
+ case MESA_FORMAT_Z24_S8:
+ return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
+ case MESA_FORMAT_S8_Z24:
+ return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
+ case MESA_FORMAT_Z24_X8:
+ return PIPE_FORMAT_X8Z24_UNORM;
+ case MESA_FORMAT_X8_Z24:
+ return PIPE_FORMAT_Z24X8_UNORM;
+ case MESA_FORMAT_S8:
+ return PIPE_FORMAT_S8_USCALED;
+ case MESA_FORMAT_YCBCR:
+ return PIPE_FORMAT_UYVY;
+#if FEATURE_texture_s3tc
+ case MESA_FORMAT_RGB_DXT1:
+ return PIPE_FORMAT_DXT1_RGB;
+ case MESA_FORMAT_RGBA_DXT1:
+ return PIPE_FORMAT_DXT1_RGBA;
+ case MESA_FORMAT_RGBA_DXT3:
+ return PIPE_FORMAT_DXT3_RGBA;
+ case MESA_FORMAT_RGBA_DXT5:
+ return PIPE_FORMAT_DXT5_RGBA;
+#if FEATURE_EXT_texture_sRGB
+ case MESA_FORMAT_SRGB_DXT1:
+ return PIPE_FORMAT_DXT1_SRGB;
+ case MESA_FORMAT_SRGBA_DXT1:
+ return PIPE_FORMAT_DXT1_SRGBA;
+ case MESA_FORMAT_SRGBA_DXT3:
+ return PIPE_FORMAT_DXT3_SRGBA;
+ case MESA_FORMAT_SRGBA_DXT5:
+ return PIPE_FORMAT_DXT5_SRGBA;
+#endif
+#endif
+#if FEATURE_EXT_texture_sRGB
+ case MESA_FORMAT_SLA8:
+ return PIPE_FORMAT_L8A8_SRGB;
+ case MESA_FORMAT_SL8:
+ return PIPE_FORMAT_L8_SRGB;
+ case MESA_FORMAT_SRGB8:
+ return PIPE_FORMAT_R8G8B8_SRGB;
+ case MESA_FORMAT_SRGBA8:
+ return PIPE_FORMAT_A8B8G8R8_SRGB;
+ case MESA_FORMAT_SARGB8:
+ return PIPE_FORMAT_B8G8R8A8_SRGB;
+#endif
+ case MESA_FORMAT_R8:
+ return PIPE_FORMAT_R8_UNORM;
+ case MESA_FORMAT_R16:
+ return PIPE_FORMAT_R16_UNORM;
+ case MESA_FORMAT_RG88:
+ return PIPE_FORMAT_R8G8_UNORM;
+ case MESA_FORMAT_RG1616:
+ return PIPE_FORMAT_R16G16_UNORM;
+ case MESA_FORMAT_RGBA_16:
+ return PIPE_FORMAT_R16G16B16A16_UNORM;
+
+ /* signed int formats */
+ case MESA_FORMAT_RGBA_INT8:
+ return PIPE_FORMAT_R8G8B8A8_SSCALED;
+ case MESA_FORMAT_RGBA_INT16:
+ return PIPE_FORMAT_R16G16B16A16_SSCALED;
+ case MESA_FORMAT_RGBA_INT32:
+ return PIPE_FORMAT_R32G32B32A32_SSCALED;
+
+ /* unsigned int formats */
+ case MESA_FORMAT_RGBA_UINT8:
+ return PIPE_FORMAT_R8G8B8A8_USCALED;
+ case MESA_FORMAT_RGBA_UINT16:
+ return PIPE_FORMAT_R16G16B16A16_USCALED;
+ case MESA_FORMAT_RGBA_UINT32:
+ return PIPE_FORMAT_R32G32B32A32_USCALED;
+
+ default:
+ assert(0);
+ return PIPE_FORMAT_NONE;
+ }
+}
+
+
+/**
+ * Translate Gallium format to Mesa format.
+ */
+gl_format
+st_pipe_format_to_mesa_format(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ return MESA_FORMAT_RGBA8888;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return MESA_FORMAT_RGBA8888_REV;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ return MESA_FORMAT_ARGB8888;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ return MESA_FORMAT_ARGB8888_REV;
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return MESA_FORMAT_XRGB8888;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ return MESA_FORMAT_XRGB8888_REV;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ return MESA_FORMAT_ARGB1555;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ return MESA_FORMAT_ARGB4444;
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return MESA_FORMAT_RGB565;
+ case PIPE_FORMAT_B2G3R3_UNORM:
+ return MESA_FORMAT_RGB332;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ return MESA_FORMAT_ARGB2101010;
+ case PIPE_FORMAT_L4A4_UNORM:
+ return MESA_FORMAT_AL44;
+ case PIPE_FORMAT_L8A8_UNORM:
+ return MESA_FORMAT_AL88;
+ case PIPE_FORMAT_L16A16_UNORM:
+ return MESA_FORMAT_AL1616;
+ case PIPE_FORMAT_A8_UNORM:
+ return MESA_FORMAT_A8;
+ case PIPE_FORMAT_A16_UNORM:
+ return MESA_FORMAT_A16;
+ case PIPE_FORMAT_L8_UNORM:
+ return MESA_FORMAT_L8;
+ case PIPE_FORMAT_L16_UNORM:
+ return MESA_FORMAT_L16;
+ case PIPE_FORMAT_I8_UNORM:
+ return MESA_FORMAT_I8;
+ case PIPE_FORMAT_I16_UNORM:
+ return MESA_FORMAT_I16;
+ case PIPE_FORMAT_S8_USCALED:
+ return MESA_FORMAT_S8;
+
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ return MESA_FORMAT_RGBA_16;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return MESA_FORMAT_SIGNED_RGBA_16;
+
+ case PIPE_FORMAT_Z16_UNORM:
+ return MESA_FORMAT_Z16;
+ case PIPE_FORMAT_Z32_UNORM:
+ return MESA_FORMAT_Z32;
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ return MESA_FORMAT_Z24_S8;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ return MESA_FORMAT_Z24_X8;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return MESA_FORMAT_X8_Z24;
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ return MESA_FORMAT_S8_Z24;
+
+ case PIPE_FORMAT_UYVY:
+ return MESA_FORMAT_YCBCR;
+ case PIPE_FORMAT_YUYV:
+ return MESA_FORMAT_YCBCR_REV;
+
+#if FEATURE_texture_s3tc
+ case PIPE_FORMAT_DXT1_RGB:
+ return MESA_FORMAT_RGB_DXT1;
+ case PIPE_FORMAT_DXT1_RGBA:
+ return MESA_FORMAT_RGBA_DXT1;
+ case PIPE_FORMAT_DXT3_RGBA:
+ return MESA_FORMAT_RGBA_DXT3;
+ case PIPE_FORMAT_DXT5_RGBA:
+ return MESA_FORMAT_RGBA_DXT5;
+#if FEATURE_EXT_texture_sRGB
+ case PIPE_FORMAT_DXT1_SRGB:
+ return MESA_FORMAT_SRGB_DXT1;
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return MESA_FORMAT_SRGBA_DXT1;
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return MESA_FORMAT_SRGBA_DXT3;
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return MESA_FORMAT_SRGBA_DXT5;
+#endif
+#endif
+
+#if FEATURE_EXT_texture_sRGB
+ case PIPE_FORMAT_L8A8_SRGB:
+ return MESA_FORMAT_SLA8;
+ case PIPE_FORMAT_L8_SRGB:
+ return MESA_FORMAT_SL8;
+ case PIPE_FORMAT_R8G8B8_SRGB:
+ return MESA_FORMAT_SRGB8;
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ return MESA_FORMAT_SRGBA8;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return MESA_FORMAT_SARGB8;
+#endif
+
+ case PIPE_FORMAT_R8_UNORM:
+ return MESA_FORMAT_R8;
+ case PIPE_FORMAT_R16_UNORM:
+ return MESA_FORMAT_R16;
+ case PIPE_FORMAT_R8G8_UNORM:
+ return MESA_FORMAT_RG88;
+ case PIPE_FORMAT_R16G16_UNORM:
+ return MESA_FORMAT_RG1616;
+
+ /* signed int formats */
+ case PIPE_FORMAT_R8G8B8A8_SSCALED:
+ return MESA_FORMAT_RGBA_INT8;
+ case PIPE_FORMAT_R16G16B16A16_SSCALED:
+ return MESA_FORMAT_RGBA_INT16;
+ case PIPE_FORMAT_R32G32B32A32_SSCALED:
+ return MESA_FORMAT_RGBA_INT32;
+
+ /* unsigned int formats */
+ case PIPE_FORMAT_R8G8B8A8_USCALED:
+ return MESA_FORMAT_RGBA_UINT8;
+ case PIPE_FORMAT_R16G16B16A16_USCALED:
+ return MESA_FORMAT_RGBA_UINT16;
+ case PIPE_FORMAT_R32G32B32A32_USCALED:
+ return MESA_FORMAT_RGBA_UINT32;
+
+ default:
+ assert(0);
+ return MESA_FORMAT_NONE;
+ }
+}
+
+
+/**
+ * Return first supported format from the given list.
+ */
+static enum pipe_format
+find_supported_format(struct pipe_screen *screen,
+ const enum pipe_format formats[],
+ uint num_formats,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned tex_usage,
+ unsigned geom_flags)
+{
+ uint i;
+ for (i = 0; i < num_formats; i++) {
+ if (screen->is_format_supported(screen, formats[i], target,
+ sample_count, tex_usage, geom_flags)) {
+ return formats[i];
+ }
+ }
+ return PIPE_FORMAT_NONE;
+}
+
+
+/**
+ * Find an RGBA format supported by the context/winsys.
+ */
+static enum pipe_format
+default_rgba_format(struct pipe_screen *screen,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned tex_usage,
+ unsigned geom_flags)
+{
+ static const enum pipe_format colorFormats[] = {
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_A8B8G8R8_UNORM,
+ PIPE_FORMAT_B5G6R5_UNORM
+ };
+ return find_supported_format(screen, colorFormats, Elements(colorFormats),
+ target, sample_count, tex_usage, geom_flags);
+}
+
+
+/**
+ * Find an RGB format supported by the context/winsys.
+ */
+static enum pipe_format
+default_rgb_format(struct pipe_screen *screen,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned tex_usage,
+ unsigned geom_flags)
+{
+ static const enum pipe_format colorFormats[] = {
+ PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_X8R8G8B8_UNORM,
+ PIPE_FORMAT_X8B8G8R8_UNORM,
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_A8B8G8R8_UNORM,
+ PIPE_FORMAT_B5G6R5_UNORM
+ };
+ return find_supported_format(screen, colorFormats, Elements(colorFormats),
+ target, sample_count, tex_usage, geom_flags);
+}
+
+/**
+ * Find an sRGBA format supported by the context/winsys.
+ */
+static enum pipe_format
+default_srgba_format(struct pipe_screen *screen,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned tex_usage,
+ unsigned geom_flags)
+{
+ static const enum pipe_format colorFormats[] = {
+ PIPE_FORMAT_B8G8R8A8_SRGB,
+ PIPE_FORMAT_A8R8G8B8_SRGB,
+ PIPE_FORMAT_A8B8G8R8_SRGB,
+ };
+ return find_supported_format(screen, colorFormats, Elements(colorFormats),
+ target, sample_count, tex_usage, geom_flags);
+}
+
+
+/**
+ * Given an OpenGL internalFormat value for a texture or surface, return
+ * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
+ * This is called during glTexImage2D, for example.
+ *
+ * The bindings parameter typically has PIPE_BIND_SAMPLER_VIEW set, plus
+ * either PIPE_BINDING_RENDER_TARGET or PIPE_BINDING_DEPTH_STENCIL if
+ * we want render-to-texture ability.
+ *
+ * \param internalFormat the user value passed to glTexImage2D
+ * \param target one of PIPE_TEXTURE_x
+ * \param bindings bitmask of PIPE_BIND_x flags.
+ */
+enum pipe_format
+st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
+ enum pipe_texture_target target, unsigned sample_count,
+ unsigned bindings)
+{
+ unsigned geom_flags = 0; /* we don't care about POT vs. NPOT here, yet */
+
+ switch (internalFormat) {
+ case GL_RGB10:
+ case GL_RGB10_A2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B10G10R10A2_UNORM;
+ /* Pass through. */
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA8:
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_BGRA:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B8G8R8A8_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case 3:
+ case GL_RGB:
+ case GL_RGB8:
+ return default_rgb_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_RGB12:
+ case GL_RGB16:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_R16G16B16A16_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_R16G16B16A16_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B4G4R4A4_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_RGB5_A1:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B5G5R5A1_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_R3_G3_B2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B2G3R3_UNORM;
+ /* Pass through. */
+ case GL_RGB5:
+ case GL_RGB4:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B5G6R5_UNORM;
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B5G5R5A1_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_A16_UNORM;
+ /* Pass through. */
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_COMPRESSED_ALPHA:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L16_UNORM;
+ /* Pass through. */
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_COMPRESSED_LUMINANCE:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L16A16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L16A16_UNORM;
+ /* Pass through. */
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_LUMINANCE4_ALPHA4:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L4A4_UNORM;
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_I16_UNORM;
+ /* Pass through. */
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_COMPRESSED_INTENSITY:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_I8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_YCBCR_MESA:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target,
+ sample_count, bindings, geom_flags)) {
+ return PIPE_FORMAT_UYVY;
+ }
+ if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target,
+ sample_count, bindings, geom_flags)) {
+ return PIPE_FORMAT_YUYV;
+ }
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RED:
+ case GL_COMPRESSED_RG:
+ case GL_COMPRESSED_RGB:
+ /* can only sample from compressed formats */
+ if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
+ return PIPE_FORMAT_NONE;
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
+ target, sample_count, bindings,
+ geom_flags))
+ return PIPE_FORMAT_DXT1_RGB;
+ else
+ return default_rgb_format(screen, target, sample_count, bindings,
+ geom_flags);
+
+ case GL_COMPRESSED_RGBA:
+ /* can only sample from compressed formats */
+ if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
+ return PIPE_FORMAT_NONE;
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
+ target, sample_count, bindings,
+ geom_flags))
+ return PIPE_FORMAT_DXT3_RGBA;
+ else
+ return default_rgba_format(screen, target, sample_count, bindings,
+ geom_flags);
+
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
+ target, sample_count, bindings,
+ geom_flags))
+ return PIPE_FORMAT_DXT1_RGB;
+ else
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGBA,
+ target, sample_count, bindings,
+ geom_flags))
+ return PIPE_FORMAT_DXT1_RGBA;
+ else
+ return PIPE_FORMAT_NONE;
+
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
+ target, sample_count, bindings,
+ geom_flags))
+ return PIPE_FORMAT_DXT3_RGBA;
+ else
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
+ target, sample_count, bindings,
+ geom_flags))
+ return PIPE_FORMAT_DXT5_RGBA;
+ else
+ return PIPE_FORMAT_NONE;
+
+#if 0
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ return PIPE_FORMAT_RGB_FXT1;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return PIPE_FORMAT_RGB_FXT1;
+#endif
+
+ case GL_DEPTH_COMPONENT16:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_Z16_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_Z16_UNORM;
+ /* fall-through */
+ case GL_DEPTH_COMPONENT24:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+ target, sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ target, sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
+ /* fall-through */
+ case GL_DEPTH_COMPONENT32:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_Z32_UNORM;
+ /* fall-through */
+ case GL_DEPTH_COMPONENT:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_Z32_UNORM,
+ PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+ PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ PIPE_FORMAT_Z16_UNORM
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings, geom_flags);
+ }
+
+ case GL_STENCIL_INDEX:
+ case GL_STENCIL_INDEX1_EXT:
+ case GL_STENCIL_INDEX4_EXT:
+ case GL_STENCIL_INDEX8_EXT:
+ case GL_STENCIL_INDEX16_EXT:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_S8_USCALED,
+ PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+ PIPE_FORMAT_S8_USCALED_Z24_UNORM
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings, geom_flags);
+ }
+
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+ PIPE_FORMAT_S8_USCALED_Z24_UNORM
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings, geom_flags);
+ }
+
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGB, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_DXT1_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ return PIPE_FORMAT_DXT1_SRGBA;
+
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_SRGBA, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_DXT3_SRGBA;
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ return PIPE_FORMAT_DXT5_SRGBA;
+
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_L8A8_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_L8_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_RED:
+ case GL_R8:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R8_UNORM;
+ return PIPE_FORMAT_NONE;
+ case GL_RG:
+ case GL_RG8:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R8G8_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_R16:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R16_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_RG16:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R16G16_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RED_RGTC1:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_RGTC1_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_SIGNED_RED_RGTC1:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_SNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_RGTC1_SNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RG_RGTC2:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_RGTC2_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_SIGNED_RG_RGTC2:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_SNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_RGTC2_SNORM;
+ return PIPE_FORMAT_NONE;
+
+ /* signed/unsigned integer formats.
+ * XXX Mesa only has formats for RGBA signed/unsigned integer formats.
+ * If/when new formats are added this code should be updated.
+ */
+ case GL_RED_INTEGER_EXT:
+ case GL_GREEN_INTEGER_EXT:
+ case GL_BLUE_INTEGER_EXT:
+ case GL_ALPHA_INTEGER_EXT:
+ case GL_RGB_INTEGER_EXT:
+ case GL_RGBA_INTEGER_EXT:
+ case GL_BGR_INTEGER_EXT:
+ case GL_BGRA_INTEGER_EXT:
+ case GL_LUMINANCE_INTEGER_EXT:
+ case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+ /* fall-through */
+ case GL_RGBA8I_EXT:
+ case GL_RGB8I_EXT:
+ case GL_ALPHA8I_EXT:
+ case GL_INTENSITY8I_EXT:
+ case GL_LUMINANCE8I_EXT:
+ case GL_LUMINANCE_ALPHA8I_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SSCALED,
+ target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R8G8B8A8_SSCALED;
+ return PIPE_FORMAT_NONE;
+ case GL_RGBA16I_EXT:
+ case GL_RGB16I_EXT:
+ case GL_ALPHA16I_EXT:
+ case GL_INTENSITY16I_EXT:
+ case GL_LUMINANCE16I_EXT:
+ case GL_LUMINANCE_ALPHA16I_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_SSCALED,
+ target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R16G16B16A16_SSCALED;
+ return PIPE_FORMAT_NONE;
+ case GL_RGBA32I_EXT:
+ case GL_RGB32I_EXT:
+ case GL_ALPHA32I_EXT:
+ case GL_INTENSITY32I_EXT:
+ case GL_LUMINANCE32I_EXT:
+ case GL_LUMINANCE_ALPHA32I_EXT:
+ /* xxx */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_SSCALED,
+ target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R32G32B32A32_SSCALED;
+ return PIPE_FORMAT_NONE;
+
+ case GL_RGBA8UI_EXT:
+ case GL_RGB8UI_EXT:
+ case GL_ALPHA8UI_EXT:
+ case GL_INTENSITY8UI_EXT:
+ case GL_LUMINANCE8UI_EXT:
+ case GL_LUMINANCE_ALPHA8UI_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_USCALED,
+ target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R8G8B8A8_USCALED;
+ return PIPE_FORMAT_NONE;
+
+ case GL_RGBA16UI_EXT:
+ case GL_RGB16UI_EXT:
+ case GL_ALPHA16UI_EXT:
+ case GL_INTENSITY16UI_EXT:
+ case GL_LUMINANCE16UI_EXT:
+ case GL_LUMINANCE_ALPHA16UI_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_USCALED,
+ target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R16G16B16A16_USCALED;
+ return PIPE_FORMAT_NONE;
+
+ case GL_RGBA32UI_EXT:
+ case GL_RGB32UI_EXT:
+ case GL_ALPHA32UI_EXT:
+ case GL_INTENSITY32UI_EXT:
+ case GL_LUMINANCE32UI_EXT:
+ case GL_LUMINANCE_ALPHA32UI_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_USCALED,
+ target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R32G32B32A32_USCALED;
+ return PIPE_FORMAT_NONE;
+
+ default:
+ return PIPE_FORMAT_NONE;
+ }
+}
+
+
+/**
+ * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
+ */
+enum pipe_format
+st_choose_renderbuffer_format(struct pipe_screen *screen,
+ GLenum internalFormat, unsigned sample_count)
+{
+ uint usage;
+ if (_mesa_is_depth_or_stencil_format(internalFormat))
+ usage = PIPE_BIND_DEPTH_STENCIL;
+ else
+ usage = PIPE_BIND_RENDER_TARGET;
+ return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D,
+ sample_count, usage);
+}
+
+
+/**
+ * Called via ctx->Driver.chooseTextureFormat().
+ */
+gl_format
+st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
+ GLenum format, GLenum type, GLboolean renderable)
+{
+ struct pipe_screen *screen = st_context(ctx)->pipe->screen;
+ enum pipe_format pFormat;
+ uint bindings;
+
+ (void) format;
+ (void) type;
+
+ /* GL textures may wind up being render targets, but we don't know
+ * that in advance. Specify potential render target flags now.
+ */
+ bindings = PIPE_BIND_SAMPLER_VIEW;
+ if (renderable == GL_TRUE) {
+ if (_mesa_is_depth_format(internalFormat) ||
+ _mesa_is_depth_or_stencil_format(internalFormat))
+ bindings |= PIPE_BIND_DEPTH_STENCIL;
+ else
+ bindings |= PIPE_BIND_RENDER_TARGET;
+ }
+
+ pFormat = st_choose_format(screen, internalFormat,
+ PIPE_TEXTURE_2D, 0, bindings);
+
+ if (pFormat == PIPE_FORMAT_NONE) {
+ /* try choosing format again, this time without render target bindings */
+ pFormat = st_choose_format(screen, internalFormat,
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
+ }
+
+ if (pFormat == PIPE_FORMAT_NONE) {
+ /* no luck at all */
+ return MESA_FORMAT_NONE;
+ }
+
+ return st_pipe_format_to_mesa_format(pFormat);
+}
+
+gl_format
+st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
+ GLenum format, GLenum type)
+{
+ boolean want_renderable =
+ internalFormat == 3 || internalFormat == 4 ||
+ internalFormat == GL_RGB || internalFormat == GL_RGBA ||
+ internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 ||
+ internalFormat == GL_BGRA;
+
+ return st_ChooseTextureFormat_renderable(ctx, internalFormat,
+ format, type, want_renderable);
+}
+
+/**
+ * Test if a gallium format is equivalent to a GL format/type.
+ */
+GLboolean
+st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type)
+{
+ switch (pFormat) {
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ return format == GL_RGBA && type == GL_UNSIGNED_BYTE;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ return format == GL_BGRA && type == GL_UNSIGNED_BYTE;
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5;
+ /* XXX more combos... */
+ default:
+ return GL_FALSE;
+ }
+}
+
+GLboolean
+st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
+{
+ if (format1 == format2)
+ return GL_TRUE;
+
+ if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM &&
+ format2 == PIPE_FORMAT_B8G8R8X8_UNORM)
+ return GL_TRUE;
+
+ if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM &&
+ format2 == PIPE_FORMAT_B8G8R8A8_UNORM)
+ return GL_TRUE;
+
+ if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM &&
+ format2 == PIPE_FORMAT_X8B8G8R8_UNORM)
+ return GL_TRUE;
+
+ if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM &&
+ format2 == PIPE_FORMAT_A8B8G8R8_UNORM)
+ return GL_TRUE;
+
+ if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM &&
+ format2 == PIPE_FORMAT_X8R8G8B8_UNORM)
+ return GL_TRUE;
+
+ if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM &&
+ format2 == PIPE_FORMAT_A8R8G8B8_UNORM)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+
+/**
+ * This is used for translating texture border color and the clear
+ * color. For example, the clear color is interpreted according to
+ * the renderbuffer's base format. For example, if clearing a
+ * GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] =
+ * alpha. Similarly for texture border colors.
+ */
+void
+st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
+ GLfloat colorOut[4])
+{
+ switch (baseFormat) {
+ case GL_RED:
+ colorOut[0] = colorIn[0];
+ colorOut[1] = 0.0F;
+ colorOut[2] = 0.0F;
+ colorOut[3] = 1.0F;
+ break;
+ case GL_RG:
+ colorOut[0] = colorIn[0];
+ colorOut[1] = colorIn[1];
+ colorOut[2] = 0.0F;
+ colorOut[3] = 1.0F;
+ break;
+ case GL_RGB:
+ colorOut[0] = colorIn[0];
+ colorOut[1] = colorIn[1];
+ colorOut[2] = colorIn[2];
+ colorOut[3] = 1.0F;
+ break;
+ case GL_ALPHA:
+ colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
+ colorOut[3] = colorIn[3];
+ break;
+ case GL_LUMINANCE:
+ colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
+ colorOut[3] = 1.0;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
+ colorOut[3] = colorIn[3];
+ break;
+ case GL_INTENSITY:
+ colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
+ break;
+ default:
+ COPY_4V(colorOut, colorIn);
+ }
+}
diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index ffcaf402a..d31e60711 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -77,4 +77,10 @@ st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type); extern GLboolean
st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2);
+
+extern void
+st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
+ GLfloat colorOut[4]);
+
+
#endif /* ST_FORMAT_H */
diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c index 5fcd806e0..d04ec696f 100644 --- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c +++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c @@ -336,6 +336,11 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, if (lastLevel == 0)
return;
+ /* The texture isn't in a "complete" state yet so set the expected
+ * lastLevel here, since it won't get done in st_finalize_texture().
+ */
+ stObj->lastLevel = lastLevel;
+
if (pt->last_level < lastLevel) {
/* The current gallium texture doesn't have space for all the
* mipmap levels we need to generate. So allocate a new texture.
@@ -353,11 +358,6 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, oldTex->array_size,
oldTex->bind);
- /* The texture isn't in a "complete" state yet so set the expected
- * lastLevel here, since it won't get done in st_finalize_texture().
- */
- stObj->lastLevel = lastLevel;
-
/* This will copy the old texture's base image into the new texture
* which we just allocated.
*/
@@ -366,8 +366,6 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, /* release the old tex (will likely be freed too) */
pipe_resource_reference(&oldTex, NULL);
pipe_sampler_view_reference(&stObj->sampler_view, NULL);
-
- pt = stObj->pt;
}
else {
/* Make sure that the base texture image data is present in the
@@ -376,6 +374,8 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, st_finalize_texture(ctx, st->pipe, texObj);
}
+ pt = stObj->pt;
+
assert(pt->last_level >= lastLevel);
/* Try to generate the mipmap by rendering/texturing. If that fails,
diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h index 2508016c0..0dd2286dc 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.h +++ b/mesalib/src/mesa/vbo/vbo_exec.h @@ -152,7 +152,6 @@ struct vbo_exec_context void vbo_exec_init( struct gl_context *ctx );
void vbo_exec_destroy( struct gl_context *ctx );
void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state );
-void vbo_exec_FlushVertices_internal( struct gl_context *ctx, GLboolean unmap );
void vbo_exec_BeginVertices( struct gl_context *ctx );
void vbo_exec_FlushVertices( struct gl_context *ctx, GLuint flags );
diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index 0c59c41ba..859db5e2c 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -159,8 +159,7 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) exec->vtx.attrsz[i],
exec->vtx.attrptr[i]);
- if (memcmp(current, tmp, sizeof(tmp)) != 0)
- {
+ if (memcmp(current, tmp, sizeof(tmp)) != 0) {
memcpy(current, tmp, sizeof(tmp));
/* Given that we explicitly state size here, there is no need
@@ -192,14 +191,18 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) }
-static void vbo_exec_copy_from_current( struct vbo_exec_context *exec )
+/**
+ * Copy current vertex attribute values into the current vertex.
+ */
+static void
+vbo_exec_copy_from_current(struct vbo_exec_context *exec)
{
struct gl_context *ctx = exec->ctx;
struct vbo_context *vbo = vbo_context(ctx);
GLint i;
- for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
- const GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
+ for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
+ const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr;
switch (exec->vtx.attrsz[i]) {
case 4: exec->vtx.attrptr[i][3] = current[3];
case 3: exec->vtx.attrptr[i][2] = current[2];
@@ -213,17 +216,21 @@ static void vbo_exec_copy_from_current( struct vbo_exec_context *exec ) /**
* Flush existing data, set new attrib size, replay copied vertices.
+ * This is called when we transition from a small vertex attribute size
+ * to a larger one. Ex: glTexCoord2f -> glTexCoord4f.
+ * We need to go back over the previous 2-component texcoords and insert
+ * zero and one values.
*/
-static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,
- GLuint attr,
- GLuint newsz )
+static void
+vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
+ GLuint attr, GLuint newSize )
{
struct gl_context *ctx = exec->ctx;
struct vbo_context *vbo = vbo_context(ctx);
- GLint lastcount = exec->vtx.vert_count;
+ const GLint lastcount = exec->vtx.vert_count;
GLfloat *old_attrptr[VBO_ATTRIB_MAX];
- GLuint old_vtx_size = exec->vtx.vertex_size;
- GLuint oldsz = exec->vtx.attrsz[attr];
+ const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex */
+ const GLuint oldSize = exec->vtx.attrsz[attr];
GLuint i;
/* Run pipeline on current vertices, copy wrapped vertices
@@ -239,7 +246,7 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, memcpy(old_attrptr, exec->vtx.attrptr, sizeof(old_attrptr));
}
- if (unlikely(oldsz)) {
+ if (unlikely(oldSize)) {
/* Do a COPY_TO_CURRENT to ensure back-copying works for the
* case when the attribute already exists in the vertex and is
* having its size increased.
@@ -251,21 +258,21 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, * begin/end so that they don't bloat the vertices.
*/
if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
- !oldsz && lastcount > 8 && exec->vtx.vertex_size) {
+ !oldSize && lastcount > 8 && exec->vtx.vertex_size) {
vbo_exec_copy_to_current( exec );
reset_attrfv( exec );
}
/* Fix up sizes:
*/
- exec->vtx.attrsz[attr] = newsz;
- exec->vtx.vertex_size += newsz - oldsz;
+ exec->vtx.attrsz[attr] = newSize;
+ exec->vtx.vertex_size += newSize - oldSize;
exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
(exec->vtx.vertex_size * sizeof(GLfloat)));
exec->vtx.vert_count = 0;
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
- if (unlikely(oldsz)) {
+ if (unlikely(oldSize)) {
/* Size changed, recalculate all the attrptr[] values
*/
GLfloat *tmp = exec->vtx.vertex;
@@ -283,11 +290,11 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, * values.
*/
vbo_exec_copy_from_current( exec );
-
- } else {
+ }
+ else {
/* Just have to append the new attribute at the end */
exec->vtx.attrptr[attr] = exec->vtx.vertex +
- exec->vtx.vertex_size - newsz;
+ exec->vtx.vertex_size - newSize;
}
/* Replay stored vertices to translate them
@@ -311,10 +318,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, GLint new_offset = exec->vtx.attrptr[j] - exec->vtx.vertex;
if (j == attr) {
- if (oldsz) {
+ if (oldSize) {
GLfloat tmp[4];
- COPY_CLEAN_4V(tmp, oldsz, data + old_offset);
- COPY_SZ_4V(dest + new_offset, newsz, tmp);
+ COPY_CLEAN_4V(tmp, oldSize, data + old_offset);
+ COPY_SZ_4V(dest + new_offset, newSize, tmp);
} else {
GLfloat *current = (GLfloat *)vbo->currval[j].Ptr;
COPY_SZ_4V(dest + new_offset, sz, current);
@@ -337,29 +344,34 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, }
-static void vbo_exec_fixup_vertex( struct gl_context *ctx,
- GLuint attr, GLuint sz )
+/**
+ * This is when a vertex attribute transitions to a different size.
+ * For example, we saw a bunch of glTexCoord2f() calls and now we got a
+ * glTexCoord4f() call. We promote the array from size=2 to size=4.
+ */
+static void
+vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
- int i;
- if (sz > exec->vtx.attrsz[attr]) {
+ if (newSize > exec->vtx.attrsz[attr]) {
/* New size is larger. Need to flush existing vertices and get
* an enlarged vertex format.
*/
- vbo_exec_wrap_upgrade_vertex( exec, attr, sz );
+ vbo_exec_wrap_upgrade_vertex( exec, attr, newSize );
}
- else if (sz < exec->vtx.active_sz[attr]) {
+ else if (newSize < exec->vtx.active_sz[attr]) {
static const GLfloat id[4] = { 0, 0, 0, 1 };
+ GLuint i;
/* New size is smaller - just need to fill in some
* zeros. Don't need to flush or wrap.
*/
- for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++)
+ for (i = newSize; i <= exec->vtx.attrsz[attr]; i++)
exec->vtx.attrptr[attr][i-1] = id[i-1];
}
- exec->vtx.active_sz[attr] = sz;
+ exec->vtx.active_sz[attr] = newSize;
/* Does setting NeedFlush belong here? Necessitates resetting
* vtxfmt on each flush (otherwise flags won't get reset
@@ -370,37 +382,44 @@ static void vbo_exec_fixup_vertex( struct gl_context *ctx, }
-/*
+/**
+ * This macro is used to implement all the glVertex, glColor, glTexCoord,
+ * glVertexAttrib, etc functions.
*/
-#define ATTR( A, N, V0, V1, V2, V3 ) \
-do { \
- struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \
+#define ATTR( A, N, V0, V1, V2, V3 ) \
+do { \
+ struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \
\
- if (unlikely(!(exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT))) \
- ctx->Driver.BeginVertices( ctx ); \
+ if (unlikely(!(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT))) \
+ ctx->Driver.BeginVertices( ctx ); \
+ \
if (unlikely(exec->vtx.active_sz[A] != N)) \
vbo_exec_fixup_vertex(ctx, A, N); \
\
- { \
- GLfloat *dest = exec->vtx.attrptr[A]; \
- if (N>0) dest[0] = V0; \
- if (N>1) dest[1] = V1; \
- if (N>2) dest[2] = V2; \
- if (N>3) dest[3] = V3; \
- } \
- \
- if ((A) == 0) { \
- GLuint i; \
- \
- for (i = 0; i < exec->vtx.vertex_size; i++) \
- exec->vtx.buffer_ptr[i] = exec->vtx.vertex[i]; \
- \
+ { \
+ GLfloat *dest = exec->vtx.attrptr[A]; \
+ if (N>0) dest[0] = V0; \
+ if (N>1) dest[1] = V1; \
+ if (N>2) dest[2] = V2; \
+ if (N>3) dest[3] = V3; \
+ } \
+ \
+ if ((A) == 0) { \
+ /* This is a glVertex call */ \
+ GLuint i; \
+ \
+ for (i = 0; i < exec->vtx.vertex_size; i++) \
+ exec->vtx.buffer_ptr[i] = exec->vtx.vertex[i]; \
+ \
exec->vtx.buffer_ptr += exec->vtx.vertex_size; \
- exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \
- \
- if (++exec->vtx.vert_count >= exec->vtx.max_vert) \
- vbo_exec_vtx_wrap( exec ); \
- } \
+ \
+ /* Set FLUSH_STORED_VERTICES to indicate that there's now */ \
+ /* something to draw (not just updating a color or texcoord).*/ \
+ ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \
+ \
+ if (++exec->vtx.vert_count >= exec->vtx.max_vert) \
+ vbo_exec_vtx_wrap( exec ); \
+ } \
} while (0)
@@ -514,6 +533,24 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j ) /**
+ * Flush (draw) vertices.
+ * \param unmap - leave VBO unmapped after flushing?
+ */
+static void
+vbo_exec_FlushVertices_internal(struct vbo_exec_context *exec, GLboolean unmap)
+{
+ if (exec->vtx.vert_count || unmap) {
+ vbo_exec_vtx_flush( exec, unmap );
+ }
+
+ if (exec->vtx.vertex_size) {
+ vbo_exec_copy_to_current( exec );
+ reset_attrfv( exec );
+ }
+}
+
+
+/**
* Called via glBegin.
*/
static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
@@ -539,7 +576,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) * begin/end pairs.
*/
if (exec->vtx.vertex_size && !exec->vtx.attrsz[0])
- vbo_exec_FlushVertices_internal( ctx, GL_FALSE );
+ vbo_exec_FlushVertices_internal(exec, GL_FALSE);
i = exec->vtx.prim_count++;
exec->vtx.prim[i].mode = mode;
@@ -894,32 +931,23 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ) _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
}
+
+/**
+ * Called upon first glVertex, glColor, glTexCoord, etc.
+ */
void vbo_exec_BeginVertices( struct gl_context *ctx )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
- if (0) printf("%s\n", __FUNCTION__);
+
vbo_exec_vtx_map( exec );
assert((exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) == 0);
exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
}
-void vbo_exec_FlushVertices_internal( struct gl_context *ctx, GLboolean unmap )
-{
- struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
-
- if (exec->vtx.vert_count || unmap) {
- vbo_exec_vtx_flush( exec, unmap );
- }
-
- if (exec->vtx.vertex_size) {
- vbo_exec_copy_to_current( exec );
- reset_attrfv( exec );
- }
-}
-
/**
+ * Called via ctx->Driver.FlushVertices()
* \param flags bitmask of FLUSH_STORED_VERTICES, FLUSH_UPDATE_CURRENT
*/
void vbo_exec_FlushVertices( struct gl_context *ctx, GLuint flags )
@@ -932,10 +960,8 @@ void vbo_exec_FlushVertices( struct gl_context *ctx, GLuint flags ) assert(exec->flush_call_depth == 1);
#endif
- if (0) printf("%s\n", __FUNCTION__);
-
if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
- if (0) printf("%s - inside begin/end\n", __FUNCTION__);
+ /* We've had glBegin but not glEnd! */
#ifdef DEBUG
exec->flush_call_depth--;
assert(exec->flush_call_depth == 0);
@@ -943,7 +969,8 @@ void vbo_exec_FlushVertices( struct gl_context *ctx, GLuint flags ) return;
}
- vbo_exec_FlushVertices_internal( ctx, GL_TRUE );
+ /* Flush (draw), and make sure VBO is left unmapped when done */
+ vbo_exec_FlushVertices_internal(exec, GL_TRUE);
/* Need to do this to ensure BeginVertices gets called again:
*/
diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c index a2a098857..7cc843779 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_draw.c +++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c @@ -253,6 +253,9 @@ vbo_exec_bind_arrays( struct gl_context *ctx ) }
+/**
+ * Unmap the VBO. This is called before drawing.
+ */
static void
vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
{
@@ -285,6 +288,9 @@ vbo_exec_vtx_unmap( struct vbo_exec_context *exec ) }
+/**
+ * Map the vertex buffer to begin storing glVertex, glColor, etc data.
+ */
void
vbo_exec_vtx_map( struct vbo_exec_context *exec )
{
@@ -301,14 +307,12 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec ) if (!_mesa_is_bufferobj(exec->vtx.bufferobj))
return;
- if (exec->vtx.buffer_map != NULL) {
- assert(0);
- exec->vtx.buffer_map = NULL;
- exec->vtx.buffer_ptr = NULL;
- }
+ assert(!exec->vtx.buffer_map);
+ assert(!exec->vtx.buffer_ptr);
if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024 &&
ctx->Driver.MapBufferRange) {
+ /* The VBO exists and there's room for more */
exec->vtx.buffer_map =
(GLfloat *)ctx->Driver.MapBufferRange(ctx,
target,
@@ -321,6 +325,7 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec ) }
if (!exec->vtx.buffer_map) {
+ /* Need to allocate a new VBO */
exec->vtx.buffer_used = 0;
ctx->Driver.BufferData(ctx, target,
@@ -349,9 +354,10 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec ) /**
* Execute the buffer and save copied verts.
+ * \param keep_unmapped if true, leave the VBO unmapped when we're done.
*/
void
-vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
+vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)
{
if (0)
vbo_exec_debug_verts( exec );
@@ -391,7 +397,7 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ) /* If using a real VBO, get new storage -- unless asked not to.
*/
- if (_mesa_is_bufferobj(exec->vtx.bufferobj) && !unmap) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj) && !keepUnmapped) {
vbo_exec_vtx_map( exec );
}
}
@@ -399,14 +405,13 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ) /* May have to unmap explicitly if we didn't draw:
*/
- if (unmap &&
+ if (keepUnmapped &&
_mesa_is_bufferobj(exec->vtx.bufferobj) &&
exec->vtx.buffer_map) {
vbo_exec_vtx_unmap( exec );
}
-
- if (unmap || exec->vtx.vertex_size == 0)
+ if (keepUnmapped || exec->vtx.vertex_size == 0)
exec->vtx.max_vert = 0;
else
exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
|