aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/state_tracker
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-03-30 06:43:04 +0000
committermarha <marha@users.sourceforge.net>2011-03-30 06:43:04 +0000
commit2039567395da75a3ae318fb82738cdcf2caa05a1 (patch)
tree23caaf9e0f6867d85f5cffc284d008c591ae99cb /mesalib/src/mesa/state_tracker
parent24abc56b37a3ec32a03b7eafccd96607ae13ea89 (diff)
downloadvcxsrv-2039567395da75a3ae318fb82738cdcf2caa05a1.tar.gz
vcxsrv-2039567395da75a3ae318fb82738cdcf2caa05a1.tar.bz2
vcxsrv-2039567395da75a3ae318fb82738cdcf2caa05a1.zip
mesa git update 30 Mar 2011
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_blend.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_depth.c320
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_rasterizer.c554
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c1202
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawpixels.c53
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_readpixels.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c1093
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.c2596
8 files changed, 3073 insertions, 2754 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom_blend.c b/mesalib/src/mesa/state_tracker/st_atom_blend.c
index fb1c7a4ef..d1844e106 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_blend.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_blend.c
@@ -286,7 +286,7 @@ update_blend( struct st_context *st )
{
struct pipe_blend_color bc;
- COPY_4FV(bc.color, st->ctx->Color.BlendColor);
+ COPY_4FV(bc.color, st->ctx->Color.BlendColorUnclamped);
cso_set_blend_color(st->cso_context, &bc);
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_depth.c b/mesalib/src/mesa/state_tracker/st_atom_depth.c
index e8e8db41d..6c51b1ac1 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_depth.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_depth.c
@@ -1,160 +1,160 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Brian Paul
- * Zack Rusin
- */
-
-
-#include <assert.h>
-
-#include "st_context.h"
-#include "st_atom.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "cso_cache/cso_context.h"
-
-
-/**
- * Convert an OpenGL compare mode to a pipe tokens.
- */
-GLuint
-st_compare_func_to_pipe(GLenum func)
-{
- /* Same values, just biased */
- assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
- assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
- assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
- assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
- assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
- assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
- assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
- assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
- assert(func >= GL_NEVER);
- assert(func <= GL_ALWAYS);
- return func - GL_NEVER;
-}
-
-
-/**
- * Convert GLenum stencil op tokens to pipe tokens.
- */
-static GLuint
-gl_stencil_op_to_pipe(GLenum func)
-{
- switch (func) {
- case GL_KEEP:
- return PIPE_STENCIL_OP_KEEP;
- case GL_ZERO:
- return PIPE_STENCIL_OP_ZERO;
- case GL_REPLACE:
- return PIPE_STENCIL_OP_REPLACE;
- case GL_INCR:
- return PIPE_STENCIL_OP_INCR;
- case GL_DECR:
- return PIPE_STENCIL_OP_DECR;
- case GL_INCR_WRAP:
- return PIPE_STENCIL_OP_INCR_WRAP;
- case GL_DECR_WRAP:
- return PIPE_STENCIL_OP_DECR_WRAP;
- case GL_INVERT:
- return PIPE_STENCIL_OP_INVERT;
- default:
- assert("invalid GL token in gl_stencil_op_to_pipe()" == NULL);
- return 0;
- }
-}
-
-static void
-update_depth_stencil_alpha(struct st_context *st)
-{
- struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil;
- struct pipe_stencil_ref sr;
- struct gl_context *ctx = st->ctx;
-
- memset(dsa, 0, sizeof(*dsa));
- memset(&sr, 0, sizeof(sr));
-
- if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) {
- dsa->depth.enabled = 1;
- dsa->depth.writemask = ctx->Depth.Mask;
- dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func);
- }
-
- if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
- dsa->stencil[0].enabled = 1;
- dsa->stencil[0].func = st_compare_func_to_pipe(ctx->Stencil.Function[0]);
- dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[0]);
- dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[0]);
- dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[0]);
- dsa->stencil[0].valuemask = ctx->Stencil.ValueMask[0] & 0xff;
- dsa->stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
- sr.ref_value[0] = ctx->Stencil.Ref[0] & 0xff;
-
- if (ctx->Stencil._TestTwoSide) {
- const GLuint back = ctx->Stencil._BackFace;
- dsa->stencil[1].enabled = 1;
- dsa->stencil[1].func = st_compare_func_to_pipe(ctx->Stencil.Function[back]);
- dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[back]);
- dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[back]);
- dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[back]);
- dsa->stencil[1].valuemask = ctx->Stencil.ValueMask[back] & 0xff;
- dsa->stencil[1].writemask = ctx->Stencil.WriteMask[back] & 0xff;
- sr.ref_value[1] = ctx->Stencil.Ref[back] & 0xff;
- }
- else {
- /* This should be unnecessary. Drivers must not expect this to
- * contain valid data, except the enabled bit
- */
- dsa->stencil[1] = dsa->stencil[0];
- dsa->stencil[1].enabled = 0;
- sr.ref_value[1] = sr.ref_value[0];
- }
- }
-
- if (ctx->Color.AlphaEnabled) {
- dsa->alpha.enabled = 1;
- dsa->alpha.func = st_compare_func_to_pipe(ctx->Color.AlphaFunc);
- dsa->alpha.ref_value = ctx->Color.AlphaRef;
- }
-
- cso_set_depth_stencil_alpha(st->cso_context, dsa);
- cso_set_stencil_ref(st->cso_context, &sr);
-}
-
-
-const struct st_tracked_state st_update_depth_stencil_alpha = {
- "st_update_depth_stencil", /* name */
- { /* dirty */
- (_NEW_DEPTH|_NEW_STENCIL|_NEW_COLOR), /* mesa */
- 0, /* st */
- },
- update_depth_stencil_alpha /* update */
-};
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Brian Paul
+ * Zack Rusin
+ */
+
+
+#include <assert.h>
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "cso_cache/cso_context.h"
+
+
+/**
+ * Convert an OpenGL compare mode to a pipe tokens.
+ */
+GLuint
+st_compare_func_to_pipe(GLenum func)
+{
+ /* Same values, just biased */
+ assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
+ assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
+ assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
+ assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
+ assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
+ assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
+ assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
+ assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
+ assert(func >= GL_NEVER);
+ assert(func <= GL_ALWAYS);
+ return func - GL_NEVER;
+}
+
+
+/**
+ * Convert GLenum stencil op tokens to pipe tokens.
+ */
+static GLuint
+gl_stencil_op_to_pipe(GLenum func)
+{
+ switch (func) {
+ case GL_KEEP:
+ return PIPE_STENCIL_OP_KEEP;
+ case GL_ZERO:
+ return PIPE_STENCIL_OP_ZERO;
+ case GL_REPLACE:
+ return PIPE_STENCIL_OP_REPLACE;
+ case GL_INCR:
+ return PIPE_STENCIL_OP_INCR;
+ case GL_DECR:
+ return PIPE_STENCIL_OP_DECR;
+ case GL_INCR_WRAP:
+ return PIPE_STENCIL_OP_INCR_WRAP;
+ case GL_DECR_WRAP:
+ return PIPE_STENCIL_OP_DECR_WRAP;
+ case GL_INVERT:
+ return PIPE_STENCIL_OP_INVERT;
+ default:
+ assert("invalid GL token in gl_stencil_op_to_pipe()" == NULL);
+ return 0;
+ }
+}
+
+static void
+update_depth_stencil_alpha(struct st_context *st)
+{
+ struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil;
+ struct pipe_stencil_ref sr;
+ struct gl_context *ctx = st->ctx;
+
+ memset(dsa, 0, sizeof(*dsa));
+ memset(&sr, 0, sizeof(sr));
+
+ if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) {
+ dsa->depth.enabled = 1;
+ dsa->depth.writemask = ctx->Depth.Mask;
+ dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func);
+ }
+
+ if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
+ dsa->stencil[0].enabled = 1;
+ dsa->stencil[0].func = st_compare_func_to_pipe(ctx->Stencil.Function[0]);
+ dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[0]);
+ dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[0]);
+ dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[0]);
+ dsa->stencil[0].valuemask = ctx->Stencil.ValueMask[0] & 0xff;
+ dsa->stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
+ sr.ref_value[0] = ctx->Stencil.Ref[0] & 0xff;
+
+ if (ctx->Stencil._TestTwoSide) {
+ const GLuint back = ctx->Stencil._BackFace;
+ dsa->stencil[1].enabled = 1;
+ dsa->stencil[1].func = st_compare_func_to_pipe(ctx->Stencil.Function[back]);
+ dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[back]);
+ dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[back]);
+ dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[back]);
+ dsa->stencil[1].valuemask = ctx->Stencil.ValueMask[back] & 0xff;
+ dsa->stencil[1].writemask = ctx->Stencil.WriteMask[back] & 0xff;
+ sr.ref_value[1] = ctx->Stencil.Ref[back] & 0xff;
+ }
+ else {
+ /* This should be unnecessary. Drivers must not expect this to
+ * contain valid data, except the enabled bit
+ */
+ dsa->stencil[1] = dsa->stencil[0];
+ dsa->stencil[1].enabled = 0;
+ sr.ref_value[1] = sr.ref_value[0];
+ }
+ }
+
+ if (ctx->Color.AlphaEnabled) {
+ dsa->alpha.enabled = 1;
+ dsa->alpha.func = st_compare_func_to_pipe(ctx->Color.AlphaFunc);
+ dsa->alpha.ref_value = ctx->Color.AlphaRefUnclamped;
+ }
+
+ cso_set_depth_stencil_alpha(st->cso_context, dsa);
+ cso_set_stencil_ref(st->cso_context, &sr);
+}
+
+
+const struct st_tracked_state st_update_depth_stencil_alpha = {
+ "st_update_depth_stencil", /* name */
+ { /* dirty */
+ (_NEW_DEPTH|_NEW_STENCIL|_NEW_COLOR), /* mesa */
+ 0, /* st */
+ },
+ update_depth_stencil_alpha /* update */
+};
diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
index 4fad1f297..250cbb226 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -1,274 +1,280 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "main/macros.h"
-#include "st_context.h"
-#include "st_atom.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "cso_cache/cso_context.h"
-
-
-static GLuint translate_fill( GLenum mode )
-{
- switch (mode) {
- case GL_POINT:
- return PIPE_POLYGON_MODE_POINT;
- case GL_LINE:
- return PIPE_POLYGON_MODE_LINE;
- case GL_FILL:
- return PIPE_POLYGON_MODE_FILL;
- default:
- assert(0);
- return 0;
- }
-}
-
-
-
-static void update_raster_state( struct st_context *st )
-{
- struct gl_context *ctx = st->ctx;
- struct pipe_rasterizer_state *raster = &st->state.rasterizer;
- const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
- const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
- uint i;
-
- memset(raster, 0, sizeof(*raster));
-
- /* _NEW_POLYGON, _NEW_BUFFERS
- */
- {
- raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);
-
- /*
- * Gallium's surfaces are Y=0=TOP orientation. OpenGL is the
- * opposite. Window system surfaces are Y=0=TOP. Mesa's FBOs
- * must match OpenGL conventions so FBOs use Y=0=BOTTOM. In that
- * case, we must invert Y and flip the notion of front vs. back.
- */
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
- /* Drawing to an FBO. The viewport will be inverted. */
- raster->front_ccw ^= 1;
- }
- }
-
- /* _NEW_LIGHT
- */
- if (ctx->Light.ShadeModel == GL_FLAT)
- raster->flatshade = 1;
-
- if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT)
- raster->flatshade_first = 1;
-
- /* _NEW_LIGHT | _NEW_PROGRAM
- *
- * Back-face colors can come from traditional lighting (when
- * GL_LIGHT_MODEL_TWO_SIDE is set) or from vertex programs/shaders (when
- * GL_VERTEX_PROGRAM_TWO_SIDE is set). Note the logic here.
- */
- if (ctx->VertexProgram._Current) {
- if (ctx->VertexProgram._Enabled ||
- (ctx->Shader.CurrentVertexProgram &&
- ctx->Shader.CurrentVertexProgram->LinkStatus)) {
- /* user-defined vertex program or shader */
- raster->light_twoside = ctx->VertexProgram.TwoSideEnabled;
- }
- else {
- /* TNL-generated program */
- raster->light_twoside = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
- }
- }
- else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
- raster->light_twoside = 1;
- }
-
- /* _NEW_POLYGON
- */
- if (ctx->Polygon.CullFlag) {
- switch (ctx->Polygon.CullFaceMode) {
- case GL_FRONT:
- raster->cull_face = PIPE_FACE_FRONT;
- break;
- case GL_BACK:
- raster->cull_face = PIPE_FACE_BACK;
- break;
- case GL_FRONT_AND_BACK:
- raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
- break;
- }
- }
- else {
- raster->cull_face = PIPE_FACE_NONE;
- }
-
- /* _NEW_POLYGON
- */
- {
- raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
- raster->fill_back = translate_fill( ctx->Polygon.BackMode );
-
- /* Simplify when culling is active:
- */
- if (raster->cull_face & PIPE_FACE_FRONT) {
- raster->fill_front = raster->fill_back;
- }
-
- if (raster->cull_face & PIPE_FACE_BACK) {
- raster->fill_back = raster->fill_front;
- }
- }
-
- /* _NEW_POLYGON
- */
- if (ctx->Polygon.OffsetUnits != 0.0 ||
- ctx->Polygon.OffsetFactor != 0.0) {
- raster->offset_point = ctx->Polygon.OffsetPoint;
- raster->offset_line = ctx->Polygon.OffsetLine;
- raster->offset_tri = ctx->Polygon.OffsetFill;
- }
-
- if (ctx->Polygon.OffsetPoint ||
- ctx->Polygon.OffsetLine ||
- ctx->Polygon.OffsetFill) {
- raster->offset_units = ctx->Polygon.OffsetUnits;
- raster->offset_scale = ctx->Polygon.OffsetFactor;
- }
-
- if (ctx->Polygon.SmoothFlag)
- raster->poly_smooth = 1;
-
- if (ctx->Polygon.StippleFlag)
- raster->poly_stipple_enable = 1;
-
- /* _NEW_POINT
- */
- raster->point_size = ctx->Point.Size;
-
- if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
- raster->point_smooth = 1;
-
- /* _NEW_POINT | _NEW_PROGRAM
- */
- if (ctx->Point.PointSprite) {
- /* origin */
- if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
- (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
- raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
- else
- raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
-
- /* Coord replacement flags. If bit 'k' is set that means
- * that we need to replace GENERIC[k] attrib with an automatically
- * computed texture coord.
- */
- for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
- if (ctx->Point.CoordReplace[i]) {
- raster->sprite_coord_enable |= 1 << i;
- }
- }
- if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) {
- raster->sprite_coord_enable |=
- 1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0);
- }
-
- raster->point_quad_rasterization = 1;
- }
-
- /* ST_NEW_VERTEX_PROGRAM
- */
- if (vertProg) {
- if (vertProg->Base.Id == 0) {
- if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_PSIZ)) {
- /* generated program which emits point size */
- raster->point_size_per_vertex = TRUE;
- }
- }
- else if (ctx->VertexProgram.PointSizeEnabled) {
- /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
- raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
- }
- }
- if (!raster->point_size_per_vertex) {
- /* clamp size now */
- raster->point_size = CLAMP(ctx->Point.Size,
- ctx->Point.MinSize,
- ctx->Point.MaxSize);
- }
-
- /* _NEW_LINE
- */
- raster->line_smooth = ctx->Line.SmoothFlag;
- if (ctx->Line.SmoothFlag) {
- raster->line_width = CLAMP(ctx->Line.Width,
- ctx->Const.MinLineWidthAA,
- ctx->Const.MaxLineWidthAA);
- }
- else {
- raster->line_width = CLAMP(ctx->Line.Width,
- ctx->Const.MinLineWidth,
- ctx->Const.MaxLineWidth);
- }
-
- raster->line_stipple_enable = ctx->Line.StippleFlag;
- raster->line_stipple_pattern = ctx->Line.StipplePattern;
- /* GL stipple factor is in [1,256], remap to [0, 255] here */
- raster->line_stipple_factor = ctx->Line.StippleFactor - 1;
-
- /* _NEW_MULTISAMPLE */
- if (ctx->Multisample._Enabled || st->force_msaa)
- raster->multisample = 1;
-
- /* _NEW_SCISSOR */
- if (ctx->Scissor.Enabled)
- raster->scissor = 1;
-
- raster->gl_rasterization_rules = 1;
-
- cso_set_rasterizer(st->cso_context, raster);
-}
-
-const struct st_tracked_state st_update_rasterizer = {
- "st_update_rasterizer", /* name */
- {
- (_NEW_BUFFERS |
- _NEW_LIGHT |
- _NEW_LINE |
- _NEW_MULTISAMPLE |
- _NEW_POINT |
- _NEW_POLYGON |
- _NEW_PROGRAM |
- _NEW_SCISSOR), /* mesa state dependencies*/
- ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */
- },
- update_raster_state /* update function */
-};
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "main/macros.h"
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "cso_cache/cso_context.h"
+
+
+static GLuint translate_fill( GLenum mode )
+{
+ switch (mode) {
+ case GL_POINT:
+ return PIPE_POLYGON_MODE_POINT;
+ case GL_LINE:
+ return PIPE_POLYGON_MODE_LINE;
+ case GL_FILL:
+ return PIPE_POLYGON_MODE_FILL;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
+
+static void update_raster_state( struct st_context *st )
+{
+ struct gl_context *ctx = st->ctx;
+ struct pipe_rasterizer_state *raster = &st->state.rasterizer;
+ const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
+ const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
+ uint i;
+
+ memset(raster, 0, sizeof(*raster));
+
+ /* _NEW_POLYGON, _NEW_BUFFERS
+ */
+ {
+ raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);
+
+ /*
+ * Gallium's surfaces are Y=0=TOP orientation. OpenGL is the
+ * opposite. Window system surfaces are Y=0=TOP. Mesa's FBOs
+ * must match OpenGL conventions so FBOs use Y=0=BOTTOM. In that
+ * case, we must invert Y and flip the notion of front vs. back.
+ */
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
+ /* Drawing to an FBO. The viewport will be inverted. */
+ raster->front_ccw ^= 1;
+ }
+ }
+
+ /* _NEW_LIGHT
+ */
+ if (ctx->Light.ShadeModel == GL_FLAT)
+ raster->flatshade = 1;
+
+ if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT)
+ raster->flatshade_first = 1;
+
+ /* _NEW_LIGHT | _NEW_PROGRAM
+ *
+ * Back-face colors can come from traditional lighting (when
+ * GL_LIGHT_MODEL_TWO_SIDE is set) or from vertex programs/shaders (when
+ * GL_VERTEX_PROGRAM_TWO_SIDE is set). Note the logic here.
+ */
+ if (ctx->VertexProgram._Current) {
+ if (ctx->VertexProgram._Enabled ||
+ (ctx->Shader.CurrentVertexProgram &&
+ ctx->Shader.CurrentVertexProgram->LinkStatus)) {
+ /* user-defined vertex program or shader */
+ raster->light_twoside = ctx->VertexProgram.TwoSideEnabled;
+ }
+ else {
+ /* TNL-generated program */
+ raster->light_twoside = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
+ }
+ }
+ else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
+ raster->light_twoside = 1;
+ }
+
+ raster->clamp_vertex_color = ctx->Light._ClampVertexColor;
+
+ /* _NEW_POLYGON
+ */
+ if (ctx->Polygon.CullFlag) {
+ switch (ctx->Polygon.CullFaceMode) {
+ case GL_FRONT:
+ raster->cull_face = PIPE_FACE_FRONT;
+ break;
+ case GL_BACK:
+ raster->cull_face = PIPE_FACE_BACK;
+ break;
+ case GL_FRONT_AND_BACK:
+ raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
+ break;
+ }
+ }
+ else {
+ raster->cull_face = PIPE_FACE_NONE;
+ }
+
+ /* _NEW_POLYGON
+ */
+ {
+ raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
+ raster->fill_back = translate_fill( ctx->Polygon.BackMode );
+
+ /* Simplify when culling is active:
+ */
+ if (raster->cull_face & PIPE_FACE_FRONT) {
+ raster->fill_front = raster->fill_back;
+ }
+
+ if (raster->cull_face & PIPE_FACE_BACK) {
+ raster->fill_back = raster->fill_front;
+ }
+ }
+
+ /* _NEW_POLYGON
+ */
+ if (ctx->Polygon.OffsetUnits != 0.0 ||
+ ctx->Polygon.OffsetFactor != 0.0) {
+ raster->offset_point = ctx->Polygon.OffsetPoint;
+ raster->offset_line = ctx->Polygon.OffsetLine;
+ raster->offset_tri = ctx->Polygon.OffsetFill;
+ }
+
+ if (ctx->Polygon.OffsetPoint ||
+ ctx->Polygon.OffsetLine ||
+ ctx->Polygon.OffsetFill) {
+ raster->offset_units = ctx->Polygon.OffsetUnits;
+ raster->offset_scale = ctx->Polygon.OffsetFactor;
+ }
+
+ if (ctx->Polygon.SmoothFlag)
+ raster->poly_smooth = 1;
+
+ if (ctx->Polygon.StippleFlag)
+ raster->poly_stipple_enable = 1;
+
+ /* _NEW_POINT
+ */
+ raster->point_size = ctx->Point.Size;
+
+ if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
+ raster->point_smooth = 1;
+
+ /* _NEW_POINT | _NEW_PROGRAM
+ */
+ if (ctx->Point.PointSprite) {
+ /* origin */
+ if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
+ (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
+ raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
+ else
+ raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
+
+ /* Coord replacement flags. If bit 'k' is set that means
+ * that we need to replace GENERIC[k] attrib with an automatically
+ * computed texture coord.
+ */
+ for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
+ if (ctx->Point.CoordReplace[i]) {
+ raster->sprite_coord_enable |= 1 << i;
+ }
+ }
+ if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) {
+ raster->sprite_coord_enable |=
+ 1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0);
+ }
+
+ raster->point_quad_rasterization = 1;
+ }
+
+ /* ST_NEW_VERTEX_PROGRAM
+ */
+ if (vertProg) {
+ if (vertProg->Base.Id == 0) {
+ if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_PSIZ)) {
+ /* generated program which emits point size */
+ raster->point_size_per_vertex = TRUE;
+ }
+ }
+ else if (ctx->VertexProgram.PointSizeEnabled) {
+ /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
+ raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
+ }
+ }
+ if (!raster->point_size_per_vertex) {
+ /* clamp size now */
+ raster->point_size = CLAMP(ctx->Point.Size,
+ ctx->Point.MinSize,
+ ctx->Point.MaxSize);
+ }
+
+ /* _NEW_LINE
+ */
+ raster->line_smooth = ctx->Line.SmoothFlag;
+ if (ctx->Line.SmoothFlag) {
+ raster->line_width = CLAMP(ctx->Line.Width,
+ ctx->Const.MinLineWidthAA,
+ ctx->Const.MaxLineWidthAA);
+ }
+ else {
+ raster->line_width = CLAMP(ctx->Line.Width,
+ ctx->Const.MinLineWidth,
+ ctx->Const.MaxLineWidth);
+ }
+
+ raster->line_stipple_enable = ctx->Line.StippleFlag;
+ raster->line_stipple_pattern = ctx->Line.StipplePattern;
+ /* GL stipple factor is in [1,256], remap to [0, 255] here */
+ raster->line_stipple_factor = ctx->Line.StippleFactor - 1;
+
+ /* _NEW_MULTISAMPLE */
+ if (ctx->Multisample._Enabled || st->force_msaa)
+ raster->multisample = 1;
+
+ /* _NEW_SCISSOR */
+ if (ctx->Scissor.Enabled)
+ raster->scissor = 1;
+
+ /* _NEW_FRAG_CLAMP */
+ raster->clamp_fragment_color = ctx->Color._ClampFragmentColor;
+
+ raster->gl_rasterization_rules = 1;
+
+ cso_set_rasterizer(st->cso_context, raster);
+}
+
+const struct st_tracked_state st_update_rasterizer = {
+ "st_update_rasterizer", /* name */
+ {
+ (_NEW_BUFFERS |
+ _NEW_LIGHT |
+ _NEW_LINE |
+ _NEW_MULTISAMPLE |
+ _NEW_POINT |
+ _NEW_POLYGON |
+ _NEW_PROGRAM |
+ _NEW_SCISSOR |
+ _NEW_FRAG_CLAMP), /* mesa state dependencies*/
+ ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */
+ },
+ update_raster_state /* update function */
+};
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 0130c7a5a..181fedd2b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -1,601 +1,601 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * Copyright 2009 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.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Brian Paul
- * Michel Dänzer
- */
-
-#include "main/glheader.h"
-#include "main/formats.h"
-#include "main/macros.h"
-#include "program/prog_instruction.h"
-#include "st_context.h"
-#include "st_atom.h"
-#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"
-#include "pipe/p_shader_tokens.h"
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_format.h"
-#include "util/u_inlines.h"
-#include "util/u_simple_shaders.h"
-#include "util/u_draw_quad.h"
-
-#include "cso_cache/cso_context.h"
-
-
-/**
- * Do per-context initialization for glClear.
- */
-void
-st_init_clear(struct st_context *st)
-{
- struct pipe_screen *pscreen = st->pipe->screen;
-
- memset(&st->clear, 0, sizeof(st->clear));
-
- st->clear.raster.gl_rasterization_rules = 1;
- st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
-}
-
-
-/**
- * Free per-context state for glClear.
- */
-void
-st_destroy_clear(struct st_context *st)
-{
- if (st->clear.fs) {
- cso_delete_fragment_shader(st->cso_context, st->clear.fs);
- st->clear.fs = NULL;
- }
- if (st->clear.vs) {
- cso_delete_vertex_shader(st->cso_context, st->clear.vs);
- st->clear.vs = NULL;
- }
- if (st->clear.vbuf) {
- pipe_resource_reference(&st->clear.vbuf, NULL);
- st->clear.vbuf = NULL;
- }
-}
-
-
-/**
- * Helper function to set the fragment shaders.
- */
-static INLINE void
-set_fragment_shader(struct st_context *st)
-{
- if (!st->clear.fs)
- st->clear.fs = util_make_fragment_passthrough_shader(st->pipe);
-
- cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
-}
-
-
-/**
- * Helper function to set the vertex shader.
- */
-static INLINE void
-set_vertex_shader(struct st_context *st)
-{
- /* vertex shader - still required to provide the linkage between
- * fragment shader input semantics and vertex_element/buffers.
- */
- if (!st->clear.vs)
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_COLOR };
- const uint semantic_indexes[] = { 0, 0 };
- st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
- semantic_names,
- semantic_indexes);
- }
-
- cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
-}
-
-
-/**
- * Draw a screen-aligned quadrilateral.
- * Coords are clip coords with y=0=bottom.
- */
-static void
-draw_quad(struct st_context *st,
- float x0, float y0, float x1, float y1, GLfloat z,
- const GLfloat color[4])
-{
- struct pipe_context *pipe = st->pipe;
-
- /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
- * no_flush) updates to buffers where we know there is no conflict
- * with previous data. Currently using max_slots > 1 will cause
- * synchronous rendering if the driver flushes its command buffers
- * between one bitmap and the next. Our flush hook below isn't
- * sufficient to catch this as the driver doesn't tell us when it
- * flushes its own command buffers. Until this gets fixed, pay the
- * price of allocating a new buffer for each bitmap cache-flush to
- * avoid synchronous rendering.
- */
- const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */
- GLuint i;
-
- if (st->clear.vbuf_slot >= max_slots) {
- pipe_resource_reference(&st->clear.vbuf, NULL);
- st->clear.vbuf_slot = 0;
- }
-
- if (!st->clear.vbuf) {
- st->clear.vbuf = pipe_buffer_create(pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- PIPE_USAGE_STREAM,
- max_slots * sizeof(st->clear.vertices));
- }
-
- /* positions */
- st->clear.vertices[0][0][0] = x0;
- st->clear.vertices[0][0][1] = y0;
-
- st->clear.vertices[1][0][0] = x1;
- st->clear.vertices[1][0][1] = y0;
-
- st->clear.vertices[2][0][0] = x1;
- st->clear.vertices[2][0][1] = y1;
-
- st->clear.vertices[3][0][0] = x0;
- st->clear.vertices[3][0][1] = y1;
-
- /* same for all verts: */
- for (i = 0; i < 4; i++) {
- st->clear.vertices[i][0][2] = z;
- st->clear.vertices[i][0][3] = 1.0;
- st->clear.vertices[i][1][0] = color[0];
- st->clear.vertices[i][1][1] = color[1];
- st->clear.vertices[i][1][2] = color[2];
- st->clear.vertices[i][1][3] = color[3];
- }
-
- /* put vertex data into vbuf */
- pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf,
- st->clear.vbuf_slot
- * sizeof(st->clear.vertices),
- sizeof(st->clear.vertices),
- st->clear.vertices);
-
- /* draw */
- util_draw_vertex_buffer(pipe,
- st->cso_context,
- st->clear.vbuf,
- st->clear.vbuf_slot * sizeof(st->clear.vertices),
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- /* Increment slot */
- st->clear.vbuf_slot++;
-}
-
-
-
-/**
- * Do glClear by drawing a quadrilateral.
- * The vertices of the quad will be computed from the
- * ctx->DrawBuffer->_X/Ymin/max fields.
- */
-static void
-clear_with_quad(struct gl_context *ctx,
- GLboolean color, GLboolean depth, GLboolean stencil)
-{
- struct st_context *st = st_context(ctx);
- const struct gl_framebuffer *fb = ctx->DrawBuffer;
- const GLfloat fb_width = (GLfloat) fb->Width;
- const GLfloat fb_height = (GLfloat) fb->Height;
- const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
- 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__,
- color ? "color, " : "",
- depth ? "depth, " : "",
- stencil ? "stencil" : "",
- x0, y0,
- x1, y1);
- */
-
- cso_save_blend(st->cso_context);
- cso_save_stencil_ref(st->cso_context);
- cso_save_depth_stencil_alpha(st->cso_context);
- cso_save_rasterizer(st->cso_context);
- cso_save_viewport(st->cso_context);
- cso_save_clip(st->cso_context);
- cso_save_fragment_shader(st->cso_context);
- cso_save_vertex_shader(st->cso_context);
- cso_save_vertex_elements(st->cso_context);
- cso_save_vertex_buffers(st->cso_context);
-
- /* blend state: RGBA masking */
- {
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(blend));
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- if (color) {
- if (ctx->Color.ColorMask[0][0])
- blend.rt[0].colormask |= PIPE_MASK_R;
- if (ctx->Color.ColorMask[0][1])
- blend.rt[0].colormask |= PIPE_MASK_G;
- if (ctx->Color.ColorMask[0][2])
- blend.rt[0].colormask |= PIPE_MASK_B;
- if (ctx->Color.ColorMask[0][3])
- blend.rt[0].colormask |= PIPE_MASK_A;
- if (st->ctx->Color.DitherFlag)
- blend.dither = 1;
- }
- cso_set_blend(st->cso_context, &blend);
- }
-
- /* depth_stencil state: always pass/set to ref value */
- {
- struct pipe_depth_stencil_alpha_state depth_stencil;
- memset(&depth_stencil, 0, sizeof(depth_stencil));
- if (depth) {
- depth_stencil.depth.enabled = 1;
- depth_stencil.depth.writemask = 1;
- depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
- }
-
- if (stencil) {
- struct pipe_stencil_ref stencil_ref;
- memset(&stencil_ref, 0, sizeof(stencil_ref));
- depth_stencil.stencil[0].enabled = 1;
- depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
- depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
- depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
- depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
- depth_stencil.stencil[0].valuemask = 0xff;
- depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
- stencil_ref.ref_value[0] = ctx->Stencil.Clear;
- cso_set_stencil_ref(st->cso_context, &stencil_ref);
- }
-
- cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
- }
-
- cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
-
- cso_set_rasterizer(st->cso_context, &st->clear.raster);
-
- /* viewport state: viewport matching window dims */
- {
- const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
- struct pipe_viewport_state vp;
- vp.scale[0] = 0.5f * fb_width;
- vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
- vp.scale[2] = 1.0f;
- vp.scale[3] = 1.0f;
- vp.translate[0] = 0.5f * fb_width;
- vp.translate[1] = 0.5f * fb_height;
- vp.translate[2] = 0.0f;
- vp.translate[3] = 0.0f;
- cso_set_viewport(st->cso_context, &vp);
- }
-
- cso_set_clip(st->cso_context, &st->clear.clip);
- set_fragment_shader(st);
- set_vertex_shader(st);
-
- 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);
- cso_restore_stencil_ref(st->cso_context);
- cso_restore_depth_stencil_alpha(st->cso_context);
- cso_restore_rasterizer(st->cso_context);
- cso_restore_viewport(st->cso_context);
- cso_restore_clip(st->cso_context);
- cso_restore_fragment_shader(st->cso_context);
- cso_restore_vertex_shader(st->cso_context);
- cso_restore_vertex_elements(st->cso_context);
- cso_restore_vertex_buffers(st->cso_context);
-}
-
-
-/**
- * Determine if we need to clear the depth buffer by drawing a quad.
- */
-static INLINE GLboolean
-check_clear_color_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
-{
- if (ctx->Scissor.Enabled &&
- (ctx->Scissor.X != 0 ||
- ctx->Scissor.Y != 0 ||
- ctx->Scissor.Width < rb->Width ||
- ctx->Scissor.Height < rb->Height))
- return GL_TRUE;
-
- if (!ctx->Color.ColorMask[0][0] ||
- !ctx->Color.ColorMask[0][1] ||
- !ctx->Color.ColorMask[0][2] ||
- !ctx->Color.ColorMask[0][3])
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-/**
- * Determine if we need to clear the combiend depth/stencil buffer by
- * drawing a quad.
- */
-static INLINE GLboolean
-check_clear_depth_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
-{
- const GLuint stencilMax = 0xff;
- GLboolean maskStencil
- = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
-
- assert(rb->Format == MESA_FORMAT_S8 ||
- rb->Format == MESA_FORMAT_Z24_S8 ||
- rb->Format == MESA_FORMAT_S8_Z24);
-
- if (ctx->Scissor.Enabled &&
- (ctx->Scissor.X != 0 ||
- ctx->Scissor.Y != 0 ||
- ctx->Scissor.Width < rb->Width ||
- ctx->Scissor.Height < rb->Height))
- return GL_TRUE;
-
- if (maskStencil)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-/**
- * Determine if we need to clear the depth buffer by drawing a quad.
- */
-static INLINE GLboolean
-check_clear_depth_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
- boolean ds_separate)
-{
- const struct st_renderbuffer *strb = st_renderbuffer(rb);
- const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
-
- if (ctx->Scissor.Enabled &&
- (ctx->Scissor.X != 0 ||
- ctx->Scissor.Y != 0 ||
- ctx->Scissor.Width < rb->Width ||
- ctx->Scissor.Height < rb->Height))
- return GL_TRUE;
-
- if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-/**
- * Determine if we need to clear the stencil buffer by drawing a quad.
- */
-static INLINE GLboolean
-check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
- boolean ds_separate)
-{
- const struct st_renderbuffer *strb = st_renderbuffer(rb);
- const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
- const GLuint stencilMax = 0xff;
- const GLboolean maskStencil
- = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
-
- assert(rb->Format == MESA_FORMAT_S8 ||
- rb->Format == MESA_FORMAT_Z24_S8 ||
- rb->Format == MESA_FORMAT_S8_Z24);
-
- if (maskStencil)
- return GL_TRUE;
-
- if (ctx->Scissor.Enabled &&
- (ctx->Scissor.X != 0 ||
- ctx->Scissor.Y != 0 ||
- ctx->Scissor.Width < rb->Width ||
- ctx->Scissor.Height < rb->Height))
- return GL_TRUE;
-
- /* This is correct, but it is necessary to look at the depth clear
- * value held in the surface when it comes time to issue the clear,
- * rather than taking depth and stencil clear values from the
- * current state.
- */
- if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-
-/**
- * Called when we need to flush.
- */
-void
-st_flush_clear(struct st_context *st)
-{
- /* Release vertex buffer to avoid synchronous rendering if we were
- * to map it in the next frame.
- */
- pipe_resource_reference(&st->clear.vbuf, NULL);
- st->clear.vbuf_slot = 0;
-}
-
-
-
-/**
- * Called via ctx->Driver.Clear()
- */
-static void
-st_Clear(struct gl_context *ctx, GLbitfield mask)
-{
- static const GLbitfield BUFFER_BITS_DS
- = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
- struct st_context *st = st_context(ctx);
- struct gl_renderbuffer *depthRb
- = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
- struct gl_renderbuffer *stencilRb
- = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
- GLbitfield quad_buffers = 0x0;
- GLbitfield clear_buffers = 0x0;
- GLuint i;
-
- /* This makes sure the pipe has the latest scissor, etc values */
- st_validate_state( st );
-
- if (mask & BUFFER_BITS_COLOR) {
- for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
-
- if (mask & (1 << b)) {
- struct gl_renderbuffer *rb
- = ctx->DrawBuffer->Attachment[b].Renderbuffer;
- struct st_renderbuffer *strb = st_renderbuffer(rb);
-
- if (!strb || !strb->surface)
- continue;
-
- if (check_clear_color_with_quad( ctx, rb ))
- quad_buffers |= PIPE_CLEAR_COLOR;
- else
- clear_buffers |= PIPE_CLEAR_COLOR;
- }
- }
- }
-
- if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
- /* clearing combined depth + stencil */
- struct st_renderbuffer *strb = st_renderbuffer(depthRb);
-
- if (strb->surface) {
- if (check_clear_depth_stencil_with_quad(ctx, depthRb))
- quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
- else
- clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
- }
- }
- else {
- /* separate depth/stencil clears */
- /* I don't think truly separate buffers are actually possible in gallium or hw? */
- if (mask & BUFFER_BIT_DEPTH) {
- struct st_renderbuffer *strb = st_renderbuffer(depthRb);
-
- if (strb->surface) {
- if (check_clear_depth_with_quad(ctx, depthRb,
- st->clear.enable_ds_separate))
- quad_buffers |= PIPE_CLEAR_DEPTH;
- else
- clear_buffers |= PIPE_CLEAR_DEPTH;
- }
- }
- if (mask & BUFFER_BIT_STENCIL) {
- struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
-
- if (strb->surface) {
- if (check_clear_stencil_with_quad(ctx, stencilRb,
- st->clear.enable_ds_separate))
- quad_buffers |= PIPE_CLEAR_STENCIL;
- else
- clear_buffers |= PIPE_CLEAR_STENCIL;
- }
- }
- }
-
- /*
- * If we're going to use clear_with_quad() for any reason, use it for
- * everything possible.
- */
- if (quad_buffers) {
- quad_buffers |= clear_buffers;
- clear_with_quad(ctx,
- quad_buffers & PIPE_CLEAR_COLOR,
- quad_buffers & PIPE_CLEAR_DEPTH,
- quad_buffers & PIPE_CLEAR_STENCIL);
- } else if (clear_buffers) {
- /* driver cannot know it can clear everything if the buffer
- * is a combined depth/stencil buffer but this wasn't actually
- * 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);
- }
- if (mask & BUFFER_BIT_ACCUM)
- st_clear_accum_buffer(ctx,
- ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
-}
-
-
-void
-st_init_clear_functions(struct dd_function_table *functions)
-{
- functions->Clear = st_Clear;
-}
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * Copyright 2009 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.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Brian Paul
+ * Michel Dänzer
+ */
+
+#include "main/glheader.h"
+#include "main/formats.h"
+#include "main/macros.h"
+#include "program/prog_instruction.h"
+#include "st_context.h"
+#include "st_atom.h"
+#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"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_draw_quad.h"
+
+#include "cso_cache/cso_context.h"
+
+
+/**
+ * Do per-context initialization for glClear.
+ */
+void
+st_init_clear(struct st_context *st)
+{
+ struct pipe_screen *pscreen = st->pipe->screen;
+
+ memset(&st->clear, 0, sizeof(st->clear));
+
+ st->clear.raster.gl_rasterization_rules = 1;
+ st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
+}
+
+
+/**
+ * Free per-context state for glClear.
+ */
+void
+st_destroy_clear(struct st_context *st)
+{
+ if (st->clear.fs) {
+ cso_delete_fragment_shader(st->cso_context, st->clear.fs);
+ st->clear.fs = NULL;
+ }
+ if (st->clear.vs) {
+ cso_delete_vertex_shader(st->cso_context, st->clear.vs);
+ st->clear.vs = NULL;
+ }
+ if (st->clear.vbuf) {
+ pipe_resource_reference(&st->clear.vbuf, NULL);
+ st->clear.vbuf = NULL;
+ }
+}
+
+
+/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct st_context *st)
+{
+ if (!st->clear.fs)
+ st->clear.fs = util_make_fragment_passthrough_shader(st->pipe);
+
+ cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct st_context *st)
+{
+ /* vertex shader - still required to provide the linkage between
+ * fragment shader input semantics and vertex_element/buffers.
+ */
+ if (!st->clear.vs)
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_COLOR };
+ const uint semantic_indexes[] = { 0, 0 };
+ st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
+}
+
+
+/**
+ * Draw a screen-aligned quadrilateral.
+ * Coords are clip coords with y=0=bottom.
+ */
+static void
+draw_quad(struct st_context *st,
+ float x0, float y0, float x1, float y1, GLfloat z,
+ const GLfloat color[4])
+{
+ struct pipe_context *pipe = st->pipe;
+
+ /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
+ * no_flush) updates to buffers where we know there is no conflict
+ * with previous data. Currently using max_slots > 1 will cause
+ * synchronous rendering if the driver flushes its command buffers
+ * between one bitmap and the next. Our flush hook below isn't
+ * sufficient to catch this as the driver doesn't tell us when it
+ * flushes its own command buffers. Until this gets fixed, pay the
+ * price of allocating a new buffer for each bitmap cache-flush to
+ * avoid synchronous rendering.
+ */
+ const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */
+ GLuint i;
+
+ if (st->clear.vbuf_slot >= max_slots) {
+ pipe_resource_reference(&st->clear.vbuf, NULL);
+ st->clear.vbuf_slot = 0;
+ }
+
+ if (!st->clear.vbuf) {
+ st->clear.vbuf = pipe_buffer_create(pipe->screen,
+ PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
+ max_slots * sizeof(st->clear.vertices));
+ }
+
+ /* positions */
+ st->clear.vertices[0][0][0] = x0;
+ st->clear.vertices[0][0][1] = y0;
+
+ st->clear.vertices[1][0][0] = x1;
+ st->clear.vertices[1][0][1] = y0;
+
+ st->clear.vertices[2][0][0] = x1;
+ st->clear.vertices[2][0][1] = y1;
+
+ st->clear.vertices[3][0][0] = x0;
+ st->clear.vertices[3][0][1] = y1;
+
+ /* same for all verts: */
+ for (i = 0; i < 4; i++) {
+ st->clear.vertices[i][0][2] = z;
+ st->clear.vertices[i][0][3] = 1.0;
+ st->clear.vertices[i][1][0] = color[0];
+ st->clear.vertices[i][1][1] = color[1];
+ st->clear.vertices[i][1][2] = color[2];
+ st->clear.vertices[i][1][3] = color[3];
+ }
+
+ /* put vertex data into vbuf */
+ pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf,
+ st->clear.vbuf_slot
+ * sizeof(st->clear.vertices),
+ sizeof(st->clear.vertices),
+ st->clear.vertices);
+
+ /* draw */
+ util_draw_vertex_buffer(pipe,
+ st->cso_context,
+ st->clear.vbuf,
+ st->clear.vbuf_slot * sizeof(st->clear.vertices),
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
+
+ /* Increment slot */
+ st->clear.vbuf_slot++;
+}
+
+
+
+/**
+ * Do glClear by drawing a quadrilateral.
+ * The vertices of the quad will be computed from the
+ * ctx->DrawBuffer->_X/Ymin/max fields.
+ */
+static void
+clear_with_quad(struct gl_context *ctx,
+ GLboolean color, GLboolean depth, GLboolean stencil)
+{
+ struct st_context *st = st_context(ctx);
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+ const GLfloat fb_width = (GLfloat) fb->Width;
+ const GLfloat fb_height = (GLfloat) fb->Height;
+ const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
+ 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__,
+ color ? "color, " : "",
+ depth ? "depth, " : "",
+ stencil ? "stencil" : "",
+ x0, y0,
+ x1, y1);
+ */
+
+ cso_save_blend(st->cso_context);
+ cso_save_stencil_ref(st->cso_context);
+ cso_save_depth_stencil_alpha(st->cso_context);
+ cso_save_rasterizer(st->cso_context);
+ cso_save_viewport(st->cso_context);
+ cso_save_clip(st->cso_context);
+ cso_save_fragment_shader(st->cso_context);
+ cso_save_vertex_shader(st->cso_context);
+ cso_save_vertex_elements(st->cso_context);
+ cso_save_vertex_buffers(st->cso_context);
+
+ /* blend state: RGBA masking */
+ {
+ struct pipe_blend_state blend;
+ memset(&blend, 0, sizeof(blend));
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ if (color) {
+ if (ctx->Color.ColorMask[0][0])
+ blend.rt[0].colormask |= PIPE_MASK_R;
+ if (ctx->Color.ColorMask[0][1])
+ blend.rt[0].colormask |= PIPE_MASK_G;
+ if (ctx->Color.ColorMask[0][2])
+ blend.rt[0].colormask |= PIPE_MASK_B;
+ if (ctx->Color.ColorMask[0][3])
+ blend.rt[0].colormask |= PIPE_MASK_A;
+ if (st->ctx->Color.DitherFlag)
+ blend.dither = 1;
+ }
+ cso_set_blend(st->cso_context, &blend);
+ }
+
+ /* depth_stencil state: always pass/set to ref value */
+ {
+ struct pipe_depth_stencil_alpha_state depth_stencil;
+ memset(&depth_stencil, 0, sizeof(depth_stencil));
+ if (depth) {
+ depth_stencil.depth.enabled = 1;
+ depth_stencil.depth.writemask = 1;
+ depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
+ }
+
+ if (stencil) {
+ struct pipe_stencil_ref stencil_ref;
+ memset(&stencil_ref, 0, sizeof(stencil_ref));
+ depth_stencil.stencil[0].enabled = 1;
+ depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
+ depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+ depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+ depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+ depth_stencil.stencil[0].valuemask = 0xff;
+ depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
+ stencil_ref.ref_value[0] = ctx->Stencil.Clear;
+ cso_set_stencil_ref(st->cso_context, &stencil_ref);
+ }
+
+ cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
+ }
+
+ cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
+
+ cso_set_rasterizer(st->cso_context, &st->clear.raster);
+
+ /* viewport state: viewport matching window dims */
+ {
+ const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
+ struct pipe_viewport_state vp;
+ vp.scale[0] = 0.5f * fb_width;
+ vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
+ vp.scale[2] = 1.0f;
+ vp.scale[3] = 1.0f;
+ vp.translate[0] = 0.5f * fb_width;
+ vp.translate[1] = 0.5f * fb_height;
+ vp.translate[2] = 0.0f;
+ vp.translate[3] = 0.0f;
+ cso_set_viewport(st->cso_context, &vp);
+ }
+
+ cso_set_clip(st->cso_context, &st->clear.clip);
+ set_fragment_shader(st);
+ set_vertex_shader(st);
+
+ if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
+ st_translate_color(ctx->Color.ClearColorUnclamped,
+ 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);
+ cso_restore_stencil_ref(st->cso_context);
+ cso_restore_depth_stencil_alpha(st->cso_context);
+ cso_restore_rasterizer(st->cso_context);
+ cso_restore_viewport(st->cso_context);
+ cso_restore_clip(st->cso_context);
+ cso_restore_fragment_shader(st->cso_context);
+ cso_restore_vertex_shader(st->cso_context);
+ cso_restore_vertex_elements(st->cso_context);
+ cso_restore_vertex_buffers(st->cso_context);
+}
+
+
+/**
+ * Determine if we need to clear the depth buffer by drawing a quad.
+ */
+static INLINE GLboolean
+check_clear_color_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
+ return GL_TRUE;
+
+ if (!ctx->Color.ColorMask[0][0] ||
+ !ctx->Color.ColorMask[0][1] ||
+ !ctx->Color.ColorMask[0][2] ||
+ !ctx->Color.ColorMask[0][3])
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Determine if we need to clear the combiend depth/stencil buffer by
+ * drawing a quad.
+ */
+static INLINE GLboolean
+check_clear_depth_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+ const GLuint stencilMax = 0xff;
+ GLboolean maskStencil
+ = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
+
+ assert(rb->Format == MESA_FORMAT_S8 ||
+ rb->Format == MESA_FORMAT_Z24_S8 ||
+ rb->Format == MESA_FORMAT_S8_Z24);
+
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
+ return GL_TRUE;
+
+ if (maskStencil)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Determine if we need to clear the depth buffer by drawing a quad.
+ */
+static INLINE GLboolean
+check_clear_depth_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ boolean ds_separate)
+{
+ const struct st_renderbuffer *strb = st_renderbuffer(rb);
+ const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
+
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
+ return GL_TRUE;
+
+ if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Determine if we need to clear the stencil buffer by drawing a quad.
+ */
+static INLINE GLboolean
+check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ boolean ds_separate)
+{
+ const struct st_renderbuffer *strb = st_renderbuffer(rb);
+ const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
+ const GLuint stencilMax = 0xff;
+ const GLboolean maskStencil
+ = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
+
+ assert(rb->Format == MESA_FORMAT_S8 ||
+ rb->Format == MESA_FORMAT_Z24_S8 ||
+ rb->Format == MESA_FORMAT_S8_Z24);
+
+ if (maskStencil)
+ return GL_TRUE;
+
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
+ return GL_TRUE;
+
+ /* This is correct, but it is necessary to look at the depth clear
+ * value held in the surface when it comes time to issue the clear,
+ * rather than taking depth and stencil clear values from the
+ * current state.
+ */
+ if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+
+/**
+ * Called when we need to flush.
+ */
+void
+st_flush_clear(struct st_context *st)
+{
+ /* Release vertex buffer to avoid synchronous rendering if we were
+ * to map it in the next frame.
+ */
+ pipe_resource_reference(&st->clear.vbuf, NULL);
+ st->clear.vbuf_slot = 0;
+}
+
+
+
+/**
+ * Called via ctx->Driver.Clear()
+ */
+static void
+st_Clear(struct gl_context *ctx, GLbitfield mask)
+{
+ static const GLbitfield BUFFER_BITS_DS
+ = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
+ struct st_context *st = st_context(ctx);
+ struct gl_renderbuffer *depthRb
+ = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+ struct gl_renderbuffer *stencilRb
+ = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
+ GLbitfield quad_buffers = 0x0;
+ GLbitfield clear_buffers = 0x0;
+ GLuint i;
+
+ /* This makes sure the pipe has the latest scissor, etc values */
+ st_validate_state( st );
+
+ if (mask & BUFFER_BITS_COLOR) {
+ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+ GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
+
+ if (mask & (1 << b)) {
+ struct gl_renderbuffer *rb
+ = ctx->DrawBuffer->Attachment[b].Renderbuffer;
+ struct st_renderbuffer *strb = st_renderbuffer(rb);
+
+ if (!strb || !strb->surface)
+ continue;
+
+ if (check_clear_color_with_quad( ctx, rb ))
+ quad_buffers |= PIPE_CLEAR_COLOR;
+ else
+ clear_buffers |= PIPE_CLEAR_COLOR;
+ }
+ }
+ }
+
+ if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
+ /* clearing combined depth + stencil */
+ struct st_renderbuffer *strb = st_renderbuffer(depthRb);
+
+ if (strb->surface) {
+ if (check_clear_depth_stencil_with_quad(ctx, depthRb))
+ quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+ else
+ clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+ }
+ }
+ else {
+ /* separate depth/stencil clears */
+ /* I don't think truly separate buffers are actually possible in gallium or hw? */
+ if (mask & BUFFER_BIT_DEPTH) {
+ struct st_renderbuffer *strb = st_renderbuffer(depthRb);
+
+ if (strb->surface) {
+ if (check_clear_depth_with_quad(ctx, depthRb,
+ st->clear.enable_ds_separate))
+ quad_buffers |= PIPE_CLEAR_DEPTH;
+ else
+ clear_buffers |= PIPE_CLEAR_DEPTH;
+ }
+ }
+ if (mask & BUFFER_BIT_STENCIL) {
+ struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
+
+ if (strb->surface) {
+ if (check_clear_stencil_with_quad(ctx, stencilRb,
+ st->clear.enable_ds_separate))
+ quad_buffers |= PIPE_CLEAR_STENCIL;
+ else
+ clear_buffers |= PIPE_CLEAR_STENCIL;
+ }
+ }
+ }
+
+ /*
+ * If we're going to use clear_with_quad() for any reason, use it for
+ * everything possible.
+ */
+ if (quad_buffers) {
+ quad_buffers |= clear_buffers;
+ clear_with_quad(ctx,
+ quad_buffers & PIPE_CLEAR_COLOR,
+ quad_buffers & PIPE_CLEAR_DEPTH,
+ quad_buffers & PIPE_CLEAR_STENCIL);
+ } else if (clear_buffers) {
+ /* driver cannot know it can clear everything if the buffer
+ * is a combined depth/stencil buffer but this wasn't actually
+ * 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.ClearColorUnclamped,
+ ctx->Depth.Clear, ctx->Stencil.Clear);
+ }
+ if (mask & BUFFER_BIT_ACCUM)
+ st_clear_accum_buffer(ctx,
+ ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
+}
+
+
+void
+st_init_clear_functions(struct dd_function_table *functions)
+{
+ functions->Clear = st_Clear;
+}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
index eccc20757..1707f827c 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -296,7 +296,7 @@ base_format(GLenum format)
* of the given format and type.
*/
static GLenum
-internal_format(GLenum format, GLenum type)
+internal_format(struct gl_context *ctx, GLenum format, GLenum type)
{
switch (format) {
case GL_DEPTH_COMPONENT:
@@ -326,7 +326,53 @@ internal_format(GLenum format, GLenum type)
}
}
else {
- return GL_RGBA;
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ default:
+ return GL_RGBA8;
+
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return GL_RGBA4;
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return GL_RGB5_A1;
+
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return GL_RGB10_A2;
+
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_INT:
+ return GL_RGBA16;
+
+ case GL_BYTE:
+ return
+ ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8;
+
+ case GL_SHORT:
+ case GL_INT:
+ return
+ ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
+
+ case GL_HALF_FLOAT_ARB:
+ return
+ ctx->Extensions.ARB_texture_float ? GL_RGBA16F :
+ ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
+
+ case GL_FLOAT:
+ case GL_DOUBLE:
+ return
+ ctx->Extensions.ARB_texture_float ? GL_RGBA32F :
+ ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
+ }
}
}
}
@@ -369,7 +415,7 @@ make_texture(struct st_context *st,
GLenum baseFormat, intFormat;
baseFormat = base_format(format);
- intFormat = internal_format(format, type);
+ intFormat = internal_format(ctx, format, type);
mformat = st_ChooseTextureFormat_renderable(ctx, intFormat,
format, type, GL_FALSE);
@@ -582,6 +628,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
{
struct pipe_rasterizer_state rasterizer;
memset(&rasterizer, 0, sizeof(rasterizer));
+ rasterizer.clamp_fragment_color = ctx->Color._ClampFragmentColor;
rasterizer.gl_rasterization_rules = 1;
rasterizer.scissor = ctx->Scissor.Enabled;
cso_set_rasterizer(cso, &rasterizer);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
index f8da2a4d1..03f58bf0f 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
@@ -331,7 +331,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
GLfloat (*temp)[4];
- const GLbitfield transferOps = ctx->_ImageTransferState;
+ GLbitfield transferOps = ctx->_ImageTransferState;
GLsizei i, j;
GLint yStep, dfStride;
GLfloat *df;
@@ -391,7 +391,10 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
return;
}
- if (format == GL_RGBA && type == GL_FLOAT) {
+ if(ctx->Color._ClampReadColor)
+ transferOps |= IMAGE_CLAMP_BIT;
+
+ if (format == GL_RGBA && type == GL_FLOAT && !transferOps) {
/* write tile(row) directly into user's buffer */
df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width,
height, format, type, 0, 0);
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 2153865cf..e32779044 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -1,529 +1,564 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * Copyright (c) 2008 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.
- *
- **************************************************************************/
-
-#include "main/imports.h"
-#include "main/context.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 "st_context.h"
-#include "st_extensions.h"
-
-
-static int _min(int a, int b)
-{
- return (a < b) ? a : b;
-}
-
-static float _maxf(float a, float b)
-{
- return (a > b) ? a : b;
-}
-
-static int _clamp(int a, int min, int max)
-{
- if (a < min)
- return min;
- else if (a > max)
- return max;
- else
- return a;
-}
-
-
-/**
- * Query driver to get implementation limits.
- * Note that we have to limit/clamp against Mesa's internal limits too.
- */
-void st_init_limits(struct st_context *st)
-{
- struct pipe_screen *screen = st->pipe->screen;
- struct gl_constants *c = &st->ctx->Const;
- gl_shader_type sh;
-
- c->MaxTextureLevels
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
- MAX_TEXTURE_LEVELS);
-
- c->Max3DTextureLevels
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS),
- MAX_3D_TEXTURE_LEVELS);
-
- c->MaxCubeTextureLevels
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS),
- MAX_CUBE_TEXTURE_LEVELS);
-
- c->MaxTextureRectSize
- = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE);
-
- c->MaxTextureImageUnits
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS),
- MAX_TEXTURE_IMAGE_UNITS);
-
- c->MaxVertexTextureImageUnits
- = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS),
- MAX_VERTEX_TEXTURE_IMAGE_UNITS);
-
- c->MaxCombinedTextureImageUnits
- = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS),
- MAX_COMBINED_TEXTURE_IMAGE_UNITS);
-
- c->MaxTextureCoordUnits
- = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS);
-
- c->MaxTextureUnits = _min(c->MaxTextureImageUnits, c->MaxTextureCoordUnits);
-
- c->MaxDrawBuffers
- = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
- 1, MAX_DRAW_BUFFERS);
-
- c->MaxLineWidth
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH));
- c->MaxLineWidthAA
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA));
-
- c->MaxPointSize
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH));
- c->MaxPointSizeAA
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA));
- /* called after _mesa_create_context/_mesa_init_point, fix default user
- * settable max point size up
- */
- st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA);
- /* these are not queryable. Note that GL basically mandates a 1.0 minimum
- * for non-aa sizes, but we can go down to 0.0 for aa points.
- */
- c->MinPointSize = 1.0f;
- c->MinPointSizeAA = 0.0f;
-
- c->MaxTextureMaxAnisotropy
- = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY));
-
- c->MaxTextureLodBias
- = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS);
-
- c->MaxDrawBuffers
- = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
- 1, MAX_DRAW_BUFFERS);
-
- /* Quads always follow GL provoking rules. */
- c->QuadsFollowProvokingVertexConvention = GL_FALSE;
-
- for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) {
- struct gl_shader_compiler_options *options =
- &st->ctx->ShaderCompilerOptions[sh];
- struct gl_program_constants *pc;
-
- switch (sh) {
- case PIPE_SHADER_FRAGMENT:
- pc = &c->FragmentProgram;
- break;
- case PIPE_SHADER_VERTEX:
- pc = &c->VertexProgram;
- break;
- case PIPE_SHADER_GEOMETRY:
- pc = &c->GeometryProgram;
- break;
- default:
- assert(0);
- continue;
- }
-
- pc->MaxNativeInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
- pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS);
- pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS);
- pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS);
- pc->MaxNativeAttribs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS);
- pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS);
- pc->MaxNativeAddressRegs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS);
- pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONSTS);
- pc->MaxUniformComponents = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS);
-
- options->EmitNoNoise = TRUE;
-
- /* TODO: make these more fine-grained if anyone needs it */
- options->EmitNoIfs = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
- options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
- options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
- options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
-
- options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED);
-
- options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR);
- options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR);
- options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR);
- options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_CONST_ADDR);
-
- if(options->EmitNoLoops)
- options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
- }
-
- /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs
- * and is set in MaxNativeAttribs. It's always 2 colors + N generic
- * attributes. The GLSL compiler never uses COLORn for varyings, so we
- * subtract the 2 colors to get the maximum number of varyings (generic
- * attributes) supported by a driver. */
- c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2;
- c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING);
-
- /* XXX we'll need a better query here someday */
- if (screen->get_param(screen, PIPE_CAP_GLSL)) {
- c->GLSLVersion = 120;
- }
-}
-
-
-/**
- * Use pipe_screen::get_param() to query PIPE_CAP_ values to determine
- * which GL extensions are supported.
- * Quite a few extensions are always supported because they are standard
- * features or can be built on top of other gallium features.
- * Some fine tuning may still be needed.
- */
-void st_init_extensions(struct st_context *st)
-{
- struct pipe_screen *screen = st->pipe->screen;
- struct gl_context *ctx = st->ctx;
-
- /*
- * Extensions that are supported by all Gallium drivers:
- */
- ctx->Extensions.ARB_copy_buffer = GL_TRUE;
- ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
- ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
- ctx->Extensions.ARB_fragment_program = GL_TRUE;
- ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
- ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
- ctx->Extensions.ARB_multisample = GL_TRUE;
- ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */
- ctx->Extensions.ARB_texture_compression = GL_TRUE;
- ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
- ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
- ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
- ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
- ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
- ctx->Extensions.ARB_vertex_program = GL_TRUE;
- ctx->Extensions.ARB_window_pos = GL_TRUE;
-
- ctx->Extensions.EXT_blend_color = GL_TRUE;
- ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
- ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
- ctx->Extensions.EXT_blend_minmax = GL_TRUE;
- ctx->Extensions.EXT_blend_subtract = GL_TRUE;
- ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
- ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
- ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
- ctx->Extensions.EXT_fog_coord = GL_TRUE;
- ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
- ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
- ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
- ctx->Extensions.EXT_point_parameters = GL_TRUE;
- ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
- ctx->Extensions.EXT_secondary_color = GL_TRUE;
- ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
- ctx->Extensions.EXT_texture_env_add = GL_TRUE;
- ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
- ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
- ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
- if (ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2)
- ctx->Extensions.EXT_texture_format_BGRA8888 = GL_TRUE;
-
- ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
-
- ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
-
- ctx->Extensions.MESA_pack_invert = GL_TRUE;
-
- ctx->Extensions.NV_blend_square = GL_TRUE;
- ctx->Extensions.NV_texgen_reflection = GL_TRUE;
- ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
- ctx->Extensions.NV_texture_rectangle = GL_TRUE;
-#if 0
- /* possibly could support the following two */
- ctx->Extensions.NV_vertex_program = GL_TRUE;
- ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
-#endif
-
-#if FEATURE_OES_EGL_image
- ctx->Extensions.OES_EGL_image = GL_TRUE;
-#endif
-#if FEATURE_OES_draw_texture
- ctx->Extensions.OES_draw_texture = GL_TRUE;
-#endif
-
- ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
-
- /*
- * Extensions that depend on the driver/hardware:
- */
- if (screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS) > 0) {
- ctx->Extensions.ARB_draw_buffers = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_SWIZZLE) > 0) {
- ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_GLSL)) {
- ctx->Extensions.ARB_fragment_shader = GL_TRUE;
- ctx->Extensions.ARB_vertex_shader = GL_TRUE;
- ctx->Extensions.ARB_shader_objects = GL_TRUE;
- ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
- ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
- ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_REPEAT) > 0) {
- ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) {
- ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_CLAMP) > 0) {
- ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
- ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
- ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS) > 1) {
- ctx->Extensions.ARB_multitexture = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
- ctx->Extensions.ATI_separate_stencil = GL_TRUE;
- ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_ANISOTROPIC_FILTER)) {
- ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
- ctx->Extensions.ARB_point_sprite = GL_TRUE;
- /* GL_NV_point_sprite is not supported by gallium because we don't
- * support the GL_POINT_SPRITE_R_MODE_NV option.
- */
- }
-
- if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
- ctx->Extensions.ARB_occlusion_query = GL_TRUE;
- ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
- }
- if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) {
- ctx->Extensions.EXT_timer_query = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_SHADOW_MAP)) {
- ctx->Extensions.ARB_depth_texture = GL_TRUE;
- ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
- ctx->Extensions.ARB_shadow = GL_TRUE;
- ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
- /*ctx->Extensions.ARB_shadow_ambient = GL_TRUE;*/
- }
-
- /* GL_EXT_packed_depth_stencil requires both the ability to render to
- * a depth/stencil buffer and texture from depth/stencil source.
- */
- if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL) &&
- screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
- }
- else if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL) &&
- screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
- }
-
- /* sRGB support */
- if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) ||
- screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
- ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
- if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET) ||
- screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET)) {
- ctx->Extensions.EXT_framebuffer_sRGB = GL_TRUE;
- ctx->Const.sRGBCapable = GL_TRUE;
- }
- }
-
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.ARB_texture_rg = GL_TRUE;
- }
-
- /* s3tc support */
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- ctx->Mesa_DXTn) {
- ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
- ctx->Extensions.S3_s3tc = GL_TRUE;
- }
-
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_SNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_SNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)
- ) {
- ctx->Extensions.ARB_texture_compression_rgtc = GL_TRUE;
- }
-
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- screen->is_format_supported(screen, PIPE_FORMAT_LATC1_SNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) &&
- screen->is_format_supported(screen, PIPE_FORMAT_LATC2_SNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.EXT_texture_compression_latc = GL_TRUE;
- }
-
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.ATI_texture_compression_3dc = GL_TRUE;
- }
-
- /* ycbcr support */
- if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW) ||
- screen->is_format_supported(screen, PIPE_FORMAT_YUYV,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW)) {
- ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
- }
-
- /* GL_EXT_texture_array */
- if (screen->get_param(screen, PIPE_CAP_ARRAY_TEXTURES)) {
- ctx->Extensions.EXT_texture_array = GL_TRUE;
- ctx->Extensions.MESA_texture_array = GL_TRUE;
- }
-
- /* GL_ARB_framebuffer_object */
- if (ctx->Extensions.EXT_packed_depth_stencil) {
- /* we support always support GL_EXT_framebuffer_blit */
- ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
- }
-
- if (st->pipe->render_condition) {
- ctx->Extensions.NV_conditional_render = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) {
- ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) {
- ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
- }
-
- /* GL_ARB_half_float_vertex */
- if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_BUFFER, 0,
- PIPE_BIND_VERTEX_BUFFER)) {
- ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
- }
-
- if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
-#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */
- ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
-#endif
- }
-
- if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
- ctx->Extensions.NV_primitive_restart = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
- ctx->Extensions.ARB_depth_clamp = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
- ctx->Extensions.ARB_shader_stencil_export = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TGSI_INSTANCEID)) {
- ctx->Extensions.ARB_draw_instanced = GL_TRUE;
- }
- if (screen->get_param(screen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR)) {
- ctx->Extensions.ARB_instanced_arrays = GL_TRUE;
- }
-
- if (screen->fence_finish) {
- ctx->Extensions.ARB_sync = GL_TRUE;
- }
-
- if (st->pipe->texture_barrier) {
- ctx->Extensions.NV_texture_barrier = GL_TRUE;
- }
-}
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright (c) 2008 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.
+ *
+ **************************************************************************/
+
+#include "main/imports.h"
+#include "main/context.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 "st_context.h"
+#include "st_extensions.h"
+
+
+static int _min(int a, int b)
+{
+ return (a < b) ? a : b;
+}
+
+static float _maxf(float a, float b)
+{
+ return (a > b) ? a : b;
+}
+
+static int _clamp(int a, int min, int max)
+{
+ if (a < min)
+ return min;
+ else if (a > max)
+ return max;
+ else
+ return a;
+}
+
+
+/**
+ * Query driver to get implementation limits.
+ * Note that we have to limit/clamp against Mesa's internal limits too.
+ */
+void st_init_limits(struct st_context *st)
+{
+ struct pipe_screen *screen = st->pipe->screen;
+ struct gl_constants *c = &st->ctx->Const;
+ gl_shader_type sh;
+
+ c->MaxTextureLevels
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
+ MAX_TEXTURE_LEVELS);
+
+ c->Max3DTextureLevels
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS),
+ MAX_3D_TEXTURE_LEVELS);
+
+ c->MaxCubeTextureLevels
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS),
+ MAX_CUBE_TEXTURE_LEVELS);
+
+ c->MaxTextureRectSize
+ = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE);
+
+ c->MaxTextureImageUnits
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS),
+ MAX_TEXTURE_IMAGE_UNITS);
+
+ c->MaxVertexTextureImageUnits
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS),
+ MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+
+ c->MaxCombinedTextureImageUnits
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS),
+ MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+
+ c->MaxTextureCoordUnits
+ = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS);
+
+ c->MaxTextureUnits = _min(c->MaxTextureImageUnits, c->MaxTextureCoordUnits);
+
+ c->MaxDrawBuffers
+ = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
+ 1, MAX_DRAW_BUFFERS);
+
+ c->MaxLineWidth
+ = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH));
+ c->MaxLineWidthAA
+ = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA));
+
+ c->MaxPointSize
+ = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH));
+ c->MaxPointSizeAA
+ = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA));
+ /* called after _mesa_create_context/_mesa_init_point, fix default user
+ * settable max point size up
+ */
+ st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA);
+ /* these are not queryable. Note that GL basically mandates a 1.0 minimum
+ * for non-aa sizes, but we can go down to 0.0 for aa points.
+ */
+ c->MinPointSize = 1.0f;
+ c->MinPointSizeAA = 0.0f;
+
+ c->MaxTextureMaxAnisotropy
+ = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY));
+
+ c->MaxTextureLodBias
+ = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS);
+
+ c->MaxDrawBuffers
+ = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
+ 1, MAX_DRAW_BUFFERS);
+
+ /* Quads always follow GL provoking rules. */
+ c->QuadsFollowProvokingVertexConvention = GL_FALSE;
+
+ for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) {
+ struct gl_shader_compiler_options *options =
+ &st->ctx->ShaderCompilerOptions[sh];
+ struct gl_program_constants *pc;
+
+ switch (sh) {
+ case PIPE_SHADER_FRAGMENT:
+ pc = &c->FragmentProgram;
+ break;
+ case PIPE_SHADER_VERTEX:
+ pc = &c->VertexProgram;
+ break;
+ case PIPE_SHADER_GEOMETRY:
+ pc = &c->GeometryProgram;
+ break;
+ default:
+ assert(0);
+ continue;
+ }
+
+ pc->MaxNativeInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
+ pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS);
+ pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS);
+ pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS);
+ pc->MaxNativeAttribs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS);
+ pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS);
+ pc->MaxNativeAddressRegs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS);
+ pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONSTS);
+ pc->MaxUniformComponents = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS);
+
+ options->EmitNoNoise = TRUE;
+
+ /* TODO: make these more fine-grained if anyone needs it */
+ options->EmitNoIfs = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
+ options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
+ options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
+ options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
+
+ options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED);
+
+ options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh,
+ PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR);
+ options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh,
+ PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR);
+ options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh,
+ PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR);
+ options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh,
+ PIPE_SHADER_CAP_INDIRECT_CONST_ADDR);
+
+ if(options->EmitNoLoops)
+ options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
+ }
+
+ /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs
+ * and is set in MaxNativeAttribs. It's always 2 colors + N generic
+ * attributes. The GLSL compiler never uses COLORn for varyings, so we
+ * subtract the 2 colors to get the maximum number of varyings (generic
+ * attributes) supported by a driver. */
+ c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2;
+ c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING);
+
+ /* XXX we'll need a better query here someday */
+ if (screen->get_param(screen, PIPE_CAP_GLSL)) {
+ c->GLSLVersion = 120;
+ }
+}
+
+
+/**
+ * Use pipe_screen::get_param() to query PIPE_CAP_ values to determine
+ * which GL extensions are supported.
+ * Quite a few extensions are always supported because they are standard
+ * features or can be built on top of other gallium features.
+ * Some fine tuning may still be needed.
+ */
+void st_init_extensions(struct st_context *st)
+{
+ struct pipe_screen *screen = st->pipe->screen;
+ struct gl_context *ctx = st->ctx;
+
+ /*
+ * Extensions that are supported by all Gallium drivers:
+ */
+ ctx->Extensions.ARB_copy_buffer = GL_TRUE;
+ ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
+ ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
+ ctx->Extensions.ARB_fragment_program = GL_TRUE;
+ ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
+ ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
+ ctx->Extensions.ARB_multisample = GL_TRUE;
+ ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */
+ ctx->Extensions.ARB_texture_compression = GL_TRUE;
+ ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
+ ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
+ ctx->Extensions.ARB_vertex_program = GL_TRUE;
+ ctx->Extensions.ARB_window_pos = GL_TRUE;
+
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+ ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
+ ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
+ ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
+ ctx->Extensions.EXT_fog_coord = GL_TRUE;
+ ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
+ ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
+ ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
+ ctx->Extensions.EXT_point_parameters = GL_TRUE;
+ ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
+ ctx->Extensions.EXT_secondary_color = GL_TRUE;
+ ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_add = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
+ ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
+ if (ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2)
+ ctx->Extensions.EXT_texture_format_BGRA8888 = GL_TRUE;
+
+ ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
+
+ ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
+
+ ctx->Extensions.MESA_pack_invert = GL_TRUE;
+
+ ctx->Extensions.NV_blend_square = GL_TRUE;
+ ctx->Extensions.NV_texgen_reflection = GL_TRUE;
+ ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
+ ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+#if 0
+ /* possibly could support the following two */
+ ctx->Extensions.NV_vertex_program = GL_TRUE;
+ ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
+#endif
+
+#if FEATURE_OES_EGL_image
+ ctx->Extensions.OES_EGL_image = GL_TRUE;
+#endif
+#if FEATURE_OES_draw_texture
+ ctx->Extensions.OES_draw_texture = GL_TRUE;
+#endif
+
+ ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
+
+ /*
+ * Extensions that depend on the driver/hardware:
+ */
+ if (screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS) > 0) {
+ ctx->Extensions.ARB_draw_buffers = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_TEXTURE_SWIZZLE) > 0) {
+ ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_GLSL)) {
+ ctx->Extensions.ARB_fragment_shader = GL_TRUE;
+ ctx->Extensions.ARB_vertex_shader = GL_TRUE;
+ ctx->Extensions.ARB_shader_objects = GL_TRUE;
+ ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
+ ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
+ ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_REPEAT) > 0) {
+ ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) {
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_CLAMP) > 0) {
+ ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
+ ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+ ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS) > 1) {
+ ctx->Extensions.ARB_multitexture = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
+ ctx->Extensions.ATI_separate_stencil = GL_TRUE;
+ ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_ANISOTROPIC_FILTER)) {
+ ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
+ ctx->Extensions.ARB_point_sprite = GL_TRUE;
+ /* GL_NV_point_sprite is not supported by gallium because we don't
+ * support the GL_POINT_SPRITE_R_MODE_NV option.
+ */
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
+ ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
+ }
+ if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) {
+ ctx->Extensions.EXT_timer_query = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_TEXTURE_SHADOW_MAP)) {
+ ctx->Extensions.ARB_depth_texture = GL_TRUE;
+ ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
+ ctx->Extensions.ARB_shadow = GL_TRUE;
+ ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
+ /*ctx->Extensions.ARB_shadow_ambient = GL_TRUE;*/
+ }
+
+ /* GL_EXT_packed_depth_stencil requires both the ability to render to
+ * a depth/stencil buffer and texture from depth/stencil source.
+ */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_DEPTH_STENCIL) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
+ }
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_DEPTH_STENCIL) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
+ }
+
+ /* sRGB support */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) ||
+ screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
+ ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET) ||
+ screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET)) {
+ ctx->Extensions.EXT_framebuffer_sRGB = GL_TRUE;
+ ctx->Const.sRGBCapable = GL_TRUE;
+ }
+ }
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.ARB_texture_rg = GL_TRUE;
+ }
+
+ /* s3tc support */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ ctx->Mesa_DXTn) {
+ ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
+ ctx->Extensions.S3_s3tc = GL_TRUE;
+ }
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)
+ ) {
+ ctx->Extensions.ARB_texture_compression_rgtc = GL_TRUE;
+ }
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_LATC1_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_LATC2_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.EXT_texture_compression_latc = GL_TRUE;
+ }
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.ATI_texture_compression_3dc = GL_TRUE;
+ }
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.EXT_texture_snorm = GL_TRUE;
+ }
+
+ /* ycbcr support */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) ||
+ screen->is_format_supported(screen, PIPE_FORMAT_YUYV,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
+ }
+
+ /* GL_EXT_texture_array */
+ if (screen->get_param(screen, PIPE_CAP_ARRAY_TEXTURES)) {
+ ctx->Extensions.EXT_texture_array = GL_TRUE;
+ ctx->Extensions.MESA_texture_array = GL_TRUE;
+ }
+
+ /* GL_ARB_framebuffer_object */
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ /* we support always support GL_EXT_framebuffer_blit */
+ ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
+ }
+
+ if (st->pipe->render_condition) {
+ ctx->Extensions.NV_conditional_render = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) {
+ ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) {
+ ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
+ }
+
+ /* GL_ARB_half_float_vertex */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT,
+ PIPE_BUFFER, 0,
+ PIPE_BIND_VERTEX_BUFFER)) {
+ ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
+ }
+
+ if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
+#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */
+ ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
+#endif
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
+ ctx->Extensions.NV_primitive_restart = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
+ ctx->Extensions.ARB_depth_clamp = GL_TRUE;
+ }
+
+ /* This extension does not actually require support of floating point
+ * render targets, just clamping controls.
+ * Advertise this extension if either fragment color clamping is supported
+ * or no render targets having color values outside of the range [0, 1]
+ * are supported, in which case the fragment color clamping has no effect
+ * on rendering.
+ */
+ if (screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL) ||
+ (!screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET) &&
+ !screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET) &&
+ !screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET) &&
+ !screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_FLOAT,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET) &&
+ !screen->is_format_supported(screen, PIPE_FORMAT_R11G11B10_FLOAT,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET) &&
+ !screen->is_format_supported(screen, PIPE_FORMAT_R9G9B9E5_FLOAT,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET))) {
+ ctx->Extensions.ARB_color_buffer_float = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
+ ctx->Extensions.ARB_shader_stencil_export = GL_TRUE;
+ }
+
+ if (screen->get_param(screen, PIPE_CAP_TGSI_INSTANCEID)) {
+ ctx->Extensions.ARB_draw_instanced = GL_TRUE;
+ }
+ if (screen->get_param(screen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR)) {
+ ctx->Extensions.ARB_instanced_arrays = GL_TRUE;
+ }
+
+ if (screen->fence_finish) {
+ ctx->Extensions.ARB_sync = GL_TRUE;
+ }
+
+ if (st->pipe->texture_barrier) {
+ ctx->Extensions.NV_texture_barrier = GL_TRUE;
+ }
+}
diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c
index 0e67a6bc2..957a06c08 100644
--- a/mesalib/src/mesa/state_tracker/st_format.c
+++ b/mesalib/src/mesa/state_tracker/st_format.c
@@ -1,1184 +1,1412 @@
-/**************************************************************************
- *
- * 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;
-
- case MESA_FORMAT_RED_RGTC1:
- return PIPE_FORMAT_RGTC1_UNORM;
- case MESA_FORMAT_SIGNED_RED_RGTC1:
- return PIPE_FORMAT_RGTC1_SNORM;
- case MESA_FORMAT_RG_RGTC2:
- return PIPE_FORMAT_RGTC2_UNORM;
- case MESA_FORMAT_SIGNED_RG_RGTC2:
- return PIPE_FORMAT_RGTC2_SNORM;
-
- case MESA_FORMAT_L_LATC1:
- return PIPE_FORMAT_LATC1_UNORM;
- case MESA_FORMAT_SIGNED_L_LATC1:
- return PIPE_FORMAT_LATC1_SNORM;
- case MESA_FORMAT_LA_LATC2:
- return PIPE_FORMAT_LATC2_UNORM;
- case MESA_FORMAT_SIGNED_LA_LATC2:
- return PIPE_FORMAT_LATC2_SNORM;
-
- 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;
-
- case PIPE_FORMAT_RGTC1_UNORM:
- return MESA_FORMAT_RED_RGTC1;
- case PIPE_FORMAT_RGTC1_SNORM:
- return MESA_FORMAT_SIGNED_RED_RGTC1;
- case PIPE_FORMAT_RGTC2_UNORM:
- return MESA_FORMAT_RG_RGTC2;
- case PIPE_FORMAT_RGTC2_SNORM:
- return MESA_FORMAT_SIGNED_RG_RGTC2;
-
- case PIPE_FORMAT_LATC1_UNORM:
- return MESA_FORMAT_L_LATC1;
- case PIPE_FORMAT_LATC1_SNORM:
- return MESA_FORMAT_SIGNED_L_LATC1;
- case PIPE_FORMAT_LATC2_UNORM:
- return MESA_FORMAT_LA_LATC2;
- case PIPE_FORMAT_LATC2_SNORM:
- return MESA_FORMAT_SIGNED_LA_LATC2;
-
- 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)
-{
- uint i;
- for (i = 0; i < num_formats; i++) {
- if (screen->is_format_supported(screen, formats[i], target,
- sample_count, tex_usage)) {
- 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)
-{
- 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);
-}
-
-
-/**
- * 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)
-{
- 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);
-}
-
-/**
- * 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)
-{
- 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);
-}
-
-
-/**
- * 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)
-{
-
- switch (internalFormat) {
- case GL_RGB10:
- case GL_RGB10_A2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B10G10R10A2_UNORM;
- /* Pass through. */
- case 4:
- case GL_RGBA:
- case GL_RGBA8:
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_BGRA:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B8G8R8A8_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B8G8R8A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case 3:
- case GL_RGB:
- case GL_RGB8:
- return default_rgb_format( screen, target, sample_count, bindings);
-
- 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))
- return PIPE_FORMAT_R16G16B16A16_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_RGBA4:
- case GL_RGBA2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B4G4R4A4_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_RGB5_A1:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B5G5R5A1_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_R3_G3_B2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM,
- target, sample_count, bindings))
- 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))
- return PIPE_FORMAT_B5G6R5_UNORM;
- if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B5G5R5A1_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_ALPHA12:
- case GL_ALPHA16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target,
- sample_count, bindings))
- 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))
- return PIPE_FORMAT_A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L16_UNORM;
- /* Pass through. */
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- 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))
- return PIPE_FORMAT_L16A16_UNORM;
- /* Pass through. */
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_LUMINANCE4_ALPHA4:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L4A4_UNORM;
- if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target,
- sample_count, bindings))
- 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))
- return PIPE_FORMAT_I8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_YCBCR_MESA:
- if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target,
- sample_count, bindings)) {
- return PIPE_FORMAT_UYVY;
- }
- if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target,
- sample_count, bindings)) {
- return PIPE_FORMAT_YUYV;
- }
- return PIPE_FORMAT_NONE;
-
- 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))
- return PIPE_FORMAT_DXT1_RGB;
- else
- return default_rgb_format(screen, target, sample_count, bindings);
-
- 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))
- return PIPE_FORMAT_DXT3_RGBA;
- else
- return default_rgba_format(screen, target, sample_count, bindings);
-
- 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))
- 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))
- 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))
- 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))
- 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))
- 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))
- return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
- if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- target, sample_count, bindings))
- 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))
- 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);
- }
-
- 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);
- }
-
- 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);
- }
-
- 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);
-
- 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))
- return PIPE_FORMAT_DXT1_SRGB;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- 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))
- return PIPE_FORMAT_DXT3_SRGBA;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- 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))
- return PIPE_FORMAT_L8A8_SRGB;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- case GL_SLUMINANCE_EXT:
- case GL_SLUMINANCE8_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8_SRGB;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- case GL_RED:
- case GL_R8:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
- sample_count, bindings))
- 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))
- 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))
- 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))
- return PIPE_FORMAT_R16G16_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RED:
- case GL_COMPRESSED_RED_RGTC1:
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_RGTC1_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R8_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))
- return PIPE_FORMAT_RGTC1_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RG:
- case GL_COMPRESSED_RG_RGTC2:
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_RGTC2_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R8G8_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))
- return PIPE_FORMAT_RGTC2_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_LUMINANCE:
- case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC1_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_SNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC1_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
- case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC2_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_SNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC2_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))
- 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))
- 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))
- 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))
- 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))
- 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))
- 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);
- }
-}
+/**************************************************************************
+ *
+ * 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;
+
+ case MESA_FORMAT_RED_RGTC1:
+ return PIPE_FORMAT_RGTC1_UNORM;
+ case MESA_FORMAT_SIGNED_RED_RGTC1:
+ return PIPE_FORMAT_RGTC1_SNORM;
+ case MESA_FORMAT_RG_RGTC2:
+ return PIPE_FORMAT_RGTC2_UNORM;
+ case MESA_FORMAT_SIGNED_RG_RGTC2:
+ return PIPE_FORMAT_RGTC2_SNORM;
+
+ case MESA_FORMAT_L_LATC1:
+ return PIPE_FORMAT_LATC1_UNORM;
+ case MESA_FORMAT_SIGNED_L_LATC1:
+ return PIPE_FORMAT_LATC1_SNORM;
+ case MESA_FORMAT_LA_LATC2:
+ return PIPE_FORMAT_LATC2_UNORM;
+ case MESA_FORMAT_SIGNED_LA_LATC2:
+ return PIPE_FORMAT_LATC2_SNORM;
+
+ /* signed normalized formats */
+ case MESA_FORMAT_SIGNED_R8:
+ return PIPE_FORMAT_R8_SNORM;
+ case MESA_FORMAT_SIGNED_RG88_REV:
+ return PIPE_FORMAT_R8G8_SNORM;
+ case MESA_FORMAT_SIGNED_RGBA8888_REV:
+ return PIPE_FORMAT_R8G8B8A8_SNORM;
+
+ case MESA_FORMAT_SIGNED_A8:
+ return PIPE_FORMAT_A8_SNORM;
+ case MESA_FORMAT_SIGNED_L8:
+ return PIPE_FORMAT_L8_SNORM;
+ case MESA_FORMAT_SIGNED_AL88:
+ return PIPE_FORMAT_L8A8_SNORM;
+ case MESA_FORMAT_SIGNED_I8:
+ return PIPE_FORMAT_I8_SNORM;
+
+ case MESA_FORMAT_SIGNED_R16:
+ return PIPE_FORMAT_R16_SNORM;
+ case MESA_FORMAT_SIGNED_GR1616:
+ return PIPE_FORMAT_R16G16_SNORM;
+ case MESA_FORMAT_SIGNED_RGBA_16:
+ return PIPE_FORMAT_R16G16B16A16_SNORM;
+
+ case MESA_FORMAT_SIGNED_A16:
+ return PIPE_FORMAT_A16_SNORM;
+ case MESA_FORMAT_SIGNED_L16:
+ return PIPE_FORMAT_L16_SNORM;
+ case MESA_FORMAT_SIGNED_AL1616:
+ return PIPE_FORMAT_L16A16_SNORM;
+ case MESA_FORMAT_SIGNED_I16:
+ return PIPE_FORMAT_I16_SNORM;
+
+ 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_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;
+
+ case PIPE_FORMAT_RGTC1_UNORM:
+ return MESA_FORMAT_RED_RGTC1;
+ case PIPE_FORMAT_RGTC1_SNORM:
+ return MESA_FORMAT_SIGNED_RED_RGTC1;
+ case PIPE_FORMAT_RGTC2_UNORM:
+ return MESA_FORMAT_RG_RGTC2;
+ case PIPE_FORMAT_RGTC2_SNORM:
+ return MESA_FORMAT_SIGNED_RG_RGTC2;
+
+ case PIPE_FORMAT_LATC1_UNORM:
+ return MESA_FORMAT_L_LATC1;
+ case PIPE_FORMAT_LATC1_SNORM:
+ return MESA_FORMAT_SIGNED_L_LATC1;
+ case PIPE_FORMAT_LATC2_UNORM:
+ return MESA_FORMAT_LA_LATC2;
+ case PIPE_FORMAT_LATC2_SNORM:
+ return MESA_FORMAT_SIGNED_LA_LATC2;
+
+ /* signed normalized formats */
+ case PIPE_FORMAT_R8_SNORM:
+ return MESA_FORMAT_SIGNED_R8;
+ case PIPE_FORMAT_R8G8_SNORM:
+ return MESA_FORMAT_SIGNED_RG88_REV;
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ return MESA_FORMAT_SIGNED_RGBA8888_REV;
+
+ case PIPE_FORMAT_A8_SNORM:
+ return MESA_FORMAT_SIGNED_A8;
+ case PIPE_FORMAT_L8_SNORM:
+ return MESA_FORMAT_SIGNED_L8;
+ case PIPE_FORMAT_L8A8_SNORM:
+ return MESA_FORMAT_SIGNED_AL88;
+ case PIPE_FORMAT_I8_SNORM:
+ return MESA_FORMAT_SIGNED_I8;
+
+ case PIPE_FORMAT_R16_SNORM:
+ return MESA_FORMAT_SIGNED_R16;
+ case PIPE_FORMAT_R16G16_SNORM:
+ return MESA_FORMAT_SIGNED_GR1616;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return MESA_FORMAT_SIGNED_RGBA_16;
+
+ case PIPE_FORMAT_A16_SNORM:
+ return MESA_FORMAT_SIGNED_A16;
+ case PIPE_FORMAT_L16_SNORM:
+ return MESA_FORMAT_SIGNED_L16;
+ case PIPE_FORMAT_L16A16_SNORM:
+ return MESA_FORMAT_SIGNED_AL1616;
+ case PIPE_FORMAT_I16_SNORM:
+ return MESA_FORMAT_SIGNED_I16;
+
+ 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)
+{
+ uint i;
+ for (i = 0; i < num_formats; i++) {
+ if (screen->is_format_supported(screen, formats[i], target,
+ sample_count, tex_usage)) {
+ 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)
+{
+ 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);
+}
+
+
+/**
+ * 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)
+{
+ 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);
+}
+
+/**
+ * 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)
+{
+ 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);
+}
+
+
+/**
+ * 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)
+{
+
+ switch (internalFormat) {
+ case GL_RGB10:
+ case GL_RGB10_A2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM,
+ target, sample_count, bindings))
+ return PIPE_FORMAT_B10G10R10A2_UNORM;
+ /* Pass through. */
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA8:
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_BGRA:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B8G8R8A8_UNORM,
+ target, sample_count, bindings))
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case 3:
+ case GL_RGB:
+ case GL_RGB8:
+ return default_rgb_format( screen, target, sample_count, bindings);
+
+ 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))
+ return PIPE_FORMAT_R16G16B16A16_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM,
+ target, sample_count, bindings))
+ return PIPE_FORMAT_B4G4R4A4_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_RGB5_A1:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
+ target, sample_count, bindings))
+ return PIPE_FORMAT_B5G5R5A1_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_R3_G3_B2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM,
+ target, sample_count, bindings))
+ 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))
+ return PIPE_FORMAT_B5G6R5_UNORM;
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
+ target, sample_count, bindings))
+ return PIPE_FORMAT_B5G5R5A1_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target,
+ sample_count, bindings))
+ 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))
+ return PIPE_FORMAT_A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L16_UNORM;
+ /* Pass through. */
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ 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))
+ return PIPE_FORMAT_L16A16_UNORM;
+ /* Pass through. */
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_LUMINANCE4_ALPHA4:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L4A4_UNORM;
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target,
+ sample_count, bindings))
+ 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))
+ return PIPE_FORMAT_I8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings);
+
+ case GL_YCBCR_MESA:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target,
+ sample_count, bindings)) {
+ return PIPE_FORMAT_UYVY;
+ }
+ if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target,
+ sample_count, bindings)) {
+ return PIPE_FORMAT_YUYV;
+ }
+ return PIPE_FORMAT_NONE;
+
+ 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))
+ return PIPE_FORMAT_DXT1_RGB;
+ else
+ return default_rgb_format(screen, target, sample_count, bindings);
+
+ 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))
+ return PIPE_FORMAT_DXT3_RGBA;
+ else
+ return default_rgba_format(screen, target, sample_count, bindings);
+
+ 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))
+ 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))
+ 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))
+ 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))
+ 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))
+ 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))
+ return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ target, sample_count, bindings))
+ 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))
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+
+ 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))
+ return PIPE_FORMAT_DXT1_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings);
+
+ 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))
+ return PIPE_FORMAT_DXT3_SRGBA;
+ return default_srgba_format( screen, target, sample_count, bindings);
+
+ 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))
+ return PIPE_FORMAT_L8A8_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings);
+
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L8_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings);
+
+ case GL_RED:
+ case GL_R8:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
+ sample_count, bindings))
+ 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))
+ 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))
+ 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))
+ return PIPE_FORMAT_R16G16_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RED:
+ case GL_COMPRESSED_RED_RGTC1:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_RGTC1_UNORM;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_R8_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))
+ return PIPE_FORMAT_RGTC1_SNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_RG:
+ case GL_COMPRESSED_RG_RGTC2:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_RGTC2_UNORM;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_R8G8_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))
+ return PIPE_FORMAT_RGTC2_SNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_LUMINANCE:
+ case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_LATC1_UNORM;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L8_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_SNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_LATC1_SNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+ case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_LATC2_UNORM;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_UNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_L8A8_UNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_SNORM, target,
+ sample_count, bindings))
+ return PIPE_FORMAT_LATC2_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))
+ 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))
+ 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))
+ 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))
+ 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))
+ 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))
+ return PIPE_FORMAT_R32G32B32A32_USCALED;
+ return PIPE_FORMAT_NONE;
+
+ /* signed normalized formats */
+ case GL_RED_SNORM:
+ case GL_R8_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_R8_SNORM,
+ PIPE_FORMAT_R8G8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_R16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_R16_SNORM,
+ PIPE_FORMAT_R16G16_SNORM,
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_R8_SNORM,
+ PIPE_FORMAT_R8G8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_RG_SNORM:
+ case GL_RG8_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_R8G8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_RG16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_R16G16_SNORM,
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_R8G8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_RGB_SNORM:
+ case GL_RGB8_SNORM:
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SNORM,
+ target,
+ sample_count, bindings))
+ return PIPE_FORMAT_R8G8B8A8_SNORM;
+ return PIPE_FORMAT_NONE;
+
+ case GL_RGB16_SNORM:
+ case GL_RGBA16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+
+ case GL_ALPHA_SNORM:
+ case GL_ALPHA8_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_A8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_ALPHA16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_A16_SNORM,
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_A8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_LUMINANCE_SNORM:
+ case GL_LUMINANCE8_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_L8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_LUMINANCE16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_L16_SNORM,
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_L8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_LUMINANCE_ALPHA_SNORM:
+ case GL_LUMINANCE8_ALPHA8_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_L8A8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_LUMINANCE16_ALPHA16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_L16A16_SNORM,
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_L8A8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_INTENSITY_SNORM:
+ case GL_INTENSITY8_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_I8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ case GL_INTENSITY16_SNORM:
+ {
+ static const enum pipe_format formats[] = {
+ PIPE_FORMAT_I16_SNORM,
+ PIPE_FORMAT_R16G16B16A16_SNORM,
+ PIPE_FORMAT_I8_SNORM,
+ PIPE_FORMAT_R8G8B8A8_SNORM,
+ };
+ return find_supported_format(screen, formats, Elements(formats),
+ target, sample_count, bindings);
+ }
+
+ 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);
+ }
+}