aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/docs/GL3.txt4
-rw-r--r--mesalib/docs/application-issues.html83
-rw-r--r--mesalib/docs/contents.html1
-rw-r--r--mesalib/src/gallium/auxiliary/Makefile.sources5
-rw-r--r--mesalib/src/gallium/auxiliary/hud/font.c446
-rw-r--r--mesalib/src/gallium/auxiliary/hud/font.h59
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_context.c1078
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_context.h45
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_cpu.c166
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_driver_query.c210
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_fps.c81
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_private.h92
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c26
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_cpu_detect.c1
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_cpu_detect.h1
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_debug_memory.c55
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format.h1
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_inlines.h4
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_resource.c119
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_resource.h34
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_transfer.c73
-rw-r--r--mesalib/src/glsl/Makefile.sources1
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/glsl_types.cpp2
-rw-r--r--mesalib/src/glsl/ir.cpp5
-rw-r--r--mesalib/src/glsl/ir.h10
-rw-r--r--mesalib/src/glsl/ir_clone.cpp1
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_hv_accept.cpp1
-rw-r--r--mesalib/src/glsl/ir_optimization.h1
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp1
-rw-r--r--mesalib/src/glsl/ir_reader.cpp14
-rw-r--r--mesalib/src/glsl/ir_rvalue_visitor.cpp1
-rw-r--r--mesalib/src/glsl/ir_validate.cpp6
-rw-r--r--mesalib/src/glsl/linker.cpp2
-rw-r--r--mesalib/src/glsl/lower_jumps.cpp4
-rw-r--r--mesalib/src/glsl/lower_ubo_reference.cpp10
-rw-r--r--mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp103
-rw-r--r--mesalib/src/glsl/opt_tree_grafting.cpp1
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml31
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_API.xml4
-rw-r--r--mesalib/src/mesa/drivers/common/driverfuncs.c3
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c18
-rw-r--r--mesalib/src/mesa/drivers/dri/common/Android.mk3
-rw-r--r--mesalib/src/mesa/drivers/dri/common/drirc6
-rw-r--r--mesalib/src/mesa/main/attrib.c9
-rw-r--r--mesalib/src/mesa/main/blend.c82
-rw-r--r--mesalib/src/mesa/main/blend.h14
-rw-r--r--mesalib/src/mesa/main/compiler.h2
-rw-r--r--mesalib/src/mesa/main/extensions.c2
-rw-r--r--mesalib/src/mesa/main/fbobject.c34
-rw-r--r--mesalib/src/mesa/main/formatquery.c15
-rw-r--r--mesalib/src/mesa/main/formatquery.h4
-rw-r--r--mesalib/src/mesa/main/framebuffer.c6
-rw-r--r--mesalib/src/mesa/main/get.c18
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py2
-rw-r--r--mesalib/src/mesa/main/imports.h6
-rw-r--r--mesalib/src/mesa/main/light.c3
-rw-r--r--mesalib/src/mesa/main/mtypes.h18
-rw-r--r--mesalib/src/mesa/main/readpix.c5
-rw-r--r--mesalib/src/mesa/main/shaderapi.c6
-rw-r--r--mesalib/src/mesa/main/state.c51
-rw-r--r--mesalib/src/mesa/main/stencil.c5
-rw-r--r--mesalib/src/mesa/main/texenv.c3
-rw-r--r--mesalib/src/mesa/main/teximage.c67
-rw-r--r--mesalib/src/mesa/main/teximage.h11
-rw-r--r--mesalib/src/mesa/main/texparam.c91
-rw-r--r--mesalib/src/mesa/main/texstorage.c37
-rw-r--r--mesalib/src/mesa/main/texstorage.h3
-rw-r--r--mesalib/src/mesa/main/version.c3
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp3
-rw-r--r--mesalib/src/mesa/program/prog_cache.c11
-rw-r--r--mesalib/src/mesa/program/prog_statevars.c8
-rw-r--r--mesalib/src/mesa/program/register_allocate.c31
-rw-r--r--mesalib/src/mesa/program/register_allocate.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_constbuf.c8
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_rasterizer.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_shader.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bitmap.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawpixels.c11
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawtex.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_readpixels.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c11
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp9
-rw-r--r--mesalib/src/mesa/state_tracker/st_manager.c5
-rw-r--r--mesalib/src/mesa/swrast/s_blit.c8
90 files changed, 3174 insertions, 270 deletions
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index 640dec24c..d150b0874 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -87,7 +87,7 @@ GL_ARB_vertex_type_2_10_10_10_rev DONE (i965, r600)
GL 4.0:
GLSL 4.0 not started
-GL_ARB_texture_query_lod not started
+GL_ARB_texture_query_lod DONE (i965)
GL_ARB_draw_buffers_blend DONE (i965, r600, softpipe)
GL_ARB_draw_indirect not started
GL_ARB_gpu_shader5 not started
@@ -151,7 +151,7 @@ ARB_shader_storage_buffer_object not started
ARB_stencil_texturing not started
ARB_texture_buffer_range DONE (nv50, nvc0)
ARB_texture_query_levels not started
-ARB_texture_storage_multisample not started
+ARB_texture_storage_multisample DONE (i965)
ARB_texture_view not started
ARB_vertex_attrib_binding not started
diff --git a/mesalib/docs/application-issues.html b/mesalib/docs/application-issues.html
new file mode 100644
index 000000000..6db086585
--- /dev/null
+++ b/mesalib/docs/application-issues.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Application Issues</title>
+ <link rel="stylesheet" type="text/css" href="mesa.css">
+</head>
+<body>
+
+<div class="header">
+ <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="contents.html"></iframe>
+<div class="content">
+
+<h1>Application Issues</h1>
+
+<p>
+This page documents known issues with some OpenGL applications.
+</p>
+
+
+<h2>Topogun</h2>
+
+<p>
+<a href="http://www.topogun.com/">Topogun</a> for Linux (version 2, at least)
+creates a GLX visual without requesting a depth buffer.
+This causes bad rendering if the OpenGL driver happens to choose a visual
+without a depth buffer.
+</p>
+
+<p>
+Mesa 9.1.2 and later (will) support a DRI configuration option to work around
+this issue.
+Using the <a href="http://dri.freedesktop.org/wiki/DriConf">driconf</a> tool,
+set the "Create all visuals with a depth buffer" option before running Topogun.
+Then, all GLX visuals will be created with a depth buffer.
+</p>
+
+
+<h2>Old OpenGL games</h2>
+
+<p>
+Some old OpenGL games (approx. ten years or older) may crash during
+start-up because of an extension string buffer-overflow problem.
+</p>
+
+<p>
+The problem is a modern OpenGL driver will return a very long string
+for the glGetString(GL_EXTENSIONS) query and if the application
+naively copies the string into a fixed-size buffer it can overflow the
+buffer and crash the application.
+</p>
+
+<p>
+The work-around is to set the MESA_EXTENSION_MAX_YEAR environment variable
+to the approximate release year of the game.
+This will cause the glGetString(GL_EXTENSIONS) query to only report extensions
+older than the given year.
+</p>
+
+<p>
+For example, if the game was released in 2001, do
+<pre>
+export MESA_EXTENSION_MAX_YEAR=2001
+</pre>
+before running the game.
+</p>
+
+
+
+<h2>Viewperf</h2>
+
+<p>
+See the <a href="viewperf.html">Viewperf issues</a> page for a detailed list
+of Viewperf issues.
+</p>
+
+
+</div>
+</body>
+</html>
diff --git a/mesalib/docs/contents.html b/mesalib/docs/contents.html
index 57522992c..50c0d5913 100644
--- a/mesalib/docs/contents.html
+++ b/mesalib/docs/contents.html
@@ -71,6 +71,7 @@
<li><a href="llvmpipe.html" target="_parent">Gallium llvmpipe driver</a>
<li><a href="vmware-guest.html" target="_parent">VMware SVGA3D guest driver</a>
<li><a href="postprocess.html" target="_parent">Gallium post-processing</a>
+<li><a href="application-issues.html" target="_parent">Application Issues</a>
<li><a href="viewperf.html" target="_parent">Viewperf Issues</a>
</ul>
diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources
index 898abe024..79def2177 100644
--- a/mesalib/src/gallium/auxiliary/Makefile.sources
+++ b/mesalib/src/gallium/auxiliary/Makefile.sources
@@ -37,6 +37,11 @@ C_SOURCES := \
draw/draw_vs.c \
draw/draw_vs_exec.c \
draw/draw_vs_variant.c \
+ hud/font.c \
+ hud/hud_context.c \
+ hud/hud_cpu.c \
+ hud/hud_fps.c \
+ hud/hud_driver_query.c \
os/os_misc.c \
os/os_time.c \
pipebuffer/pb_buffer_fenced.c \
diff --git a/mesalib/src/gallium/auxiliary/hud/font.c b/mesalib/src/gallium/auxiliary/hud/font.c
new file mode 100644
index 000000000..6747874ee
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/font.c
@@ -0,0 +1,446 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+/* This is the "8_BY_13" font extracted from freeglut. */
+
+/*
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Creation date: Thu Dec 16 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA 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 "hud/font.h"
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+#include "util/u_inlines.h"
+
+typedef unsigned char GLubyte; /* 1-byte unsigned */
+typedef struct tagSFG_Font SFG_Font;
+
+struct tagSFG_Font
+{
+ char* Name; /* The source font name */
+ int Quantity; /* Number of chars in font */
+ int Height; /* Height of the characters */
+ const GLubyte** Characters; /* The characters mapping */
+
+ float xorig, yorig; /* Relative origin of the character */
+};
+
+static const GLubyte Fixed8x13_Character_000[] = { 8, 0, 0, 0,170, 0,130, 0,130, 0,130, 0,170, 0, 0};
+static const GLubyte Fixed8x13_Character_001[] = { 8, 0, 0, 0, 0, 16, 56,124,254,124, 56, 16, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_002[] = { 8, 0,170, 85,170, 85,170, 85,170, 85,170, 85,170, 85,170};
+static const GLubyte Fixed8x13_Character_003[] = { 8, 0, 0, 0, 4, 4, 4, 4,174,160,224,160,160, 0, 0};
+static const GLubyte Fixed8x13_Character_004[] = { 8, 0, 0, 0, 8, 8, 12, 8,142,128,192,128,224, 0, 0};
+static const GLubyte Fixed8x13_Character_005[] = { 8, 0, 0, 0, 10, 10, 12, 10,108,128,128,128, 96, 0, 0};
+static const GLubyte Fixed8x13_Character_006[] = { 8, 0, 0, 0, 8, 8, 12, 8,238,128,128,128,128, 0, 0};
+static const GLubyte Fixed8x13_Character_007[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 24, 36, 36, 24, 0, 0};
+static const GLubyte Fixed8x13_Character_008[] = { 8, 0, 0, 0, 0,124, 0, 16, 16,124, 16, 16, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_009[] = { 8, 0, 0, 0, 14, 8, 8, 8,168,160,160,160,192, 0, 0};
+static const GLubyte Fixed8x13_Character_010[] = { 8, 0, 0, 0, 4, 4, 4, 4, 46, 80, 80,136,136, 0, 0};
+static const GLubyte Fixed8x13_Character_011[] = { 8, 0, 0, 0, 0, 0, 0, 0,240, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_012[] = { 8, 0, 16, 16, 16, 16, 16, 16,240, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_013[] = { 8, 0, 16, 16, 16, 16, 16, 16, 31, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_014[] = { 8, 0, 0, 0, 0, 0, 0, 0, 31, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_015[] = { 8, 0, 16, 16, 16, 16, 16, 16,255, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_016[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255};
+static const GLubyte Fixed8x13_Character_017[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_018[] = { 8, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_019[] = { 8, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_020[] = { 8, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_021[] = { 8, 0, 16, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_022[] = { 8, 0, 16, 16, 16, 16, 16, 16,240, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_023[] = { 8, 0, 0, 0, 0, 0, 0, 0,255, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_024[] = { 8, 0, 16, 16, 16, 16, 16, 16,255, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_025[] = { 8, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
+static const GLubyte Fixed8x13_Character_026[] = { 8, 0, 0, 0,254, 0, 14, 48,192, 48, 14, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_027[] = { 8, 0, 0, 0,254, 0,224, 24, 6, 24,224, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_028[] = { 8, 0, 0, 0, 68, 68, 68, 68, 68,254, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_029[] = { 8, 0, 0, 0, 32, 32,126, 16, 8,126, 4, 4, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_030[] = { 8, 0, 0, 0,220, 98, 32, 32, 32,112, 32, 34, 28, 0, 0};
+static const GLubyte Fixed8x13_Character_031[] = { 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_032[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_033[] = { 8, 0, 0, 0, 16, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_034[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36, 0, 0};
+static const GLubyte Fixed8x13_Character_035[] = { 8, 0, 0, 0, 0, 36, 36,126, 36,126, 36, 36, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_036[] = { 8, 0, 0, 0, 16,120, 20, 20, 56, 80, 80, 60, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_037[] = { 8, 0, 0, 0, 68, 42, 36, 16, 8, 8, 36, 82, 34, 0, 0};
+static const GLubyte Fixed8x13_Character_038[] = { 8, 0, 0, 0, 58, 68, 74, 48, 72, 72, 48, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_039[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 48, 56, 0, 0};
+static const GLubyte Fixed8x13_Character_040[] = { 8, 0, 0, 0, 4, 8, 8, 16, 16, 16, 8, 8, 4, 0, 0};
+static const GLubyte Fixed8x13_Character_041[] = { 8, 0, 0, 0, 32, 16, 16, 8, 8, 8, 16, 16, 32, 0, 0};
+static const GLubyte Fixed8x13_Character_042[] = { 8, 0, 0, 0, 0, 0, 36, 24,126, 24, 36, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_043[] = { 8, 0, 0, 0, 0, 0, 16, 16,124, 16, 16, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_044[] = { 8, 0, 0, 64, 48, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_045[] = { 8, 0, 0, 0, 0, 0, 0, 0,126, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_046[] = { 8, 0, 0, 16, 56, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_047[] = { 8, 0, 0, 0,128,128, 64, 32, 16, 8, 4, 2, 2, 0, 0};
+static const GLubyte Fixed8x13_Character_048[] = { 8, 0, 0, 0, 24, 36, 66, 66, 66, 66, 66, 36, 24, 0, 0};
+static const GLubyte Fixed8x13_Character_049[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16, 80, 48, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_050[] = { 8, 0, 0, 0,126, 64, 32, 24, 4, 2, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_051[] = { 8, 0, 0, 0, 60, 66, 2, 2, 28, 8, 4, 2,126, 0, 0};
+static const GLubyte Fixed8x13_Character_052[] = { 8, 0, 0, 0, 4, 4,126, 68, 68, 36, 20, 12, 4, 0, 0};
+static const GLubyte Fixed8x13_Character_053[] = { 8, 0, 0, 0, 60, 66, 2, 2, 98, 92, 64, 64,126, 0, 0};
+static const GLubyte Fixed8x13_Character_054[] = { 8, 0, 0, 0, 60, 66, 66, 98, 92, 64, 64, 32, 28, 0, 0};
+static const GLubyte Fixed8x13_Character_055[] = { 8, 0, 0, 0, 32, 32, 16, 16, 8, 8, 4, 2,126, 0, 0};
+static const GLubyte Fixed8x13_Character_056[] = { 8, 0, 0, 0, 60, 66, 66, 66, 60, 66, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_057[] = { 8, 0, 0, 0, 56, 4, 2, 2, 58, 70, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_058[] = { 8, 0, 0, 16, 56, 16, 0, 0, 16, 56, 16, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_059[] = { 8, 0, 0, 64, 48, 56, 0, 0, 16, 56, 16, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_060[] = { 8, 0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0};
+static const GLubyte Fixed8x13_Character_061[] = { 8, 0, 0, 0, 0, 0,126, 0, 0,126, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_062[] = { 8, 0, 0, 0, 64, 32, 16, 8, 4, 8, 16, 32, 64, 0, 0};
+static const GLubyte Fixed8x13_Character_063[] = { 8, 0, 0, 0, 8, 0, 8, 8, 4, 2, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_064[] = { 8, 0, 0, 0, 60, 64, 74, 86, 82, 78, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_065[] = { 8, 0, 0, 0, 66, 66, 66,126, 66, 66, 66, 36, 24, 0, 0};
+static const GLubyte Fixed8x13_Character_066[] = { 8, 0, 0, 0,252, 66, 66, 66,124, 66, 66, 66,252, 0, 0};
+static const GLubyte Fixed8x13_Character_067[] = { 8, 0, 0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_068[] = { 8, 0, 0, 0,252, 66, 66, 66, 66, 66, 66, 66,252, 0, 0};
+static const GLubyte Fixed8x13_Character_069[] = { 8, 0, 0, 0,126, 64, 64, 64,120, 64, 64, 64,126, 0, 0};
+static const GLubyte Fixed8x13_Character_070[] = { 8, 0, 0, 0, 64, 64, 64, 64,120, 64, 64, 64,126, 0, 0};
+static const GLubyte Fixed8x13_Character_071[] = { 8, 0, 0, 0, 58, 70, 66, 78, 64, 64, 64, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_072[] = { 8, 0, 0, 0, 66, 66, 66, 66,126, 66, 66, 66, 66, 0, 0};
+static const GLubyte Fixed8x13_Character_073[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16, 16, 16,124, 0, 0};
+static const GLubyte Fixed8x13_Character_074[] = { 8, 0, 0, 0, 56, 68, 4, 4, 4, 4, 4, 4, 31, 0, 0};
+static const GLubyte Fixed8x13_Character_075[] = { 8, 0, 0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 0, 0};
+static const GLubyte Fixed8x13_Character_076[] = { 8, 0, 0, 0,126, 64, 64, 64, 64, 64, 64, 64, 64, 0, 0};
+static const GLubyte Fixed8x13_Character_077[] = { 8, 0, 0, 0,130,130,130,146,146,170,198,130,130, 0, 0};
+static const GLubyte Fixed8x13_Character_078[] = { 8, 0, 0, 0, 66, 66, 66, 70, 74, 82, 98, 66, 66, 0, 0};
+static const GLubyte Fixed8x13_Character_079[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_080[] = { 8, 0, 0, 0, 64, 64, 64, 64,124, 66, 66, 66,124, 0, 0};
+static const GLubyte Fixed8x13_Character_081[] = { 8, 0, 0, 2, 60, 74, 82, 66, 66, 66, 66, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_082[] = { 8, 0, 0, 0, 66, 68, 72, 80,124, 66, 66, 66,124, 0, 0};
+static const GLubyte Fixed8x13_Character_083[] = { 8, 0, 0, 0, 60, 66, 2, 2, 60, 64, 64, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_084[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,254, 0, 0};
+static const GLubyte Fixed8x13_Character_085[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 0, 0};
+static const GLubyte Fixed8x13_Character_086[] = { 8, 0, 0, 0, 16, 40, 40, 40, 68, 68, 68,130,130, 0, 0};
+static const GLubyte Fixed8x13_Character_087[] = { 8, 0, 0, 0, 68,170,146,146,146,130,130,130,130, 0, 0};
+static const GLubyte Fixed8x13_Character_088[] = { 8, 0, 0, 0,130,130, 68, 40, 16, 40, 68,130,130, 0, 0};
+static const GLubyte Fixed8x13_Character_089[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 40, 68,130,130, 0, 0};
+static const GLubyte Fixed8x13_Character_090[] = { 8, 0, 0, 0,126, 64, 64, 32, 16, 8, 4, 2,126, 0, 0};
+static const GLubyte Fixed8x13_Character_091[] = { 8, 0, 0, 0, 60, 32, 32, 32, 32, 32, 32, 32, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_092[] = { 8, 0, 0, 0, 2, 2, 4, 8, 16, 32, 64,128,128, 0, 0};
+static const GLubyte Fixed8x13_Character_093[] = { 8, 0, 0, 0,120, 8, 8, 8, 8, 8, 8, 8,120, 0, 0};
+static const GLubyte Fixed8x13_Character_094[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 40, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_095[] = { 8, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_096[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 56, 0, 0};
+static const GLubyte Fixed8x13_Character_097[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_098[] = { 8, 0, 0, 0, 92, 98, 66, 66, 98, 92, 64, 64, 64, 0, 0};
+static const GLubyte Fixed8x13_Character_099[] = { 8, 0, 0, 0, 60, 66, 64, 64, 66, 60, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_100[] = { 8, 0, 0, 0, 58, 70, 66, 66, 70, 58, 2, 2, 2, 0, 0};
+static const GLubyte Fixed8x13_Character_101[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_102[] = { 8, 0, 0, 0, 32, 32, 32, 32,124, 32, 32, 34, 28, 0, 0};
+static const GLubyte Fixed8x13_Character_103[] = { 8, 0, 60, 66, 60, 64, 56, 68, 68, 58, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_104[] = { 8, 0, 0, 0, 66, 66, 66, 66, 98, 92, 64, 64, 64, 0, 0};
+static const GLubyte Fixed8x13_Character_105[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 16, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_106[] = { 8, 0, 56, 68, 68, 4, 4, 4, 4, 12, 0, 4, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_107[] = { 8, 0, 0, 0, 66, 68, 72,112, 72, 68, 64, 64, 64, 0, 0};
+static const GLubyte Fixed8x13_Character_108[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16, 16, 16, 48, 0, 0};
+static const GLubyte Fixed8x13_Character_109[] = { 8, 0, 0, 0,130,146,146,146,146,236, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_110[] = { 8, 0, 0, 0, 66, 66, 66, 66, 98, 92, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_111[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_112[] = { 8, 0, 64, 64, 64, 92, 98, 66, 98, 92, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_113[] = { 8, 0, 2, 2, 2, 58, 70, 66, 70, 58, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_114[] = { 8, 0, 0, 0, 32, 32, 32, 32, 34, 92, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_115[] = { 8, 0, 0, 0, 60, 66, 12, 48, 66, 60, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_116[] = { 8, 0, 0, 0, 28, 34, 32, 32, 32,124, 32, 32, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_117[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_118[] = { 8, 0, 0, 0, 16, 40, 40, 68, 68, 68, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_119[] = { 8, 0, 0, 0, 68,170,146,146,130,130, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_120[] = { 8, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_121[] = { 8, 0, 60, 66, 2, 58, 70, 66, 66, 66, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_122[] = { 8, 0, 0, 0,126, 32, 16, 8, 4,126, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_123[] = { 8, 0, 0, 0, 14, 16, 16, 8, 48, 8, 16, 16, 14, 0, 0};
+static const GLubyte Fixed8x13_Character_124[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_125[] = { 8, 0, 0, 0,112, 8, 8, 16, 12, 16, 8, 8,112, 0, 0};
+static const GLubyte Fixed8x13_Character_126[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 84, 36, 0, 0};
+static const GLubyte Fixed8x13_Character_127[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_128[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_129[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_130[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_131[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_132[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_133[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_134[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_135[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_136[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_137[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_138[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_139[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_140[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_141[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_142[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_143[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_144[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_145[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_146[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_147[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_148[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_149[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_150[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_151[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_152[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_153[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_154[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_155[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_156[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_157[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_158[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_159[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_160[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_161[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_162[] = { 8, 0, 0, 0, 0, 16, 56, 84, 80, 80, 84, 56, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_163[] = { 8, 0, 0, 0,220, 98, 32, 32, 32,112, 32, 34, 28, 0, 0};
+static const GLubyte Fixed8x13_Character_164[] = { 8, 0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_165[] = { 8, 0, 0, 0, 16, 16,124, 16,124, 40, 68,130,130, 0, 0};
+static const GLubyte Fixed8x13_Character_166[] = { 8, 0, 0, 0, 16, 16, 16, 16, 0, 16, 16, 16, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_167[] = { 8, 0, 0, 0, 24, 36, 4, 24, 36, 36, 24, 32, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_168[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108, 0, 0};
+static const GLubyte Fixed8x13_Character_169[] = { 8, 0, 0, 0, 0, 56, 68,146,170,162,170,146, 68, 56, 0};
+static const GLubyte Fixed8x13_Character_170[] = { 8, 0, 0, 0, 0, 0,124, 0, 60, 68, 60, 4, 56, 0, 0};
+static const GLubyte Fixed8x13_Character_171[] = { 8, 0, 0, 0, 0, 18, 36, 72,144, 72, 36, 18, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_172[] = { 8, 0, 0, 0, 0, 2, 2, 2,126, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_173[] = { 8, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_174[] = { 8, 0, 0, 0, 0, 56, 68,170,178,170,170,146, 68, 56, 0};
+static const GLubyte Fixed8x13_Character_175[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0, 0};
+static const GLubyte Fixed8x13_Character_176[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 24, 36, 36, 24, 0, 0};
+static const GLubyte Fixed8x13_Character_177[] = { 8, 0, 0, 0, 0,124, 0, 16, 16,124, 16, 16, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_178[] = { 8, 0, 0, 0, 0, 0, 0, 0,120, 64, 48, 8, 72, 48, 0};
+static const GLubyte Fixed8x13_Character_179[] = { 8, 0, 0, 0, 0, 0, 0, 0, 48, 72, 8, 16, 72, 48, 0};
+static const GLubyte Fixed8x13_Character_180[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_181[] = { 8, 0, 0, 64, 90,102, 66, 66, 66, 66, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_182[] = { 8, 0, 0, 0, 20, 20, 20, 20, 52,116,116,116, 62, 0, 0};
+static const GLubyte Fixed8x13_Character_183[] = { 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_184[] = { 8, 0, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_185[] = { 8, 0, 0, 0, 0, 0, 0, 0,112, 32, 32, 32, 96, 32, 0};
+static const GLubyte Fixed8x13_Character_186[] = { 8, 0, 0, 0, 0, 0, 0,120, 0, 48, 72, 72, 48, 0, 0};
+static const GLubyte Fixed8x13_Character_187[] = { 8, 0, 0, 0, 0,144, 72, 36, 18, 36, 72,144, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_188[] = { 8, 0, 0, 0, 6, 26, 18, 10,230, 66, 64, 64,192, 64, 0};
+static const GLubyte Fixed8x13_Character_189[] = { 8, 0, 0, 0, 30, 16, 12, 2,242, 76, 64, 64,192, 64, 0};
+static const GLubyte Fixed8x13_Character_190[] = { 8, 0, 0, 0, 6, 26, 18, 10,102,146, 16, 32,144, 96, 0};
+static const GLubyte Fixed8x13_Character_191[] = { 8, 0, 0, 0, 60, 66, 66, 64, 32, 16, 16, 0, 16, 0, 0};
+static const GLubyte Fixed8x13_Character_192[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 8, 16, 0};
+static const GLubyte Fixed8x13_Character_193[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_194[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_195[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 76, 50, 0};
+static const GLubyte Fixed8x13_Character_196[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 36, 36, 0};
+static const GLubyte Fixed8x13_Character_197[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 24, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_198[] = { 8, 0, 0, 0,158,144,144,240,156,144,144,144,110, 0, 0};
+static const GLubyte Fixed8x13_Character_199[] = { 8, 0, 16, 8, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0};
+static const GLubyte Fixed8x13_Character_200[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 8, 16, 0};
+static const GLubyte Fixed8x13_Character_201[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_202[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_203[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 36, 36, 0};
+static const GLubyte Fixed8x13_Character_204[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 16, 32, 0};
+static const GLubyte Fixed8x13_Character_205[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_206[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_207[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 40, 40, 0};
+static const GLubyte Fixed8x13_Character_208[] = { 8, 0, 0, 0,120, 68, 66, 66,226, 66, 66, 68,120, 0, 0};
+static const GLubyte Fixed8x13_Character_209[] = { 8, 0, 0, 0,130,134,138,146,162,194,130, 0,152,100, 0};
+static const GLubyte Fixed8x13_Character_210[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 16, 32, 0};
+static const GLubyte Fixed8x13_Character_211[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_212[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_213[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0,152,100, 0};
+static const GLubyte Fixed8x13_Character_214[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 40, 40, 0};
+static const GLubyte Fixed8x13_Character_215[] = { 8, 0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_216[] = { 8, 0, 0, 64, 60, 98, 82, 82, 82, 74, 74, 70, 60, 2, 0};
+static const GLubyte Fixed8x13_Character_217[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 8, 16, 0};
+static const GLubyte Fixed8x13_Character_218[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_219[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_220[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 36, 36, 0};
+static const GLubyte Fixed8x13_Character_221[] = { 8, 0, 0, 0, 16, 16, 16, 16, 40, 68, 68, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_222[] = { 8, 0, 0, 0, 64, 64, 64,124, 66, 66, 66,124, 64, 0, 0};
+static const GLubyte Fixed8x13_Character_223[] = { 8, 0, 0, 0, 92, 66, 66, 76, 80, 72, 68, 68, 56, 0, 0};
+static const GLubyte Fixed8x13_Character_224[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 8, 16, 0};
+static const GLubyte Fixed8x13_Character_225[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 8, 4, 0};
+static const GLubyte Fixed8x13_Character_226[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_227[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 76, 50, 0};
+static const GLubyte Fixed8x13_Character_228[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 36, 36, 0};
+static const GLubyte Fixed8x13_Character_229[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 24, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_230[] = { 8, 0, 0, 0,108,146,144,124, 18,108, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_231[] = { 8, 0, 16, 8, 60, 66, 64, 64, 66, 60, 0, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_232[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 8, 16, 0};
+static const GLubyte Fixed8x13_Character_233[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_234[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_235[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 36, 36, 0};
+static const GLubyte Fixed8x13_Character_236[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 16, 32, 0};
+static const GLubyte Fixed8x13_Character_237[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 32, 16, 0};
+static const GLubyte Fixed8x13_Character_238[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 72, 48, 0};
+static const GLubyte Fixed8x13_Character_239[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 40, 40, 0};
+static const GLubyte Fixed8x13_Character_240[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 4, 40, 24, 36, 0};
+static const GLubyte Fixed8x13_Character_241[] = { 8, 0, 0, 0, 66, 66, 66, 66, 98, 92, 0, 0, 76, 50, 0};
+static const GLubyte Fixed8x13_Character_242[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 16, 32, 0};
+static const GLubyte Fixed8x13_Character_243[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_244[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_245[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 76, 50, 0};
+static const GLubyte Fixed8x13_Character_246[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 36, 36, 0};
+static const GLubyte Fixed8x13_Character_247[] = { 8, 0, 0, 0, 0, 16, 16, 0,124, 0, 16, 16, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_248[] = { 8, 0, 0, 64, 60, 98, 82, 74, 70, 60, 2, 0, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_249[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 16, 32, 0};
+static const GLubyte Fixed8x13_Character_250[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_251[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 36, 24, 0};
+static const GLubyte Fixed8x13_Character_252[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 40, 40, 0};
+static const GLubyte Fixed8x13_Character_253[] = { 8, 0, 60, 66, 2, 58, 70, 66, 66, 66, 0, 0, 16, 8, 0};
+static const GLubyte Fixed8x13_Character_254[] = { 8, 0, 64, 64, 92, 98, 66, 66, 98, 92, 64, 64, 0, 0, 0};
+static const GLubyte Fixed8x13_Character_255[] = { 8, 0, 60, 66, 2, 58, 70, 66, 66, 66, 0, 0, 36, 36, 0};
+
+/* The font characters mapping: */
+static const GLubyte* Fixed8x13_Character_Map[] = {Fixed8x13_Character_000,Fixed8x13_Character_001,Fixed8x13_Character_002,Fixed8x13_Character_003,Fixed8x13_Character_004,Fixed8x13_Character_005,Fixed8x13_Character_006,Fixed8x13_Character_007,Fixed8x13_Character_008,Fixed8x13_Character_009,Fixed8x13_Character_010,Fixed8x13_Character_011,Fixed8x13_Character_012,Fixed8x13_Character_013,Fixed8x13_Character_014,Fixed8x13_Character_015,
+ Fixed8x13_Character_016,Fixed8x13_Character_017,Fixed8x13_Character_018,Fixed8x13_Character_019,Fixed8x13_Character_020,Fixed8x13_Character_021,Fixed8x13_Character_022,Fixed8x13_Character_023,Fixed8x13_Character_024,Fixed8x13_Character_025,Fixed8x13_Character_026,Fixed8x13_Character_027,Fixed8x13_Character_028,Fixed8x13_Character_029,Fixed8x13_Character_030,Fixed8x13_Character_031,
+ Fixed8x13_Character_032,Fixed8x13_Character_033,Fixed8x13_Character_034,Fixed8x13_Character_035,Fixed8x13_Character_036,Fixed8x13_Character_037,Fixed8x13_Character_038,Fixed8x13_Character_039,Fixed8x13_Character_040,Fixed8x13_Character_041,Fixed8x13_Character_042,Fixed8x13_Character_043,Fixed8x13_Character_044,Fixed8x13_Character_045,Fixed8x13_Character_046,Fixed8x13_Character_047,
+ Fixed8x13_Character_048,Fixed8x13_Character_049,Fixed8x13_Character_050,Fixed8x13_Character_051,Fixed8x13_Character_052,Fixed8x13_Character_053,Fixed8x13_Character_054,Fixed8x13_Character_055,Fixed8x13_Character_056,Fixed8x13_Character_057,Fixed8x13_Character_058,Fixed8x13_Character_059,Fixed8x13_Character_060,Fixed8x13_Character_061,Fixed8x13_Character_062,Fixed8x13_Character_063,
+ Fixed8x13_Character_064,Fixed8x13_Character_065,Fixed8x13_Character_066,Fixed8x13_Character_067,Fixed8x13_Character_068,Fixed8x13_Character_069,Fixed8x13_Character_070,Fixed8x13_Character_071,Fixed8x13_Character_072,Fixed8x13_Character_073,Fixed8x13_Character_074,Fixed8x13_Character_075,Fixed8x13_Character_076,Fixed8x13_Character_077,Fixed8x13_Character_078,Fixed8x13_Character_079,
+ Fixed8x13_Character_080,Fixed8x13_Character_081,Fixed8x13_Character_082,Fixed8x13_Character_083,Fixed8x13_Character_084,Fixed8x13_Character_085,Fixed8x13_Character_086,Fixed8x13_Character_087,Fixed8x13_Character_088,Fixed8x13_Character_089,Fixed8x13_Character_090,Fixed8x13_Character_091,Fixed8x13_Character_092,Fixed8x13_Character_093,Fixed8x13_Character_094,Fixed8x13_Character_095,
+ Fixed8x13_Character_096,Fixed8x13_Character_097,Fixed8x13_Character_098,Fixed8x13_Character_099,Fixed8x13_Character_100,Fixed8x13_Character_101,Fixed8x13_Character_102,Fixed8x13_Character_103,Fixed8x13_Character_104,Fixed8x13_Character_105,Fixed8x13_Character_106,Fixed8x13_Character_107,Fixed8x13_Character_108,Fixed8x13_Character_109,Fixed8x13_Character_110,Fixed8x13_Character_111,
+ Fixed8x13_Character_112,Fixed8x13_Character_113,Fixed8x13_Character_114,Fixed8x13_Character_115,Fixed8x13_Character_116,Fixed8x13_Character_117,Fixed8x13_Character_118,Fixed8x13_Character_119,Fixed8x13_Character_120,Fixed8x13_Character_121,Fixed8x13_Character_122,Fixed8x13_Character_123,Fixed8x13_Character_124,Fixed8x13_Character_125,Fixed8x13_Character_126,Fixed8x13_Character_032,
+ Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,
+ Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,
+ Fixed8x13_Character_160,Fixed8x13_Character_161,Fixed8x13_Character_162,Fixed8x13_Character_163,Fixed8x13_Character_164,Fixed8x13_Character_165,Fixed8x13_Character_166,Fixed8x13_Character_167,Fixed8x13_Character_168,Fixed8x13_Character_169,Fixed8x13_Character_170,Fixed8x13_Character_171,Fixed8x13_Character_172,Fixed8x13_Character_173,Fixed8x13_Character_174,Fixed8x13_Character_175,
+ Fixed8x13_Character_176,Fixed8x13_Character_177,Fixed8x13_Character_178,Fixed8x13_Character_179,Fixed8x13_Character_180,Fixed8x13_Character_181,Fixed8x13_Character_182,Fixed8x13_Character_183,Fixed8x13_Character_184,Fixed8x13_Character_185,Fixed8x13_Character_186,Fixed8x13_Character_187,Fixed8x13_Character_188,Fixed8x13_Character_189,Fixed8x13_Character_190,Fixed8x13_Character_191,
+ Fixed8x13_Character_192,Fixed8x13_Character_193,Fixed8x13_Character_194,Fixed8x13_Character_195,Fixed8x13_Character_196,Fixed8x13_Character_197,Fixed8x13_Character_198,Fixed8x13_Character_199,Fixed8x13_Character_200,Fixed8x13_Character_201,Fixed8x13_Character_202,Fixed8x13_Character_203,Fixed8x13_Character_204,Fixed8x13_Character_205,Fixed8x13_Character_206,Fixed8x13_Character_207,
+ Fixed8x13_Character_208,Fixed8x13_Character_209,Fixed8x13_Character_210,Fixed8x13_Character_211,Fixed8x13_Character_212,Fixed8x13_Character_213,Fixed8x13_Character_214,Fixed8x13_Character_215,Fixed8x13_Character_216,Fixed8x13_Character_217,Fixed8x13_Character_218,Fixed8x13_Character_219,Fixed8x13_Character_220,Fixed8x13_Character_221,Fixed8x13_Character_222,Fixed8x13_Character_223,
+ Fixed8x13_Character_224,Fixed8x13_Character_225,Fixed8x13_Character_226,Fixed8x13_Character_227,Fixed8x13_Character_228,Fixed8x13_Character_229,Fixed8x13_Character_230,Fixed8x13_Character_231,Fixed8x13_Character_232,Fixed8x13_Character_233,Fixed8x13_Character_234,Fixed8x13_Character_235,Fixed8x13_Character_236,Fixed8x13_Character_237,Fixed8x13_Character_238,Fixed8x13_Character_239,
+ Fixed8x13_Character_240,Fixed8x13_Character_241,Fixed8x13_Character_242,Fixed8x13_Character_243,Fixed8x13_Character_244,Fixed8x13_Character_245,Fixed8x13_Character_246,Fixed8x13_Character_247,Fixed8x13_Character_248,Fixed8x13_Character_249,Fixed8x13_Character_250,Fixed8x13_Character_251,Fixed8x13_Character_252,Fixed8x13_Character_253,Fixed8x13_Character_254,Fixed8x13_Character_255,NULL};
+
+/* The font structure: */
+static const SFG_Font fgFontFixed8x13 = { "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", 256, 14, Fixed8x13_Character_Map, 0, 3 };
+
+
+static void
+util_font_draw_character(void *dst_mem, unsigned dst_stride, unsigned character)
+{
+ unsigned char *dst = (unsigned char*)dst_mem;
+ const SFG_Font *font = &fgFontFixed8x13;
+ unsigned width = font->Characters[character][0];
+ unsigned bitmap_stride = (width + 7) / 8;
+ unsigned j,i;
+ const GLubyte *bitmap = font->Characters[character]+1 + bitmap_stride * (font->Height - 1);
+
+ for (j = 0; j < font->Height; j++) {
+ for (i = 0; i < width; i++) {
+ dst[i] = bitmap[i/8] & (128 >> (i%8)) ? 0xff : 0;
+ }
+ dst += dst_stride;
+ bitmap -= bitmap_stride;
+ }
+}
+
+static boolean
+util_font_create_fixed_8x13(struct pipe_context *pipe,
+ struct util_font *out_font)
+{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_resource tex_templ, *tex;
+ struct pipe_transfer *transfer = NULL;
+ char *map;
+ enum pipe_format tex_format;
+ int i;
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
+ PIPE_TEXTURE_RECT, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ tex_format = PIPE_FORMAT_I8_UNORM;
+ }
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM,
+ PIPE_TEXTURE_RECT, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ tex_format = PIPE_FORMAT_L8_UNORM;
+ }
+ else {
+ return FALSE;
+ }
+
+ memset(&tex_templ, 0, sizeof(tex_templ));
+ tex_templ.target = PIPE_TEXTURE_RECT;
+ tex_templ.format = tex_format;
+ tex_templ.width0 = 128;
+ tex_templ.height0 = 256;
+ tex_templ.depth0 = 1;
+ tex_templ.array_size = 1;
+ tex_templ.usage = PIPE_USAGE_STATIC;
+ tex_templ.bind = PIPE_BIND_SAMPLER_VIEW;
+
+ tex = screen->resource_create(screen, &tex_templ);
+ if (!tex) {
+ return FALSE;
+ }
+
+ map = pipe_transfer_map(pipe, tex, 0, 0, PIPE_TRANSFER_WRITE, 0, 0,
+ tex->width0, tex->height0, &transfer);
+ if (!map) {
+ pipe_resource_reference(&tex, NULL);
+ return FALSE;
+ }
+
+ for (i = 0; i < 256; i++) {
+ int x = (i % 16) * 8;
+ int y = (i / 16) * 14;
+
+ util_font_draw_character(map + y * transfer->stride + x,
+ transfer->stride, i);
+ }
+
+ pipe_transfer_unmap(pipe, transfer);
+
+ pipe_resource_reference(&out_font->texture, NULL);
+ out_font->texture = tex;
+ out_font->glyph_width = 8;
+ out_font->glyph_height = 14;
+ return TRUE;
+}
+
+
+boolean
+util_font_create(struct pipe_context *pipe, enum util_font_name name,
+ struct util_font *out_font)
+{
+ switch (name) {
+ case UTIL_FONT_FIXED_8X13:
+ return util_font_create_fixed_8x13(pipe, out_font);
+ }
+ return FALSE;
+}
diff --git a/mesalib/src/gallium/auxiliary/hud/font.h b/mesalib/src/gallium/auxiliary/hud/font.h
new file mode 100644
index 000000000..cf1c87984
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/font.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+#ifndef FONT_H
+#define FONT_H
+
+#include "pipe/p_compiler.h"
+
+struct pipe_resource;
+struct pipe_context;
+
+enum util_font_name {
+ UTIL_FONT_FIXED_8X13
+};
+
+/* The font is stored in a RECT texture. There are 256 glyphs
+ * drawn in a 16x16 matrix. The texture coordinates of a glyph
+ * within the matrix should be calculated as follows:
+ *
+ * x1 = (glyph % 16) * glyph_width;
+ * y1 = (glyph / 16) * glyph_height;
+ * x2 = x1 + glyph_width;
+ * y2 = y1 + glyph_height;
+ */
+struct util_font {
+ struct pipe_resource *texture;
+ unsigned glyph_width;
+ unsigned glyph_height;
+};
+
+boolean
+util_font_create(struct pipe_context *pipe, enum util_font_name name,
+ struct util_font *out_font);
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_context.c b/mesalib/src/gallium/auxiliary/hud/hud_context.c
new file mode 100644
index 000000000..983f05756
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/hud_context.c
@@ -0,0 +1,1078 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+/* This head-up display module can draw transparent graphs on top of what
+ * the app is rendering, visualizing various data like framerate, cpu load,
+ * performance counters, etc. It can be hook up into any state tracker.
+ *
+ * The HUD is controlled with the GALLIUM_HUD environment variable.
+ * Set GALLIUM_HUD=help for more info.
+ */
+
+#include "hud/hud_context.h"
+#include "hud/hud_private.h"
+#include "hud/font.h"
+
+#include "cso_cache/cso_context.h"
+#include "util/u_draw_quad.h"
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_string.h"
+#include "util/u_upload_mgr.h"
+#include "tgsi/tgsi_text.h"
+#include "tgsi/tgsi_dump.h"
+
+
+struct hud_context {
+ struct pipe_context *pipe;
+ struct cso_context *cso;
+ struct u_upload_mgr *uploader;
+
+ struct list_head pane_list;
+
+ /* states */
+ struct pipe_blend_state alpha_blend;
+ struct pipe_depth_stencil_alpha_state dsa;
+ void *fs_color, *fs_text;
+ struct pipe_rasterizer_state rasterizer;
+ void *vs;
+ struct pipe_vertex_element velems[2];
+
+ /* font */
+ struct util_font font;
+ struct pipe_sampler_view *font_sampler_view;
+ struct pipe_sampler_state font_sampler_state;
+
+ /* VS constant buffer */
+ struct {
+ float color[4];
+ float two_div_fb_width;
+ float two_div_fb_height;
+ float translate[2];
+ float scale[2];
+ float padding[2];
+ } constants;
+ struct pipe_constant_buffer constbuf;
+
+ unsigned fb_width, fb_height;
+
+ /* vertices for text and background drawing are accumulated here and then
+ * drawn all at once */
+ struct vertex_queue {
+ float *vertices;
+ struct pipe_vertex_buffer vbuf;
+ unsigned max_num_vertices;
+ unsigned num_vertices;
+ } text, bg, whitelines;
+
+ struct {
+ boolean query_pipeline_statistics;
+ } cap;
+};
+
+
+static void
+hud_draw_colored_prims(struct hud_context *hud, unsigned prim,
+ float *buffer, unsigned num_vertices,
+ float r, float g, float b, float a,
+ int xoffset, int yoffset, float yscale)
+{
+ struct cso_context *cso = hud->cso;
+ struct pipe_vertex_buffer vbuffer = {0};
+
+ hud->constants.color[0] = r;
+ hud->constants.color[1] = g;
+ hud->constants.color[2] = b;
+ hud->constants.color[3] = a;
+ hud->constants.translate[0] = xoffset;
+ hud->constants.translate[1] = yoffset;
+ hud->constants.scale[0] = 1;
+ hud->constants.scale[1] = yscale;
+ cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+
+ vbuffer.user_buffer = buffer;
+ vbuffer.stride = 2 * sizeof(float);
+
+ cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso),
+ 1, &vbuffer);
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
+ cso_draw_arrays(cso, prim, 0, num_vertices);
+}
+
+static void
+hud_draw_colored_quad(struct hud_context *hud, unsigned prim,
+ unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ float r, float g, float b, float a)
+{
+ float buffer[] = {
+ x1, y1,
+ x1, y2,
+ x2, y2,
+ x2, y1,
+ };
+
+ hud_draw_colored_prims(hud, prim, buffer, 4, r, g, b, a, 0, 0, 1);
+}
+
+static void
+hud_draw_background_quad(struct hud_context *hud,
+ unsigned x1, unsigned y1, unsigned x2, unsigned y2)
+{
+ float *vertices = hud->bg.vertices + hud->bg.num_vertices*2;
+ unsigned num = 0;
+
+ assert(hud->bg.num_vertices + 4 <= hud->bg.max_num_vertices);
+
+ vertices[num++] = x1;
+ vertices[num++] = y1;
+
+ vertices[num++] = x1;
+ vertices[num++] = y2;
+
+ vertices[num++] = x2;
+ vertices[num++] = y2;
+
+ vertices[num++] = x2;
+ vertices[num++] = y1;
+
+ hud->bg.num_vertices += num/2;
+}
+
+static void
+hud_draw_string(struct hud_context *hud, unsigned x, unsigned y,
+ const char *str, ...)
+{
+ char buf[256];
+ char *s = buf;
+ float *vertices = hud->text.vertices + hud->text.num_vertices*4;
+ unsigned num = 0;
+
+ va_list ap;
+ va_start(ap, str);
+ util_vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+ if (!*s)
+ return;
+
+ hud_draw_background_quad(hud,
+ x, y,
+ x + strlen(buf)*hud->font.glyph_width,
+ y + hud->font.glyph_height);
+
+ while (*s) {
+ unsigned x1 = x;
+ unsigned y1 = y;
+ unsigned x2 = x + hud->font.glyph_width;
+ unsigned y2 = y + hud->font.glyph_height;
+ unsigned tx1 = (*s % 16) * hud->font.glyph_width;
+ unsigned ty1 = (*s / 16) * hud->font.glyph_height;
+ unsigned tx2 = tx1 + hud->font.glyph_width;
+ unsigned ty2 = ty1 + hud->font.glyph_height;
+
+ if (*s == ' ') {
+ x += hud->font.glyph_width;
+ s++;
+ continue;
+ }
+
+ assert(hud->text.num_vertices + num/4 + 4 <= hud->text.max_num_vertices);
+
+ vertices[num++] = x1;
+ vertices[num++] = y1;
+ vertices[num++] = tx1;
+ vertices[num++] = ty1;
+
+ vertices[num++] = x1;
+ vertices[num++] = y2;
+ vertices[num++] = tx1;
+ vertices[num++] = ty2;
+
+ vertices[num++] = x2;
+ vertices[num++] = y2;
+ vertices[num++] = tx2;
+ vertices[num++] = ty2;
+
+ vertices[num++] = x2;
+ vertices[num++] = y1;
+ vertices[num++] = tx2;
+ vertices[num++] = ty1;
+
+ x += hud->font.glyph_width;
+ s++;
+ }
+
+ hud->text.num_vertices += num/4;
+}
+
+static void
+number_to_human_readable(uint64_t num, boolean is_in_bytes, char *out)
+{
+ static const char *byte_units[] =
+ {"", " KB", " MB", " GB", " TB", " PB", " EB"};
+ static const char *metric_units[] =
+ {"", " k", " M", " G", " T", " P", " E"};
+ const char **units = is_in_bytes ? byte_units : metric_units;
+ double divisor = is_in_bytes ? 1024 : 1000;
+ int unit = 0;
+ double d = num;
+
+ while (d > divisor) {
+ d /= divisor;
+ unit++;
+ }
+
+ if (d >= 100 || d == (int)d)
+ sprintf(out, "%.0f%s", d, units[unit]);
+ else if (d >= 10 || d*10 == (int)(d*10))
+ sprintf(out, "%.1f%s", d, units[unit]);
+ else
+ sprintf(out, "%.2f%s", d, units[unit]);
+}
+
+static void
+hud_draw_graph_line_strip(struct hud_context *hud, const struct hud_graph *gr,
+ unsigned xoffset, unsigned yoffset, float yscale)
+{
+ if (gr->num_vertices <= 1)
+ return;
+
+ assert(gr->index <= gr->num_vertices);
+
+ hud_draw_colored_prims(hud, PIPE_PRIM_LINE_STRIP,
+ gr->vertices, gr->index,
+ gr->color[0], gr->color[1], gr->color[2], 1,
+ xoffset + (gr->pane->max_num_vertices - gr->index - 1) * 2 - 1,
+ yoffset, yscale);
+
+ if (gr->num_vertices <= gr->index)
+ return;
+
+ hud_draw_colored_prims(hud, PIPE_PRIM_LINE_STRIP,
+ gr->vertices + gr->index*2,
+ gr->num_vertices - gr->index,
+ gr->color[0], gr->color[1], gr->color[2], 1,
+ xoffset - gr->index*2 - 1, yoffset, yscale);
+}
+
+static void
+hud_pane_accumulate_vertices(struct hud_context *hud,
+ const struct hud_pane *pane)
+{
+ struct hud_graph *gr;
+ float *line_verts = hud->whitelines.vertices + hud->whitelines.num_vertices*2;
+ unsigned i, num = 0;
+ char str[32];
+
+ /* draw background */
+ hud_draw_background_quad(hud,
+ pane->x1, pane->y1,
+ pane->x2, pane->y2);
+
+ /* draw numbers on the right-hand side */
+ for (i = 0; i < 6; i++) {
+ unsigned x = pane->x2 + 2;
+ unsigned y = pane->inner_y1 + pane->inner_height * (5 - i) / 5 -
+ hud->font.glyph_height / 2;
+
+ number_to_human_readable(pane->max_value * i / 5,
+ pane->uses_byte_units, str);
+ hud_draw_string(hud, x, y, str);
+ }
+
+ /* draw info below the pane */
+ i = 0;
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ unsigned x = pane->x1 + 2;
+ unsigned y = pane->y2 + 2 + i*hud->font.glyph_height;
+
+ number_to_human_readable(gr->current_value,
+ pane->uses_byte_units, str);
+ hud_draw_string(hud, x, y, " %s: %s", gr->name, str);
+ i++;
+ }
+
+ /* draw border */
+ assert(hud->whitelines.num_vertices + num/2 + 8 <= hud->whitelines.max_num_vertices);
+ line_verts[num++] = pane->x1;
+ line_verts[num++] = pane->y1;
+ line_verts[num++] = pane->x2;
+ line_verts[num++] = pane->y1;
+
+ line_verts[num++] = pane->x2;
+ line_verts[num++] = pane->y1;
+ line_verts[num++] = pane->x2;
+ line_verts[num++] = pane->y2;
+
+ line_verts[num++] = pane->x1;
+ line_verts[num++] = pane->y2;
+ line_verts[num++] = pane->x2;
+ line_verts[num++] = pane->y2;
+
+ line_verts[num++] = pane->x1;
+ line_verts[num++] = pane->y1;
+ line_verts[num++] = pane->x1;
+ line_verts[num++] = pane->y2;
+
+ /* draw horizontal lines inside the graph */
+ for (i = 0; i <= 5; i++) {
+ float y = round((pane->max_value * i / 5.0) * pane->yscale + pane->inner_y2);
+
+ assert(hud->whitelines.num_vertices + num/2 + 2 <= hud->whitelines.max_num_vertices);
+ line_verts[num++] = pane->x1;
+ line_verts[num++] = y;
+ line_verts[num++] = pane->x2;
+ line_verts[num++] = y;
+ }
+
+ hud->whitelines.num_vertices += num/2;
+}
+
+static void
+hud_pane_draw_colored_objects(struct hud_context *hud,
+ const struct hud_pane *pane)
+{
+ struct hud_graph *gr;
+ unsigned i;
+
+ /* draw colored quads below the pane */
+ i = 0;
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ unsigned x = pane->x1 + 2;
+ unsigned y = pane->y2 + 2 + i*hud->font.glyph_height;
+
+ hud_draw_colored_quad(hud, PIPE_PRIM_QUADS, x + 1, y + 1, x + 12, y + 13,
+ gr->color[0], gr->color[1], gr->color[2], 1);
+ i++;
+ }
+
+ /* draw the line strips */
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ hud_draw_graph_line_strip(hud, gr, pane->inner_x1, pane->inner_y2, pane->yscale);
+ }
+}
+
+static void
+hud_alloc_vertices(struct hud_context *hud, struct vertex_queue *v,
+ unsigned num_vertices, unsigned stride)
+{
+ v->num_vertices = 0;
+ v->max_num_vertices = num_vertices;
+ v->vbuf.stride = stride;
+ u_upload_alloc(hud->uploader, 0, v->vbuf.stride * v->max_num_vertices,
+ &v->vbuf.buffer_offset, &v->vbuf.buffer,
+ (void**)&v->vertices);
+}
+
+/**
+ * Draw the HUD to the texture \p tex.
+ * The texture is usually the back buffer being displayed.
+ */
+void
+hud_draw(struct hud_context *hud, struct pipe_resource *tex)
+{
+ struct cso_context *cso = hud->cso;
+ struct pipe_context *pipe = hud->pipe;
+ struct pipe_framebuffer_state fb;
+ struct pipe_surface surf_templ, *surf;
+ struct pipe_viewport_state viewport;
+ const struct pipe_sampler_state *sampler_states[] =
+ { &hud->font_sampler_state };
+ struct hud_pane *pane;
+ struct hud_graph *gr;
+
+ hud->fb_width = tex->width0;
+ hud->fb_height = tex->height0;
+ hud->constants.two_div_fb_width = 2.0 / hud->fb_width;
+ hud->constants.two_div_fb_height = 2.0 / hud->fb_height;
+
+ cso_save_framebuffer(cso);
+ cso_save_sample_mask(cso);
+ cso_save_blend(cso);
+ cso_save_depth_stencil_alpha(cso);
+ cso_save_fragment_shader(cso);
+ cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
+ cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
+ cso_save_rasterizer(cso);
+ cso_save_viewport(cso);
+ cso_save_stream_outputs(cso);
+ cso_save_geometry_shader(cso);
+ cso_save_vertex_shader(cso);
+ cso_save_vertex_elements(cso);
+ cso_save_aux_vertex_buffer_slot(cso);
+ cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
+ cso_save_render_condition(cso);
+
+ /* set states */
+ memset(&surf_templ, 0, sizeof(surf_templ));
+ surf_templ.format = tex->format;
+ surf = pipe->create_surface(pipe, tex, &surf_templ);
+
+ memset(&fb, 0, sizeof(fb));
+ fb.nr_cbufs = 1;
+ fb.cbufs[0] = surf;
+ fb.zsbuf = NULL;
+ fb.width = hud->fb_width;
+ fb.height = hud->fb_height;
+
+ viewport.scale[0] = 0.5f * hud->fb_width;
+ viewport.scale[1] = 0.5f * hud->fb_height;
+ viewport.scale[2] = 1.0f;
+ viewport.scale[3] = 1.0f;
+ viewport.translate[0] = 0.5f * hud->fb_width;
+ viewport.translate[1] = 0.5f * hud->fb_height;
+ viewport.translate[2] = 0.0f;
+ viewport.translate[3] = 0.0f;
+
+ cso_set_framebuffer(cso, &fb);
+ cso_set_sample_mask(cso, ~0);
+ cso_set_blend(cso, &hud->alpha_blend);
+ cso_set_depth_stencil_alpha(cso, &hud->dsa);
+ cso_set_rasterizer(cso, &hud->rasterizer);
+ cso_set_viewport(cso, &viewport);
+ cso_set_stream_outputs(cso, 0, NULL, 0);
+ cso_set_geometry_shader_handle(cso, NULL);
+ cso_set_vertex_shader_handle(cso, hud->vs);
+ cso_set_vertex_elements(cso, 2, hud->velems);
+ cso_set_render_condition(cso, NULL, 0);
+ cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, 1,
+ &hud->font_sampler_view);
+ cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, sampler_states);
+ cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+
+ /* prepare vertex buffers */
+ hud_alloc_vertices(hud, &hud->bg, 4 * 64, 2 * sizeof(float));
+ hud_alloc_vertices(hud, &hud->whitelines, 4 * 256, 2 * sizeof(float));
+ hud_alloc_vertices(hud, &hud->text, 4 * 512, 4 * sizeof(float));
+
+ /* prepare all graphs */
+ LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ gr->query_new_value(gr);
+ }
+
+ hud_pane_accumulate_vertices(hud, pane);
+ }
+
+ /* unmap the uploader's vertex buffer before drawing */
+ u_upload_flush(hud->uploader);
+
+ /* draw accumulated vertices for background quads */
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
+
+ if (hud->bg.num_vertices) {
+ hud->constants.color[0] = 0;
+ hud->constants.color[1] = 0;
+ hud->constants.color[2] = 0;
+ hud->constants.color[3] = 0.666;
+ hud->constants.translate[0] = 0;
+ hud->constants.translate[1] = 0;
+ hud->constants.scale[0] = 1;
+ hud->constants.scale[1] = 1;
+
+ cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+ cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1,
+ &hud->bg.vbuf);
+ cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->bg.num_vertices);
+ }
+ pipe_resource_reference(&hud->bg.vbuf.buffer, NULL);
+
+ /* draw accumulated vertices for white lines */
+ hud->constants.color[0] = 1;
+ hud->constants.color[1] = 1;
+ hud->constants.color[2] = 1;
+ hud->constants.color[3] = 1;
+ hud->constants.translate[0] = 0;
+ hud->constants.translate[1] = 0;
+ hud->constants.scale[0] = 1;
+ hud->constants.scale[1] = 1;
+ cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+
+ if (hud->whitelines.num_vertices) {
+ cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1,
+ &hud->whitelines.vbuf);
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
+ cso_draw_arrays(cso, PIPE_PRIM_LINES, 0, hud->whitelines.num_vertices);
+ }
+ pipe_resource_reference(&hud->whitelines.vbuf.buffer, NULL);
+
+ /* draw accumulated vertices for text */
+ if (hud->text.num_vertices) {
+ cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1,
+ &hud->text.vbuf);
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_text);
+ cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->text.num_vertices);
+ }
+ pipe_resource_reference(&hud->text.vbuf.buffer, NULL);
+
+ /* draw the rest */
+ LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+ if (pane)
+ hud_pane_draw_colored_objects(hud, pane);
+ }
+
+ /* restore states */
+ cso_restore_framebuffer(cso);
+ cso_restore_sample_mask(cso);
+ cso_restore_blend(cso);
+ cso_restore_depth_stencil_alpha(cso);
+ cso_restore_fragment_shader(cso);
+ cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
+ cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
+ cso_restore_rasterizer(cso);
+ cso_restore_viewport(cso);
+ cso_restore_stream_outputs(cso);
+ cso_restore_geometry_shader(cso);
+ cso_restore_vertex_shader(cso);
+ cso_restore_vertex_elements(cso);
+ cso_restore_aux_vertex_buffer_slot(cso);
+ cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
+ cso_restore_render_condition(cso);
+
+ pipe_surface_reference(&surf, NULL);
+}
+
+/**
+ * Set the maximum value for the Y axis of the graph.
+ * This scales the graph accordingly.
+ */
+void
+hud_pane_set_max_value(struct hud_pane *pane, uint64_t value)
+{
+ pane->max_value = value;
+ pane->yscale = -(int)pane->inner_height / (double)pane->max_value;
+}
+
+static struct hud_pane *
+hud_pane_create(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ unsigned period, uint64_t max_value)
+{
+ struct hud_pane *pane = CALLOC_STRUCT(hud_pane);
+
+ if (!pane)
+ return NULL;
+
+ pane->x1 = x1;
+ pane->y1 = y1;
+ pane->x2 = x2;
+ pane->y2 = y2;
+ pane->inner_x1 = x1 + 1;
+ pane->inner_x2 = x2 - 1;
+ pane->inner_y1 = y1 + 1;
+ pane->inner_y2 = y2 - 1;
+ pane->inner_width = pane->inner_x2 - pane->inner_x1;
+ pane->inner_height = pane->inner_y2 - pane->inner_y1;
+ pane->period = period;
+ pane->max_num_vertices = (x2 - x1 + 2) / 2;
+ hud_pane_set_max_value(pane, max_value);
+ LIST_INITHEAD(&pane->graph_list);
+ return pane;
+}
+
+/**
+ * Add a graph to an existing pane.
+ * One pane can contain multiple graphs over each other.
+ */
+void
+hud_pane_add_graph(struct hud_pane *pane, struct hud_graph *gr)
+{
+ static const float colors[][3] = {
+ {0, 1, 0},
+ {1, 0, 0},
+ {0, 1, 1},
+ {1, 0, 1},
+ {1, 1, 0},
+ {0.5, 0.5, 1},
+ {0.5, 0.5, 0.5},
+ };
+ char *name = gr->name;
+
+ /* replace '-' with a space */
+ while (*name) {
+ if (*name == '-')
+ *name = ' ';
+ name++;
+ }
+
+ assert(pane->num_graphs < Elements(colors));
+ gr->vertices = MALLOC(pane->max_num_vertices * sizeof(float) * 2);
+ gr->color[0] = colors[pane->num_graphs][0];
+ gr->color[1] = colors[pane->num_graphs][1];
+ gr->color[2] = colors[pane->num_graphs][2];
+ gr->pane = pane;
+ LIST_ADDTAIL(&gr->head, &pane->graph_list);
+ pane->num_graphs++;
+}
+
+void
+hud_graph_add_value(struct hud_graph *gr, uint64_t value)
+{
+ if (gr->index == gr->pane->max_num_vertices) {
+ gr->vertices[0] = 0;
+ gr->vertices[1] = gr->vertices[(gr->index-1)*2+1];
+ gr->index = 1;
+ }
+ gr->vertices[(gr->index)*2+0] = gr->index*2;
+ gr->vertices[(gr->index)*2+1] = value;
+ gr->index++;
+
+ if (gr->num_vertices < gr->pane->max_num_vertices) {
+ gr->num_vertices++;
+ }
+
+ gr->current_value = value;
+ if (value > gr->pane->max_value) {
+ hud_pane_set_max_value(gr->pane, value);
+ }
+}
+
+static void
+hud_graph_destroy(struct hud_graph *graph)
+{
+ FREE(graph->vertices);
+ if (graph->free_query_data)
+ graph->free_query_data(graph->query_data);
+ FREE(graph);
+}
+
+/**
+ * Read a string from the environment variable.
+ * The separators "+", ",", ":", and ";" terminate the string.
+ * Return the number of read characters.
+ */
+static int
+parse_string(const char *s, char *out)
+{
+ int i;
+
+ for (i = 0; *s && *s != '+' && *s != ',' && *s != ':' && *s != ';';
+ s++, out++, i++)
+ *out = *s;
+
+ *out = 0;
+
+ if (*s && !i)
+ fprintf(stderr, "gallium_hud: syntax error: unexpected '%c' (%i) while "
+ "parsing a string\n", *s, *s);
+ return i;
+}
+
+static boolean
+has_occlusion_query(struct pipe_screen *screen)
+{
+ return screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY) != 0;
+}
+
+static boolean
+has_streamout(struct pipe_screen *screen)
+{
+ return screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
+}
+
+static void
+hud_parse_env_var(struct hud_context *hud, const char *env)
+{
+ unsigned num, i;
+ char name[256], s[256];
+ struct hud_pane *pane = NULL;
+ unsigned x = 10, y = 10;
+ unsigned width = 251, height = 100;
+ unsigned period = 500 * 1000; /* default period (1/2 second) */
+ const char *period_env;
+
+ /*
+ * The GALLIUM_HUD_PERIOD env var sets the graph update rate.
+ * The env var is in seconds (a float).
+ * Zero means update after every frame.
+ */
+ period_env = getenv("GALLIUM_HUD_PERIOD");
+ if (period_env) {
+ float p = atof(period_env);
+ if (p >= 0.0) {
+ period = (unsigned) (p * 1000 * 1000);
+ }
+ }
+
+ while ((num = parse_string(env, name)) != 0) {
+ env += num;
+
+ if (!pane) {
+ pane = hud_pane_create(x, y, x + width, y + height, period, 10);
+ if (!pane)
+ return;
+ }
+
+ /* add a graph */
+ if (strcmp(name, "fps") == 0) {
+ hud_fps_graph_install(pane);
+ }
+ else if (strcmp(name, "cpu") == 0) {
+ hud_cpu_graph_install(pane, ALL_CPUS);
+ }
+ else if (sscanf(name, "cpu%u%s", &i, s) == 1) {
+ hud_cpu_graph_install(pane, i);
+ }
+ else if (strcmp(name, "samples-passed") == 0 &&
+ has_occlusion_query(hud->pipe->screen)) {
+ hud_pipe_query_install(pane, hud->pipe, "samples-passed",
+ PIPE_QUERY_OCCLUSION_COUNTER, 0, 0, FALSE);
+ }
+ else if (strcmp(name, "primitives-generated") == 0 &&
+ has_streamout(hud->pipe->screen)) {
+ hud_pipe_query_install(pane, hud->pipe, "primitives-generated",
+ PIPE_QUERY_PRIMITIVES_GENERATED, 0, 0, FALSE);
+ }
+ else if (strncmp(name, "pipeline-statistics-", 20) == 0) {
+ if (hud->cap.query_pipeline_statistics) {
+ static const char *pipeline_statistics_names[] =
+ {
+ "ia-vertices",
+ "ia-primitives",
+ "vs-invocations",
+ "gs-invocations",
+ "gs-primitives",
+ "clipper-invocations",
+ "clipper-primitives-generated",
+ "ps-invocations",
+ "hs-invocations",
+ "ds-invocations",
+ "cs-invocations"
+ };
+ for (i = 0; i < Elements(pipeline_statistics_names); ++i)
+ if (strcmp(&name[20], pipeline_statistics_names[i]) == 0)
+ break;
+ if (i < Elements(pipeline_statistics_names))
+ hud_pipe_query_install(pane, hud->pipe, &name[20],
+ PIPE_QUERY_PIPELINE_STATISTICS, i,
+ 0, FALSE);
+ else
+ fprintf(stderr, "gallium_hud: invalid pipeline-statistics-*\n");
+ } else {
+ fprintf(stderr, "gallium_hud: PIPE_QUERY_PIPELINE_STATISTICS "
+ "not supported by the driver\n");
+ }
+ }
+ else {
+ if (!hud_driver_query_install(pane, hud->pipe, name)){
+ fprintf(stderr, "gallium_hud: unknown driver query '%s'\n", name);
+ }
+ }
+
+ if (*env == ':') {
+ env++;
+
+ if (!pane) {
+ fprintf(stderr, "gallium_hud: syntax error: unexpected ':', "
+ "expected a name\n");
+ break;
+ }
+
+ num = parse_string(env, s);
+ env += num;
+
+ if (num && sscanf(s, "%u", &i) == 1) {
+ hud_pane_set_max_value(pane, i);
+ }
+ else {
+ fprintf(stderr, "gallium_hud: syntax error: unexpected '%c' (%i) "
+ "after ':'\n", *env, *env);
+ }
+ }
+
+ if (*env == 0)
+ break;
+
+ /* parse a separator */
+ switch (*env) {
+ case '+':
+ env++;
+ break;
+
+ case ',':
+ env++;
+ y += height + hud->font.glyph_height * (pane->num_graphs + 2);
+
+ if (pane && pane->num_graphs) {
+ LIST_ADDTAIL(&pane->head, &hud->pane_list);
+ pane = NULL;
+ }
+ break;
+
+ case ';':
+ env++;
+ y = 10;
+ x += width + hud->font.glyph_width * 7;
+
+ if (pane && pane->num_graphs) {
+ LIST_ADDTAIL(&pane->head, &hud->pane_list);
+ pane = NULL;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "gallium_hud: syntax error: unexpected '%c'\n", *env);
+ }
+ }
+
+ if (pane) {
+ if (pane->num_graphs) {
+ LIST_ADDTAIL(&pane->head, &hud->pane_list);
+ }
+ else {
+ FREE(pane);
+ }
+ }
+}
+
+static void
+print_help(struct pipe_screen *screen)
+{
+ int i, num_queries, num_cpus = hud_get_num_cpus();
+
+ puts("Syntax: GALLIUM_HUD=name1[+name2][...][:value1][,nameI...][;nameJ...]");
+ puts("");
+ puts(" Names are identifiers of data sources which will be drawn as graphs");
+ puts(" in panes. Multiple graphs can be drawn in the same pane.");
+ puts(" There can be multiple panes placed in rows and columns.");
+ puts("");
+ puts(" '+' separates names which will share a pane.");
+ puts(" ':[value]' specifies the initial maximum value of the Y axis");
+ puts(" for the given pane.");
+ puts(" ',' creates a new pane below the last one.");
+ puts(" ';' creates a new pane at the top of the next column.");
+ puts("");
+ puts(" Example: GALLIUM_HUD=\"cpu,fps;primitives-generated\"");
+ puts("");
+ puts(" Available names:");
+ puts(" fps");
+ puts(" cpu");
+
+ for (i = 0; i < num_cpus; i++)
+ printf(" cpu%i\n", i);
+
+ if (has_occlusion_query(screen))
+ puts(" pixels-rendered");
+ if (has_streamout(screen))
+ puts(" primitives-generated");
+
+ if (screen->get_driver_query_info){
+ struct pipe_driver_query_info info;
+ num_queries = screen->get_driver_query_info(screen, 0, NULL);
+
+ for (i = 0; i < num_queries; i++){
+ screen->get_driver_query_info(screen, i, &info);
+ printf(" %s\n", info.name);
+ }
+ }
+
+ puts("");
+}
+
+struct hud_context *
+hud_create(struct pipe_context *pipe, struct cso_context *cso)
+{
+ struct hud_context *hud;
+ struct pipe_sampler_view view_templ;
+ unsigned i;
+ const char *env = debug_get_option("GALLIUM_HUD", NULL);
+
+ if (!env || !*env)
+ return NULL;
+
+ if (strcmp(env, "help") == 0) {
+ print_help(pipe->screen);
+ return NULL;
+ }
+
+ hud = CALLOC_STRUCT(hud_context);
+ if (!hud)
+ return NULL;
+
+ hud->pipe = pipe;
+ hud->cso = cso;
+ hud->uploader = u_upload_create(pipe, 256 * 1024, 16,
+ PIPE_BIND_VERTEX_BUFFER);
+
+ /* font */
+ if (!util_font_create(pipe, UTIL_FONT_FIXED_8X13, &hud->font)) {
+ u_upload_destroy(hud->uploader);
+ FREE(hud);
+ return NULL;
+ }
+
+ /* blend state */
+ hud->alpha_blend.rt[0].colormask = PIPE_MASK_RGBA;
+ hud->alpha_blend.rt[0].blend_enable = 1;
+ hud->alpha_blend.rt[0].rgb_func = PIPE_BLEND_ADD;
+ hud->alpha_blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ hud->alpha_blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ hud->alpha_blend.rt[0].alpha_func = PIPE_BLEND_ADD;
+ hud->alpha_blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ hud->alpha_blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+
+ /* fragment shader */
+ hud->fs_color =
+ util_make_fragment_passthrough_shader(pipe,
+ TGSI_SEMANTIC_COLOR,
+ TGSI_INTERPOLATE_CONSTANT);
+
+ {
+ /* Read a texture and do .xxxx swizzling. */
+ static const char *fragment_shader_text = {
+ "FRAG\n"
+ "DCL IN[0], GENERIC[0], LINEAR\n"
+ "DCL SAMP[0]\n"
+ "DCL OUT[0], COLOR[0]\n"
+ "DCL TEMP[0]\n"
+
+ "TEX TEMP[0], IN[0], SAMP[0], RECT\n"
+ "MOV OUT[0], TEMP[0].xxxx\n"
+ "END\n"
+ };
+
+ struct tgsi_token tokens[1000];
+ struct pipe_shader_state state = {tokens};
+
+ if (!tgsi_text_translate(fragment_shader_text, tokens, Elements(tokens))) {
+ assert(0);
+ pipe_resource_reference(&hud->font.texture, NULL);
+ u_upload_destroy(hud->uploader);
+ FREE(hud);
+ return NULL;
+ }
+
+ hud->fs_text = pipe->create_fs_state(pipe, &state);
+ }
+
+ /* rasterizer */
+ hud->rasterizer.gl_rasterization_rules = 1;
+ hud->rasterizer.depth_clip = 1;
+ hud->rasterizer.line_width = 1;
+ hud->rasterizer.line_last_pixel = 1;
+
+ /* vertex shader */
+ {
+ static const char *vertex_shader_text = {
+ "VERT\n"
+ "DCL IN[0..1]\n"
+ "DCL OUT[0], POSITION\n"
+ "DCL OUT[1], COLOR[0]\n" /* color */
+ "DCL OUT[2], GENERIC[0]\n" /* texcoord */
+ /* [0] = color,
+ * [1] = (2/fb_width, 2/fb_height, xoffset, yoffset)
+ * [2] = (xscale, yscale, 0, 0) */
+ "DCL CONST[0..2]\n"
+ "DCL TEMP[0]\n"
+ "IMM[0] FLT32 { -1, 0, 0, 1 }\n"
+
+ /* v = in * (xscale, yscale) + (xoffset, yoffset) */
+ "MAD TEMP[0].xy, IN[0], CONST[2].xyyy, CONST[1].zwww\n"
+ /* pos = v * (2 / fb_width, 2 / fb_height) - (1, 1) */
+ "MAD OUT[0].xy, TEMP[0], CONST[1].xyyy, IMM[0].xxxx\n"
+ "MOV OUT[0].zw, IMM[0]\n"
+
+ "MOV OUT[1], CONST[0]\n"
+ "MOV OUT[2], IN[1]\n"
+ "END\n"
+ };
+
+ struct tgsi_token tokens[1000];
+ struct pipe_shader_state state = {tokens};
+
+ if (!tgsi_text_translate(vertex_shader_text, tokens, Elements(tokens))) {
+ assert(0);
+ pipe_resource_reference(&hud->font.texture, NULL);
+ u_upload_destroy(hud->uploader);
+ FREE(hud);
+ return NULL;
+ }
+
+ hud->vs = pipe->create_vs_state(pipe, &state);
+ }
+
+ /* vertex elements */
+ for (i = 0; i < 2; i++) {
+ hud->velems[i].src_offset = i * 2 * sizeof(float);
+ hud->velems[i].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ hud->velems[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
+ }
+
+ /* sampler view */
+ memset(&view_templ, 0, sizeof(view_templ));
+ view_templ.format = hud->font.texture->format;
+ view_templ.swizzle_r = PIPE_SWIZZLE_RED;
+ view_templ.swizzle_g = PIPE_SWIZZLE_GREEN;
+ view_templ.swizzle_b = PIPE_SWIZZLE_BLUE;
+ view_templ.swizzle_a = PIPE_SWIZZLE_ALPHA;
+ hud->font_sampler_view = pipe->create_sampler_view(pipe, hud->font.texture,
+ &view_templ);
+
+ /* sampler state (for font drawing) */
+ hud->font_sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ hud->font_sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ hud->font_sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ hud->font_sampler_state.normalized_coords = 0;
+
+ /* constants */
+ hud->constbuf.buffer_size = sizeof(hud->constants);
+ hud->constbuf.user_buffer = &hud->constants;
+
+ LIST_INITHEAD(&hud->pane_list);
+
+ hud->cap.query_pipeline_statistics =
+ pipe->screen->get_param(pipe->screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS);
+
+ hud_parse_env_var(hud, env);
+ return hud;
+}
+
+void
+hud_destroy(struct hud_context *hud)
+{
+ struct pipe_context *pipe = hud->pipe;
+ struct hud_pane *pane, *pane_tmp;
+ struct hud_graph *graph, *graph_tmp;
+
+ LIST_FOR_EACH_ENTRY_SAFE(pane, pane_tmp, &hud->pane_list, head) {
+ LIST_FOR_EACH_ENTRY_SAFE(graph, graph_tmp, &pane->graph_list, head) {
+ LIST_DEL(&graph->head);
+ hud_graph_destroy(graph);
+ }
+ LIST_DEL(&pane->head);
+ FREE(pane);
+ }
+
+ pipe->delete_fs_state(pipe, hud->fs_color);
+ pipe->delete_fs_state(pipe, hud->fs_text);
+ pipe->delete_vs_state(pipe, hud->vs);
+ pipe_sampler_view_reference(&hud->font_sampler_view, NULL);
+ pipe_resource_reference(&hud->font.texture, NULL);
+ u_upload_destroy(hud->uploader);
+ FREE(hud);
+}
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_context.h b/mesalib/src/gallium/auxiliary/hud/hud_context.h
new file mode 100644
index 000000000..abf2ad586
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/hud_context.h
@@ -0,0 +1,45 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+#ifndef HUD_CONTEXT_H
+#define HUD_CONTEXT_H
+
+struct hud_context;
+struct cso_context;
+struct pipe_context;
+struct pipe_resource;
+
+struct hud_context *
+hud_create(struct pipe_context *pipe, struct cso_context *cso);
+
+void
+hud_destroy(struct hud_context *hud);
+
+void
+hud_draw(struct hud_context *hud, struct pipe_resource *tex);
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_cpu.c b/mesalib/src/gallium/auxiliary/hud/hud_cpu.c
new file mode 100644
index 000000000..ce98115d5
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/hud_cpu.c
@@ -0,0 +1,166 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+/* This file contains code for reading CPU load for displaying on the HUD.
+ */
+
+#include "hud/hud_private.h"
+#include "os/os_time.h"
+#include "util/u_memory.h"
+#include <stdio.h>
+#include <inttypes.h>
+
+static boolean
+get_cpu_stats(unsigned cpu_index, uint64_t *busy_time, uint64_t *total_time)
+{
+ char cpuname[32];
+ char line[1024];
+ FILE *f;
+
+ if (cpu_index == ALL_CPUS)
+ strcpy(cpuname, "cpu");
+ else
+ sprintf(cpuname, "cpu%u", cpu_index);
+
+ f = fopen("/proc/stat", "r");
+ if (!f)
+ return FALSE;
+
+ while (!feof(f) && fgets(line, sizeof(line), f)) {
+ if (strstr(line, cpuname) == line) {
+ uint64_t v[12];
+ int i, num;
+
+ num = sscanf(line,
+ "%s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64
+ " %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64
+ " %"PRIu64" %"PRIu64"",
+ cpuname, &v[0], &v[1], &v[2], &v[3], &v[4], &v[5],
+ &v[6], &v[7], &v[8], &v[9], &v[10], &v[11]);
+ if (num < 5) {
+ fclose(f);
+ return FALSE;
+ }
+
+ /* user + nice + system */
+ *busy_time = v[0] + v[1] + v[2];
+ *total_time = *busy_time;
+
+ /* ... + idle + iowait + irq + softirq + ... */
+ for (i = 3; i < num-1; i++) {
+ *total_time += v[i];
+ }
+ fclose(f);
+ return TRUE;
+ }
+ }
+ fclose(f);
+ return FALSE;
+}
+
+struct cpu_info {
+ unsigned cpu_index;
+ uint64_t last_cpu_busy, last_cpu_total, last_time;
+};
+
+static void
+query_cpu_load(struct hud_graph *gr)
+{
+ struct cpu_info *info = gr->query_data;
+ uint64_t now = os_time_get();
+
+ if (info->last_time) {
+ if (info->last_time + gr->pane->period <= now) {
+ uint64_t cpu_busy, cpu_total, cpu_load;
+
+ get_cpu_stats(info->cpu_index, &cpu_busy, &cpu_total);
+
+ cpu_load = (cpu_busy - info->last_cpu_busy) * 100 /
+ (double)(cpu_total - info->last_cpu_total);
+ hud_graph_add_value(gr, cpu_load);
+
+ info->last_cpu_busy = cpu_busy;
+ info->last_cpu_total = cpu_total;
+ info->last_time = now;
+ }
+ }
+ else {
+ /* initialize */
+ info->last_time = now;
+ get_cpu_stats(info->cpu_index, &info->last_cpu_busy,
+ &info->last_cpu_total);
+ }
+}
+
+void
+hud_cpu_graph_install(struct hud_pane *pane, unsigned cpu_index)
+{
+ struct hud_graph *gr;
+ struct cpu_info *info;
+ uint64_t busy, total;
+
+ /* see if the cpu exists */
+ if (cpu_index != ALL_CPUS && !get_cpu_stats(cpu_index, &busy, &total)) {
+ return;
+ }
+
+ gr = CALLOC_STRUCT(hud_graph);
+ if (!gr)
+ return;
+
+ if (cpu_index == ALL_CPUS)
+ strcpy(gr->name, "cpu");
+ else
+ sprintf(gr->name, "cpu%u", cpu_index);
+
+ gr->query_data = CALLOC_STRUCT(cpu_info);
+ if (!gr->query_data) {
+ FREE(gr);
+ return;
+ }
+
+ gr->query_new_value = query_cpu_load;
+ gr->free_query_data = free;
+
+ info = gr->query_data;
+ info->cpu_index = cpu_index;
+
+ hud_pane_add_graph(pane, gr);
+ hud_pane_set_max_value(pane, 100);
+}
+
+int
+hud_get_num_cpus(void)
+{
+ uint64_t busy, total;
+ int i = 0;
+
+ while (get_cpu_stats(i, &busy, &total))
+ i++;
+
+ return i;
+}
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
new file mode 100644
index 000000000..0f52e18cc
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
@@ -0,0 +1,210 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+/* This file contains code for reading values from pipe queries
+ * for displaying on the HUD. To prevent stalls when reading queries, we
+ * keep a list of busy queries in a ring. We read only those queries which
+ * are idle.
+ */
+
+#include "hud/hud_private.h"
+#include "pipe/p_screen.h"
+#include "os/os_time.h"
+#include "util/u_memory.h"
+#include <stdio.h>
+
+#define NUM_QUERIES 8
+
+struct query_info {
+ struct pipe_context *pipe;
+ unsigned query_type;
+ unsigned result_index; /* unit depends on query_type */
+
+ /* Ring of queries. If a query is busy, we use another slot. */
+ struct pipe_query *query[NUM_QUERIES];
+ unsigned head, tail;
+ unsigned num_queries;
+
+ uint64_t last_time;
+ uint64_t results_cumulative;
+ unsigned num_results;
+};
+
+static void
+query_new_value(struct hud_graph *gr)
+{
+ struct query_info *info = gr->query_data;
+ struct pipe_context *pipe = info->pipe;
+ uint64_t now = os_time_get();
+
+ if (info->last_time) {
+ pipe->end_query(pipe, info->query[info->head]);
+
+ /* read query results */
+ while (1) {
+ struct pipe_query *query = info->query[info->tail];
+ union pipe_query_result result;
+ uint64_t *res64 = (uint64_t *)&result;
+
+ if (pipe->get_query_result(pipe, query, FALSE, &result)) {
+ info->results_cumulative += res64[info->result_index];
+ info->num_results++;
+
+ if (info->tail == info->head)
+ break;
+
+ info->tail = (info->tail+1) % NUM_QUERIES;
+ }
+ else {
+ /* the oldest query is busy */
+ if ((info->head+1) % NUM_QUERIES == info->tail) {
+ /* all queries are busy, throw away the last query and create
+ * a new one */
+ fprintf(stderr,
+ "gallium_hud: all queries are busy after %i frames, "
+ "can't add another query\n",
+ NUM_QUERIES);
+ pipe->destroy_query(pipe, info->query[info->head]);
+ info->query[info->head] =
+ pipe->create_query(pipe, info->query_type);
+ }
+ else {
+ /* the last query is busy, we need to add a new one we can use
+ * for this frame */
+ info->head = (info->head+1) % NUM_QUERIES;
+ if (!info->query[info->head]) {
+ info->query[info->head] =
+ pipe->create_query(pipe, info->query_type);
+ }
+ }
+ break;
+ }
+ }
+
+ if (info->num_results && info->last_time + gr->pane->period <= now) {
+ /* compute the average value across all frames */
+ hud_graph_add_value(gr, info->results_cumulative / info->num_results);
+
+ info->last_time = now;
+ info->results_cumulative = 0;
+ info->num_results = 0;
+ }
+
+ pipe->begin_query(pipe, info->query[info->head]);
+ }
+ else {
+ /* initialize */
+ info->last_time = now;
+ info->query[info->head] = pipe->create_query(pipe, info->query_type);
+ pipe->begin_query(pipe, info->query[info->head]);
+ }
+}
+
+static void
+free_query_info(void *ptr)
+{
+ struct query_info *info = ptr;
+
+ if (info->last_time) {
+ struct pipe_context *pipe = info->pipe;
+ int i;
+
+ pipe->end_query(pipe, info->query[info->head]);
+
+ for (i = 0; i < Elements(info->query); i++) {
+ if (info->query[i]) {
+ pipe->destroy_query(pipe, info->query[i]);
+ }
+ }
+ }
+ FREE(info);
+}
+
+void
+hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe,
+ const char *name, unsigned query_type,
+ unsigned result_index,
+ uint64_t max_value, boolean uses_byte_units)
+{
+ struct hud_graph *gr;
+ struct query_info *info;
+
+ gr = CALLOC_STRUCT(hud_graph);
+ if (!gr)
+ return;
+
+ strcpy(gr->name, name);
+ gr->query_data = CALLOC_STRUCT(query_info);
+ if (!gr->query_data) {
+ FREE(gr);
+ return;
+ }
+
+ gr->query_new_value = query_new_value;
+ gr->free_query_data = free_query_info;
+
+ info = gr->query_data;
+ info->pipe = pipe;
+ info->query_type = query_type;
+ info->result_index = result_index;
+
+ hud_pane_add_graph(pane, gr);
+ if (pane->max_value < max_value)
+ hud_pane_set_max_value(pane, max_value);
+ if (uses_byte_units)
+ pane->uses_byte_units = TRUE;
+}
+
+boolean
+hud_driver_query_install(struct hud_pane *pane, struct pipe_context *pipe,
+ const char *name)
+{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_driver_query_info query;
+ unsigned num_queries, i;
+ boolean found = FALSE;
+
+ if (!screen->get_driver_query_info)
+ return FALSE;
+
+ num_queries = screen->get_driver_query_info(screen, 0, NULL);
+
+ for (i = 0; i < num_queries; i++) {
+ if (screen->get_driver_query_info(screen, i, &query) &&
+ strcmp(query.name, name) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return FALSE;
+
+ hud_pipe_query_install(pane, pipe, query.name, query.query_type, 0,
+ query.max_value, query.uses_byte_units);
+ return TRUE;
+}
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_fps.c b/mesalib/src/gallium/auxiliary/hud/hud_fps.c
new file mode 100644
index 000000000..71cdfd04e
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/hud_fps.c
@@ -0,0 +1,81 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+/* This file contains code for calculating framerate for displaying on the HUD.
+ */
+
+#include "hud/hud_private.h"
+#include "os/os_time.h"
+#include "util/u_memory.h"
+
+struct fps_info {
+ int frames;
+ uint64_t last_time;
+};
+
+static void
+query_fps(struct hud_graph *gr)
+{
+ struct fps_info *info = gr->query_data;
+ uint64_t now = os_time_get();
+
+ info->frames++;
+
+ if (info->last_time) {
+ if (info->last_time + gr->pane->period <= now) {
+ double fps = info->frames * 1000000 / (double)(now - info->last_time);
+ info->frames = 0;
+ info->last_time = now;
+
+ hud_graph_add_value(gr, fps);
+ }
+ }
+ else {
+ info->last_time = now;
+ }
+}
+
+void
+hud_fps_graph_install(struct hud_pane *pane)
+{
+ struct hud_graph *gr = CALLOC_STRUCT(hud_graph);
+
+ if (!gr)
+ return;
+
+ strcpy(gr->name, "fps");
+ gr->query_data = CALLOC_STRUCT(fps_info);
+ if (!gr->query_data) {
+ FREE(gr);
+ return;
+ }
+
+ gr->query_new_value = query_fps;
+ gr->free_query_data = free;
+
+ hud_pane_add_graph(pane, gr);
+}
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_private.h b/mesalib/src/gallium/auxiliary/hud/hud_private.h
new file mode 100644
index 000000000..2b7d56bb1
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/hud/hud_private.h
@@ -0,0 +1,92 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ * 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 THE AUTHORS 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.
+ *
+ **************************************************************************/
+
+#ifndef HUD_PRIVATE_H
+#define HUD_PRIVATE_H
+
+#include "pipe/p_context.h"
+#include "util/u_double_list.h"
+
+struct hud_graph {
+ /* initialized by common code */
+ struct list_head head;
+ struct hud_pane *pane;
+ float color[3];
+ float *vertices; /* ring buffer of vertices */
+
+ /* name and query */
+ char name[128];
+ void *query_data;
+ void (*query_new_value)(struct hud_graph *gr);
+ void (*free_query_data)(void *ptr);
+
+ /* mutable variables */
+ unsigned num_vertices;
+ unsigned index; /* vertex index being updated */
+ uint64_t current_value;
+};
+
+struct hud_pane {
+ struct list_head head;
+ unsigned x1, y1, x2, y2;
+ unsigned inner_x1;
+ unsigned inner_y1;
+ unsigned inner_x2;
+ unsigned inner_y2;
+ unsigned inner_width;
+ unsigned inner_height;
+ float yscale;
+ unsigned max_num_vertices;
+ uint64_t max_value;
+ boolean uses_byte_units;
+ uint64_t period; /* in microseconds */
+
+ struct list_head graph_list;
+ unsigned num_graphs;
+};
+
+
+/* core */
+void hud_pane_add_graph(struct hud_pane *pane, struct hud_graph *gr);
+void hud_pane_set_max_value(struct hud_pane *pane, uint64_t value);
+void hud_graph_add_value(struct hud_graph *gr, uint64_t value);
+
+/* graphs/queries */
+#define ALL_CPUS ~0 /* optionally set as cpu_index */
+
+int hud_get_num_cpus(void);
+
+void hud_fps_graph_install(struct hud_pane *pane);
+void hud_cpu_graph_install(struct hud_pane *pane, unsigned cpu_index);
+void hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe,
+ const char *name, unsigned query_type,
+ unsigned result_index,
+ uint64_t max_value, boolean uses_byte_units);
+boolean hud_driver_query_install(struct hud_pane *pane,
+ struct pipe_context *pipe, const char *name);
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index 70fec9118..2a4a13e9f 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -1135,18 +1135,17 @@ static boolean is_blit_generic_supported(struct blitter_context *blitter,
if (dst) {
unsigned bind;
- boolean is_stencil;
const struct util_format_description *desc =
util_format_description(dst_format);
-
- is_stencil = util_format_has_stencil(desc);
+ boolean dst_has_stencil = util_format_has_stencil(desc);
/* Stencil export must be supported for stencil copy. */
- if ((mask & PIPE_MASK_S) && is_stencil && !ctx->has_stencil_export) {
+ if ((mask & PIPE_MASK_S) && dst_has_stencil &&
+ !ctx->has_stencil_export) {
return FALSE;
}
- if (is_stencil || util_format_has_depth(desc))
+ if (dst_has_stencil || util_format_has_depth(desc))
bind = PIPE_BIND_DEPTH_STENCIL;
else
bind = PIPE_BIND_RENDER_TARGET;
@@ -1168,15 +1167,18 @@ static boolean is_blit_generic_supported(struct blitter_context *blitter,
}
/* Check stencil sampler support for stencil copy. */
- if (util_format_has_stencil(util_format_description(src_format))) {
- enum pipe_format stencil_format =
+ if (mask & PIPE_MASK_S) {
+ if (util_format_has_stencil(util_format_description(src_format))) {
+ enum pipe_format stencil_format =
util_format_stencil_only(src_format);
- assert(stencil_format != PIPE_FORMAT_NONE);
+ assert(stencil_format != PIPE_FORMAT_NONE);
- if (stencil_format != src_format &&
- !screen->is_format_supported(screen, stencil_format, src->target,
- src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
- return FALSE;
+ if (stencil_format != src_format &&
+ !screen->is_format_supported(screen, stencil_format,
+ src->target, src->nr_samples,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ return FALSE;
+ }
}
}
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c
index 03280515b..7e6df9df1 100644
--- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c
+++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c
@@ -279,6 +279,7 @@ util_cpu_detect(void)
util_cpu_caps.has_sse4_1 = (regs2[2] >> 19) & 1;
util_cpu_caps.has_sse4_2 = (regs2[2] >> 20) & 1;
util_cpu_caps.has_avx = (regs2[2] >> 28) & 1;
+ util_cpu_caps.has_f16c = (regs2[2] >> 29) & 1;
util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */
cacheline = ((regs2[1] >> 8) & 0xFF) * 8;
diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h
index acac68658..21c2f048f 100644
--- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h
+++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h
@@ -63,6 +63,7 @@ struct util_cpu_caps {
unsigned has_sse4_1:1;
unsigned has_sse4_2:1;
unsigned has_avx:1;
+ unsigned has_f16c:1;
unsigned has_3dnow:1;
unsigned has_3dnow_ext:1;
unsigned has_altivec:1;
diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_memory.c b/mesalib/src/gallium/auxiliary/util/u_debug_memory.c
index 4bf26a524..472354781 100644
--- a/mesalib/src/gallium/auxiliary/util/u_debug_memory.c
+++ b/mesalib/src/gallium/auxiliary/util/u_debug_memory.c
@@ -76,6 +76,7 @@ struct debug_memory_header
#endif
unsigned magic;
+ unsigned tag;
};
struct debug_memory_footer
@@ -140,6 +141,7 @@ debug_malloc(const char *file, unsigned line, const char *function,
hdr->function = function;
hdr->size = size;
hdr->magic = DEBUG_MEMORY_MAGIC;
+ hdr->tag = 0;
#if DEBUG_FREED_MEMORY
hdr->freed = FALSE;
#endif
@@ -263,6 +265,7 @@ debug_realloc(const char *file, unsigned line, const char *function,
new_hdr->function = old_hdr->function;
new_hdr->size = new_size;
new_hdr->magic = DEBUG_MEMORY_MAGIC;
+ new_hdr->tag = 0;
#if DEBUG_FREED_MEMORY
new_hdr->freed = FALSE;
#endif
@@ -348,6 +351,58 @@ debug_memory_end(unsigned long start_no)
/**
+ * Put a tag (arbitrary integer) on a memory block.
+ * Can be useful for debugging.
+ */
+void
+debug_memory_tag(void *ptr, unsigned tag)
+{
+ struct debug_memory_header *hdr;
+
+ if (!ptr)
+ return;
+
+ hdr = header_from_data(ptr);
+ if (hdr->magic != DEBUG_MEMORY_MAGIC) {
+ debug_printf("%s corrupted memory at %p\n", __FUNCTION__, ptr);
+ debug_assert(0);
+ }
+
+ hdr->tag = tag;
+}
+
+
+/**
+ * Check the given block of memory for validity/corruption.
+ */
+void
+debug_memory_check_block(void *ptr)
+{
+ struct debug_memory_header *hdr;
+ struct debug_memory_footer *ftr;
+
+ if (!ptr)
+ return;
+
+ hdr = header_from_data(ptr);
+ ftr = footer_from_header(hdr);
+
+ if (hdr->magic != DEBUG_MEMORY_MAGIC) {
+ debug_printf("%s:%u:%s: bad or corrupted memory %p\n",
+ hdr->file, hdr->line, hdr->function, ptr);
+ debug_assert(0);
+ }
+
+ if (ftr->magic != DEBUG_MEMORY_MAGIC) {
+ debug_printf("%s:%u:%s: buffer overflow %p\n",
+ hdr->file, hdr->line, hdr->function, ptr);
+ debug_assert(0);
+ }
+}
+
+
+
+/**
* We can periodically call this from elsewhere to do a basic sanity
* check of the heap memory we've allocated.
*/
diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h
index 00301265d..ed942fb16 100644
--- a/mesalib/src/gallium/auxiliary/util/u_format.h
+++ b/mesalib/src/gallium/auxiliary/util/u_format.h
@@ -447,6 +447,7 @@ util_format_is_compressed(enum pipe_format format)
switch (desc->layout) {
case UTIL_FORMAT_LAYOUT_S3TC:
case UTIL_FORMAT_LAYOUT_RGTC:
+ case UTIL_FORMAT_LAYOUT_ETC:
/* XXX add other formats in the future */
return TRUE;
default:
diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h
index ba745ebb5..7770cd514 100644
--- a/mesalib/src/gallium/auxiliary/util/u_inlines.h
+++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h
@@ -517,7 +517,7 @@ util_query_clear_result(union pipe_query_result *result, unsigned type)
memset(&result->pipeline_statistics, 0, sizeof(result->pipeline_statistics));
break;
default:
- assert(0);
+ memset(result, 0, sizeof(*result));
}
}
@@ -583,7 +583,7 @@ util_copy_constant_buffer(struct pipe_constant_buffer *dst,
}
static INLINE unsigned
-util_max_layer(struct pipe_resource *r, unsigned level)
+util_max_layer(const struct pipe_resource *r, unsigned level)
{
switch (r->target) {
case PIPE_TEXTURE_CUBE:
diff --git a/mesalib/src/gallium/auxiliary/util/u_resource.c b/mesalib/src/gallium/auxiliary/util/u_resource.c
index a32c4f6df..66caaae84 100644
--- a/mesalib/src/gallium/auxiliary/util/u_resource.c
+++ b/mesalib/src/gallium/auxiliary/util/u_resource.c
@@ -1,76 +1,65 @@
+/*
+ * Copyright 2013 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 THE AUTHORS 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 "util/u_inlines.h"
-#include "util/u_transfer.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_resource.h"
-static INLINE struct u_resource *
-u_resource( struct pipe_resource *res )
-{
- return (struct u_resource *)res;
-}
-boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
- struct pipe_resource *resource,
- struct winsys_handle *handle)
+/**
+ * Return the size of the resource in bytes.
+ */
+unsigned
+util_resource_size(const struct pipe_resource *res)
{
- struct u_resource *ur = u_resource(resource);
- return ur->vtbl->resource_get_handle(screen, resource, handle);
-}
+ unsigned width = res->width0;
+ unsigned height = res->height0;
+ unsigned depth = res->depth0;
+ unsigned size = 0;
+ unsigned level;
-void u_resource_destroy_vtbl(struct pipe_screen *screen,
- struct pipe_resource *resource)
-{
- struct u_resource *ur = u_resource(resource);
- ur->vtbl->resource_destroy(screen, resource);
-}
+ for (level = 0; level <= res->last_level; level++) {
+ unsigned slices;
-void *u_transfer_map_vtbl(struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- struct pipe_transfer **transfer)
-{
- struct u_resource *ur = u_resource(resource);
- return ur->vtbl->transfer_map(context, resource, level, usage, box,
- transfer);
-}
+ if (res->target == PIPE_TEXTURE_CUBE)
+ slices = 6;
+ else if (res->target == PIPE_TEXTURE_3D)
+ slices = depth;
+ else
+ slices = res->array_size;
-void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box)
-{
- struct u_resource *ur = u_resource(transfer->resource);
- ur->vtbl->transfer_flush_region(pipe, transfer, box);
-}
+ size += (util_format_get_nblocksy(res->format, height) *
+ util_format_get_stride(res->format, width) * slices);
-void u_transfer_unmap_vtbl( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
-{
- struct u_resource *ur = u_resource(transfer->resource);
- ur->vtbl->transfer_unmap(pipe, transfer);
-}
+ width = u_minify(width, 1);
+ height = u_minify(height, 1);
+ depth = u_minify(depth, 1);
+ }
-void u_transfer_inline_write_vtbl( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride)
-{
- struct u_resource *ur = u_resource(resource);
- ur->vtbl->transfer_inline_write(pipe,
- resource,
- level,
- usage,
- box,
- data,
- stride,
- layer_stride);
+ return size;
}
-
-
-
-
diff --git a/mesalib/src/gallium/auxiliary/util/u_resource.h b/mesalib/src/gallium/auxiliary/util/u_resource.h
new file mode 100644
index 000000000..977e0136b
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/util/u_resource.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 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 THE AUTHORS 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.
+ */
+
+#ifndef U_RESOURCE_H
+#define U_RESOURCE_H
+
+struct pipe_resource;
+
+unsigned
+util_resource_size(const struct pipe_resource *res);
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.c b/mesalib/src/gallium/auxiliary/util/u_transfer.c
index 861682553..56e059bfd 100644
--- a/mesalib/src/gallium/auxiliary/util/u_transfer.c
+++ b/mesalib/src/gallium/auxiliary/util/u_transfer.c
@@ -87,3 +87,76 @@ void u_default_transfer_unmap( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
}
+
+
+static INLINE struct u_resource *
+u_resource( struct pipe_resource *res )
+{
+ return (struct u_resource *)res;
+}
+
+boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
+ struct pipe_resource *resource,
+ struct winsys_handle *handle)
+{
+ struct u_resource *ur = u_resource(resource);
+ return ur->vtbl->resource_get_handle(screen, resource, handle);
+}
+
+void u_resource_destroy_vtbl(struct pipe_screen *screen,
+ struct pipe_resource *resource)
+{
+ struct u_resource *ur = u_resource(resource);
+ ur->vtbl->resource_destroy(screen, resource);
+}
+
+void *u_transfer_map_vtbl(struct pipe_context *context,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer)
+{
+ struct u_resource *ur = u_resource(resource);
+ return ur->vtbl->transfer_map(context, resource, level, usage, box,
+ transfer);
+}
+
+void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
+{
+ struct u_resource *ur = u_resource(transfer->resource);
+ ur->vtbl->transfer_flush_region(pipe, transfer, box);
+}
+
+void u_transfer_unmap_vtbl( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct u_resource *ur = u_resource(transfer->resource);
+ ur->vtbl->transfer_unmap(pipe, transfer);
+}
+
+void u_transfer_inline_write_vtbl( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride)
+{
+ struct u_resource *ur = u_resource(resource);
+ ur->vtbl->transfer_inline_write(pipe,
+ resource,
+ level,
+ usage,
+ box,
+ data,
+ stride,
+ layer_stride);
+}
+
+
+
+
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index c294aa429..b5282a604 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -80,6 +80,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_dead_code.cpp \
$(GLSL_SRCDIR)/opt_dead_code_local.cpp \
$(GLSL_SRCDIR)/opt_dead_functions.cpp \
+ $(GLSL_SRCDIR)/opt_flatten_nested_if_blocks.cpp \
$(GLSL_SRCDIR)/opt_function_inlining.cpp \
$(GLSL_SRCDIR)/opt_if_simplification.cpp \
$(GLSL_SRCDIR)/opt_noop_swizzle.cpp \
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index d6afe8814..00edbbfbd 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -1233,6 +1233,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->ARB_texture_multisample)
add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
+
+ if (extensions->ARB_texture_query_lod)
+ add_builtin_define(parser, "GL_ARB_texture_query_lod", 1);
}
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 56082f761..099229410 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -467,6 +467,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array),
EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing),
EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample),
+ EXT(ARB_texture_query_lod, false, false, true, true, false, ARB_texture_query_lod),
};
#undef EXT
@@ -1217,6 +1218,7 @@ do_common_optimization(exec_list *ir, bool linked,
progress = do_structure_splitting(ir) || progress;
}
progress = do_if_simplification(ir) || progress;
+ progress = opt_flatten_nested_if_blocks(ir) || progress;
progress = do_copy_propagation(ir) || progress;
progress = do_copy_propagation_elements(ir) || progress;
if (linked)
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 1765cdf16..95891b595 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -282,6 +282,8 @@ struct _mesa_glsl_parse_state {
bool ARB_shading_language_packing_warn;
bool ARB_texture_multisample_enable;
bool ARB_texture_multisample_warn;
+ bool ARB_texture_query_lod_enable;
+ bool ARB_texture_query_lod_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 8b0a24805..419761a7d 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -476,6 +476,8 @@ const glsl_type *glsl_type::get_scalar_type() const
return int_type;
case GLSL_TYPE_FLOAT:
return float_type;
+ case GLSL_TYPE_BOOL:
+ return bool_type;
default:
/* Handle everything else */
return type;
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 60ef8b95a..05b77da2c 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1307,7 +1307,7 @@ ir_dereference::is_lvalue() const
}
-static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" };
+static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod" };
const char *ir_texture::opcode_string()
{
@@ -1338,6 +1338,9 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
if (this->op == ir_txs) {
assert(type->base_type == GLSL_TYPE_INT);
+ } else if (this->op == ir_lod) {
+ assert(type->vector_elements == 2);
+ assert(type->base_type == GLSL_TYPE_FLOAT);
} else {
assert(sampler->type->sampler_type == (int) type->base_type);
if (sampler->type->sampler_shadow)
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index bbfec695f..0c3e39979 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -120,6 +120,7 @@ public:
virtual class ir_dereference * as_dereference() { return NULL; }
virtual class ir_dereference_array * as_dereference_array() { return NULL; }
virtual class ir_dereference_variable *as_dereference_variable() { return NULL; }
+ virtual class ir_dereference_record *as_dereference_record() { return NULL; }
virtual class ir_expression * as_expression() { return NULL; }
virtual class ir_rvalue * as_rvalue() { return NULL; }
virtual class ir_loop * as_loop() { return NULL; }
@@ -1425,7 +1426,8 @@ enum ir_texture_opcode {
ir_txd, /**< Texture look-up with partial derivatvies */
ir_txf, /**< Texel fetch with explicit LOD */
ir_txf_ms, /**< Multisample texture fetch */
- ir_txs /**< Texture size */
+ ir_txs, /**< Texture size */
+ ir_lod /**< Texture lod query */
};
@@ -1449,6 +1451,7 @@ enum ir_texture_opcode {
* (txf_ms
* <type> <sampler> <coordinate> <sample_index>)
* (txs <type> <sampler> <lod>)
+ * (lod <type> <sampler> <coordinate>)
*/
class ir_texture : public ir_rvalue {
public:
@@ -1738,6 +1741,11 @@ public:
virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+ virtual ir_dereference_record *as_dereference_record()
+ {
+ return this;
+ }
+
/**
* Get the variable that is ultimately referenced by an r-value
*/
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index 4797451d7..5b42935f8 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -243,6 +243,7 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
switch (this->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht);
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index c2d0dc46c..c09e56a3d 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -1398,7 +1398,7 @@ ir_dereference_array::constant_referenced(struct hash_table *variable_context,
return;
}
- const glsl_type *vt = substore->type;
+ const glsl_type *vt = array->type;
if (vt->is_array()) {
store = substore->get_array_element(index);
offset = 0;
diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp
index 5fa75011e..559b71af3 100644
--- a/mesalib/src/glsl/ir_hv_accept.cpp
+++ b/mesalib/src/glsl/ir_hv_accept.cpp
@@ -213,6 +213,7 @@ ir_texture::accept(ir_hierarchical_visitor *v)
switch (this->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
s = this->lod_info.bias->accept(v);
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index 2454bbe6f..a8885d722 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -82,6 +82,7 @@ bool do_function_inlining(exec_list *instructions);
bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lower_sub_return = true, bool lower_main_return = false, bool lower_continue = false, bool lower_break = false);
bool do_lower_texture_projection(exec_list *instructions);
bool do_if_simplification(exec_list *instructions);
+bool opt_flatten_nested_if_blocks(exec_list *instructions);
bool do_discard_simplification(exec_list *instructions);
bool lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth = 0);
bool do_mat_op_to_vec(exec_list *instructions);
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index 3bdea9bbc..597d2813f 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -278,6 +278,7 @@ void ir_print_visitor::visit(ir_texture *ir)
switch (ir->op)
{
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
ir->lod_info.bias->accept(this);
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 22ce03b0d..16fdc41b4 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -917,6 +917,8 @@ ir_reader::read_texture(s_expression *expr)
s_pattern tex_pattern[] =
{ "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
+ s_pattern lod_pattern[] =
+ { "lod", s_type, s_sampler, s_coord };
s_pattern txf_pattern[] =
{ "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
s_pattern txf_ms_pattern[] =
@@ -926,7 +928,9 @@ ir_reader::read_texture(s_expression *expr)
s_pattern other_pattern[] =
{ tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
- if (MATCH(expr, tex_pattern)) {
+ if (MATCH(expr, lod_pattern)) {
+ op = ir_lod;
+ } else if (MATCH(expr, tex_pattern)) {
op = ir_tex;
} else if (MATCH(expr, txf_pattern)) {
op = ir_txf;
@@ -939,7 +943,7 @@ ir_reader::read_texture(s_expression *expr)
if (op == -1)
return NULL;
} else {
- ir_read_error(NULL, "unexpected texture pattern");
+ ir_read_error(NULL, "unexpected texture pattern %s", tag->value());
return NULL;
}
@@ -971,7 +975,7 @@ ir_reader::read_texture(s_expression *expr)
return NULL;
}
- if (op != ir_txf_ms) {
+ if (op != ir_txf_ms && op != ir_lod) {
// Read texel offset - either 0 or an rvalue.
s_int *si_offset = SX_AS_INT(s_offset);
if (si_offset == NULL || si_offset->value() != 0) {
@@ -984,7 +988,7 @@ ir_reader::read_texture(s_expression *expr)
}
}
- if (op != ir_txf && op != ir_txf_ms && op != ir_txs) {
+ if (op != ir_txf && op != ir_txf_ms && op != ir_txs && op != ir_lod) {
s_int *proj_as_int = SX_AS_INT(s_proj);
if (proj_as_int && proj_as_int->value() == 1) {
tex->projector = NULL;
@@ -1054,7 +1058,7 @@ ir_reader::read_texture(s_expression *expr)
break;
}
default:
- // tex doesn't have any extra parameters.
+ // tex and lod don't have any extra parameters.
break;
};
return tex;
diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp
index 543c54496..3504a4dda 100644
--- a/mesalib/src/glsl/ir_rvalue_visitor.cpp
+++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp
@@ -57,6 +57,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
switch (ir->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
handle_rvalue(&ir->lod_info.bias);
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 24ea506dc..699c192cd 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -701,6 +701,11 @@ check_node_type(ir_instruction *ir, void *data)
void
validate_ir_tree(exec_list *instructions)
{
+ /* We shouldn't have any reason to validate IR in a release build,
+ * and it's half composed of assert()s anyway which wouldn't do
+ * anything.
+ */
+#ifdef DEBUG
ir_validate v;
v.run(instructions);
@@ -710,4 +715,5 @@ validate_ir_tree(exec_list *instructions)
visit_tree(ir, check_node_type, NULL);
}
+#endif
}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 29856b080..2b30d2b65 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1067,13 +1067,11 @@ link_intrastage_shaders(void *mem_ctx,
free(linking_shaders);
-#ifdef DEBUG
/* At this point linked should contain all of the linked IR, so
* validate it to make sure nothing went wrong.
*/
if (linked)
validate_ir_tree(linked->ir);
-#endif
/* Make a pass over all variable declarations to ensure that arrays with
* unspecified sizes have a size specified. The size is inferred from the
diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp
index 92813f567..bfc8c013b 100644
--- a/mesalib/src/glsl/lower_jumps.cpp
+++ b/mesalib/src/glsl/lower_jumps.cpp
@@ -1002,10 +1002,12 @@ do_lower_jumps(exec_list *instructions, bool pull_out_jumps, bool lower_sub_retu
v.lower_sub_return = lower_sub_return;
v.lower_main_return = lower_main_return;
+ bool progress_ever = false;
do {
v.progress = false;
visit_exec_list(instructions, &v);
+ progress_ever = v.progress || progress_ever;
} while (v.progress);
- return v.progress;
+ return progress_ever;
}
diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp
index 026197df7..aade203e7 100644
--- a/mesalib/src/glsl/lower_ubo_reference.cpp
+++ b/mesalib/src/glsl/lower_ubo_reference.cpp
@@ -356,18 +356,14 @@ lower_ubo_reference_visitor::emit_ubo_loads(ir_dereference *deref,
unsigned matrix_stride = 16;
for (unsigned i = 0; i < deref->type->vector_elements; i++) {
- ir_rvalue *chan = new(mem_ctx) ir_constant((int)i);
- ir_dereference *deref_chan =
- new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL),
- chan);
-
ir_rvalue *chan_offset =
add(base_offset,
new(mem_ctx) ir_constant(deref_offset + i * matrix_stride));
- base_ir->insert_before(assign(deref_chan,
+ base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
ubo_load(glsl_type::float_type,
- chan_offset)));
+ chan_offset),
+ (1U << i)));
}
}
}
diff --git a/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp b/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp
new file mode 100644
index 000000000..c70210204
--- /dev/null
+++ b/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file opt_flatten_nested_if_blocks.cpp
+ *
+ * Flattens nested if blocks such as:
+ *
+ * if (x) {
+ * if (y) {
+ * ...
+ * }
+ * }
+ *
+ * into a single if block with a combined condition:
+ *
+ * if (x && y) {
+ * ...
+ * }
+ */
+
+#include "ir.h"
+#include "ir_builder.h"
+
+using namespace ir_builder;
+
+namespace {
+
+class nested_if_flattener : public ir_hierarchical_visitor {
+public:
+ nested_if_flattener()
+ {
+ progress = false;
+ }
+
+ ir_visitor_status visit_leave(ir_if *);
+ ir_visitor_status visit_enter(ir_assignment *);
+
+ bool progress;
+};
+
+} /* unnamed namespace */
+
+/* We only care about the top level "if" instructions, so don't
+ * descend into expressions.
+ */
+ir_visitor_status
+nested_if_flattener::visit_enter(ir_assignment *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+bool
+opt_flatten_nested_if_blocks(exec_list *instructions)
+{
+ nested_if_flattener v;
+
+ v.run(instructions);
+ return v.progress;
+}
+
+
+ir_visitor_status
+nested_if_flattener::visit_leave(ir_if *ir)
+{
+ /* Only handle a single ir_if within the then clause of an ir_if. No extra
+ * instructions, no else clauses, nothing.
+ */
+ if (ir->then_instructions.is_empty() || !ir->else_instructions.is_empty())
+ return visit_continue;
+
+ ir_if *inner = ((ir_instruction *) ir->then_instructions.head)->as_if();
+ if (!inner || !inner->next->is_tail_sentinel() ||
+ !inner->else_instructions.is_empty())
+ return visit_continue;
+
+ ir->condition = logic_and(ir->condition, inner->condition);
+ inner->then_instructions.move_nodes_to(&ir->then_instructions);
+
+ progress = true;
+ return visit_continue;
+}
diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp
index 985540196..9aceb134d 100644
--- a/mesalib/src/glsl/opt_tree_grafting.cpp
+++ b/mesalib/src/glsl/opt_tree_grafting.cpp
@@ -274,6 +274,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
switch (ir->op) {
case ir_tex:
+ case ir_lod:
break;
case ir_txb:
if (do_graft(&ir->lod_info.bias))
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index b5ef768bd..0c1f52f48 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -103,6 +103,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Extensions.OES_standard_derivatives = true;
ctx->Extensions.ARB_texture_cube_map_array = true;
ctx->Extensions.ARB_texture_multisample = true;
+ ctx->Extensions.ARB_texture_query_lod = true;
ctx->Const.GLSLVersion = 120;
diff --git a/mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml b/mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml
new file mode 100644
index 000000000..0f9d323d4
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+<category name="GL_ARB_texture_storage_multisample" number="141">
+
+ <function name="TexStorage2DMultisample" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="fixedsamplelocations" type="GLboolean"/>
+ </function>
+
+ <function name="TexStorage3DMultisample" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="depth" type="GLsizei"/>
+ <param name="fixedsamplelocations" type="GLboolean"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index 75957dc7d..df9592477 100644
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8321,6 +8321,10 @@
<xi:include href="ARB_texture_buffer_range.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 140. GL_ARB_texture_query_levels -->
+
+<xi:include href="ARB_texture_storage_multisample.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<!-- Non-ARB extensions sorted by extension number. -->
<category name="GL_EXT_blend_color" number="2">
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c
index 731d46658..a98dfc607 100644
--- a/mesalib/src/mesa/drivers/common/driverfuncs.c
+++ b/mesalib/src/mesa/drivers/common/driverfuncs.c
@@ -28,6 +28,7 @@
#include "main/accum.h"
#include "main/arrayobj.h"
#include "main/context.h"
+#include "main/formatquery.h"
#include "main/framebuffer.h"
#include "main/mipmap.h"
#include "main/queryobj.h"
@@ -90,7 +91,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
/* Texture functions */
driver->ChooseTextureFormat = _mesa_choose_tex_format;
- driver->QuerySamplesForFormat = NULL;
+ driver->QuerySamplesForFormat = _mesa_query_samples_for_format;
driver->TexImage = _mesa_store_teximage;
driver->TexSubImage = _mesa_store_texsubimage;
driver->GetTexImage = _mesa_meta_GetTexImage;
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 8114550ba..e3ab82bfe 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -757,7 +757,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
* it's for the pixel path (ClampFragmentColor is GL_TRUE),
* regardless of the internal implementation of the metaops.
*/
- if (ctx->Color.ClampFragmentColor != GL_TRUE)
+ if (ctx->Color.ClampFragmentColor != GL_TRUE &&
+ ctx->Extensions.ARB_color_buffer_float)
_mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
}
@@ -767,7 +768,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
/* Generally in here we never want vertex color clamping --
* result clamping is only dependent on fragment clamping.
*/
- _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
+ if (ctx->Extensions.ARB_color_buffer_float)
+ _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
}
if (state & MESA_META_CONDITIONAL_RENDER) {
@@ -1091,11 +1093,13 @@ _mesa_meta_end(struct gl_context *ctx)
_mesa_DepthRange(save->DepthNear, save->DepthFar);
}
- if (state & MESA_META_CLAMP_FRAGMENT_COLOR) {
+ if (state & MESA_META_CLAMP_FRAGMENT_COLOR &&
+ ctx->Extensions.ARB_color_buffer_float) {
_mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor);
}
- if (state & MESA_META_CLAMP_VERTEX_COLOR) {
+ if (state & MESA_META_CLAMP_VERTEX_COLOR &&
+ ctx->Extensions.ARB_color_buffer_float) {
_mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor);
}
@@ -2044,7 +2048,8 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
/* leave colormask, glDrawBuffer state as-is */
/* Clears never have the color clamped. */
- _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
+ if (ctx->Extensions.ARB_color_buffer_float)
+ _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
}
else {
ASSERT(metaSave & MESA_META_COLOR_MASK);
@@ -2295,7 +2300,8 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
/* leave colormask, glDrawBuffer state as-is */
/* Clears never have the color clamped. */
- _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
+ if (ctx->Extensions.ARB_color_buffer_float)
+ _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
}
else {
ASSERT(metaSave & MESA_META_COLOR_MASK);
diff --git a/mesalib/src/mesa/drivers/dri/common/Android.mk b/mesalib/src/mesa/drivers/dri/common/Android.mk
index f428c3855..b3dac29dd 100644
--- a/mesalib/src/mesa/drivers/dri/common/Android.mk
+++ b/mesalib/src/mesa/drivers/dri/common/Android.mk
@@ -77,7 +77,8 @@ $(intermediates)/xmlpool/options.h: PRIVATE_SCRIPT := $(LOCAL_PATH)/xmlpool/gen_
$(intermediates)/xmlpool/options.h: PRIVATE_LOCALEDIR := $(intermediates)/xmlpool
$(intermediates)/xmlpool/options.h: PRIVATE_TEMPLATE_HEADER := $(LOCAL_PATH)/xmlpool/t_options.h
$(intermediates)/xmlpool/options.h: PRIVATE_MO_FILES := $(MESA_DRI_OPTIONS_LANGS:%=$(intermediates)/xmlpool/%/LC_MESSAGES/options.mo)
-$(intermediates)/xmlpool/options.h: $(PRIVATE_SCRIPT) $(PRIVATE_TEMPLATE_HEADER) $(PRIVATE_MO_FILES)
+.SECONDEXPANSION:
+$(intermediates)/xmlpool/options.h: $$(PRIVATE_SCRIPT) $$(PRIVATE_TEMPLATE_HEADER) $$(PRIVATE_MO_FILES)
mkdir -p $(dir $@)
mkdir -p $(PRIVATE_LOCALEDIR)
$(MESA_PYTHON2) $(PRIVATE_SCRIPT) $(PRIVATE_TEMPLATE_HEADER) \
diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc
index a13941f68..556d1b599 100644
--- a/mesalib/src/mesa/drivers/dri/common/drirc
+++ b/mesalib/src/mesa/drivers/dri/common/drirc
@@ -25,5 +25,11 @@
<application name="Savage 2" executable="savage2.bin">
<option name="disable_glsl_line_continuations" value="true" />
</application>
+ <application name="Topogun (32-bit)" executable="topogun32">
+ <option name="always_have_depth_buffer" value="true" />
+ </application>
+ <application name="Topogun (64-bit)" executable="topogun64">
+ <option name="always_have_depth_buffer" value="true" />
+ </application>
</device>
</driconf>
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index 3b991bcac..a672845bf 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -986,7 +986,9 @@ _mesa_PopAttrib(void)
_mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
color->IndexLogicOpEnabled);
_mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
- _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, color->ClampFragmentColor);
+ if (ctx->Extensions.ARB_color_buffer_float)
+ _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB,
+ color->ClampFragmentColor);
_mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor);
/* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
@@ -1114,7 +1116,10 @@ _mesa_PopAttrib(void)
/* materials */
memcpy(&ctx->Light.Material, &light->Material,
sizeof(struct gl_material));
- _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB, light->ClampVertexColor);
+ if (ctx->Extensions.ARB_color_buffer_float) {
+ _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB,
+ light->ClampVertexColor);
+ }
}
break;
case GL_LINE_BIT:
diff --git a/mesalib/src/mesa/main/blend.c b/mesalib/src/mesa/main/blend.c
index 309f1d538..09a1c9ae8 100644
--- a/mesalib/src/mesa/main/blend.c
+++ b/mesalib/src/mesa/main/blend.c
@@ -765,24 +765,96 @@ _mesa_ClampColor(GLenum target, GLenum clamp)
switch (target) {
case GL_CLAMP_VERTEX_COLOR_ARB:
+ if (ctx->API == API_OPENGL_CORE &&
+ !ctx->Extensions.ARB_color_buffer_float) {
+ goto invalid_enum;
+ }
FLUSH_VERTICES(ctx, _NEW_LIGHT);
ctx->Light.ClampVertexColor = clamp;
+ _mesa_update_clamp_vertex_color(ctx);
break;
case GL_CLAMP_FRAGMENT_COLOR_ARB:
+ if (ctx->API == API_OPENGL_CORE &&
+ !ctx->Extensions.ARB_color_buffer_float) {
+ goto invalid_enum;
+ }
FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
ctx->Color.ClampFragmentColor = clamp;
+ _mesa_update_clamp_fragment_color(ctx);
break;
case GL_CLAMP_READ_COLOR_ARB:
FLUSH_VERTICES(ctx, _NEW_COLOR);
ctx->Color.ClampReadColor = clamp;
break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)");
- return;
+ goto invalid_enum;
}
+ return;
+
+invalid_enum:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glClampColor(%s)",
+ _mesa_lookup_enum_by_nr(target));
+}
+
+static GLboolean
+get_clamp_color(const struct gl_framebuffer *fb, GLenum clamp)
+{
+ if (clamp == GL_TRUE || clamp == GL_FALSE)
+ return clamp;
+
+ ASSERT(clamp == GL_FIXED_ONLY);
+ if (!fb)
+ return GL_TRUE;
+
+ return fb->_AllColorBuffersFixedPoint;
+}
+
+GLboolean
+_mesa_get_clamp_fragment_color(const struct gl_context *ctx)
+{
+ return get_clamp_color(ctx->DrawBuffer,
+ ctx->Color.ClampFragmentColor);
+}
+
+GLboolean
+_mesa_get_clamp_vertex_color(const struct gl_context *ctx)
+{
+ return get_clamp_color(ctx->DrawBuffer, ctx->Light.ClampVertexColor);
+}
+
+GLboolean
+_mesa_get_clamp_read_color(const struct gl_context *ctx)
+{
+ return get_clamp_color(ctx->ReadBuffer, ctx->Color.ClampReadColor);
}
+/**
+ * Update the ctx->Color._ClampFragmentColor field
+ */
+void
+_mesa_update_clamp_fragment_color(struct gl_context *ctx)
+{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ /* Don't clamp if:
+ * - there is no colorbuffer
+ * - all colorbuffers are unsigned normalized, so clamping has no effect
+ * - there is an integer colorbuffer
+ */
+ if (!fb || !fb->_HasSNormOrFloatColorBuffer || fb->_IntegerColor)
+ ctx->Color._ClampFragmentColor = GL_FALSE;
+ else
+ ctx->Color._ClampFragmentColor = _mesa_get_clamp_fragment_color(ctx);
+}
+
+/**
+ * Update the ctx->Color._ClampVertexColor field
+ */
+void
+_mesa_update_clamp_vertex_color(struct gl_context *ctx)
+{
+ ctx->Light._ClampVertexColor = _mesa_get_clamp_vertex_color(ctx);
+}
/**********************************************************************/
@@ -832,10 +904,10 @@ void _mesa_init_color( struct gl_context * ctx )
ctx->Color.DrawBuffer[0] = GL_FRONT;
}
- ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
- ctx->Color._ClampFragmentColor = GL_TRUE;
+ ctx->Color.ClampFragmentColor = ctx->API == API_OPENGL_COMPAT ?
+ GL_FIXED_ONLY_ARB : GL_FALSE;
+ ctx->Color._ClampFragmentColor = GL_FALSE;
ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
- ctx->Color._ClampReadColor = GL_TRUE;
if (ctx->API == API_OPENGLES2) {
/* GLES 3 behaves as though GL_FRAMEBUFFER_SRGB is always enabled. */
diff --git a/mesalib/src/mesa/main/blend.h b/mesalib/src/mesa/main/blend.h
index a539aa809..621311d55 100644
--- a/mesalib/src/mesa/main/blend.h
+++ b/mesalib/src/mesa/main/blend.h
@@ -99,6 +99,20 @@ _mesa_ColorMaski( GLuint buf, GLboolean red, GLboolean green,
extern void GLAPIENTRY
_mesa_ClampColor(GLenum target, GLenum clamp);
+extern GLboolean
+_mesa_get_clamp_fragment_color(const struct gl_context *ctx);
+
+extern GLboolean
+_mesa_get_clamp_vertex_color(const struct gl_context *ctx);
+
+extern GLboolean
+_mesa_get_clamp_read_color(const struct gl_context *ctx);
+
+extern void
+_mesa_update_clamp_fragment_color(struct gl_context *ctx);
+
+extern void
+_mesa_update_clamp_vertex_color(struct gl_context *ctx);
extern void
_mesa_init_color( struct gl_context * ctx );
diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h
index 8b23665e6..8431534c3 100644
--- a/mesalib/src/mesa/main/compiler.h
+++ b/mesalib/src/mesa/main/compiler.h
@@ -256,7 +256,7 @@ static INLINE GLuint CPU_TO_LE32(GLuint x)
*/
#define STATIC_ASSERT(COND) \
do { \
- typedef int static_assertion_failed[(!!(COND))*2-1]; \
+ (void) sizeof(char [1 - 2*!(COND)]); \
} while (0)
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index e90a29680..c7f038b88 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -144,10 +144,12 @@ static const struct extension extension_table[] = {
{ "GL_ARB_texture_mirrored_repeat", o(dummy_true), GLL, 2001 },
{ "GL_ARB_texture_multisample", o(ARB_texture_multisample), GL, 2009 },
{ "GL_ARB_texture_non_power_of_two", o(ARB_texture_non_power_of_two), GL, 2003 },
+ { "GL_ARB_texture_query_lod", o(ARB_texture_query_lod), GL, 2009 },
{ "GL_ARB_texture_rectangle", o(NV_texture_rectangle), GL, 2004 },
{ "GL_ARB_texture_rgb10_a2ui", o(ARB_texture_rgb10_a2ui), GL, 2009 },
{ "GL_ARB_texture_rg", o(ARB_texture_rg), GL, 2008 },
{ "GL_ARB_texture_storage", o(ARB_texture_storage), GL, 2011 },
+ { "GL_ARB_texture_storage_multisample", o(ARB_texture_storage_multisample), GL, 2012 },
{ "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL, 2008 },
{ "GL_ARB_timer_query", o(ARB_timer_query), GL, 2010 },
{ "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL, 2010 },
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 3fdf62667..fc2b2620b 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -784,6 +784,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
numImages = 0;
fb->Width = 0;
fb->Height = 0;
+ fb->_AllColorBuffersFixedPoint = GL_TRUE;
+ fb->_HasSNormOrFloatColorBuffer = GL_FALSE;
/* Start at -2 to more easily loop over all attachment points.
* -2: depth buffer
@@ -900,6 +902,19 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
/* check if integer color */
fb->_IntegerColor = _mesa_is_format_integer_color(attFormat);
+ /* Update _AllColorBuffersFixedPoint and _HasSNormOrFloatColorBuffer. */
+ if (i >= 0) {
+ GLenum type = _mesa_get_format_datatype(attFormat);
+
+ fb->_AllColorBuffersFixedPoint =
+ fb->_AllColorBuffersFixedPoint &&
+ (type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED);
+
+ fb->_HasSNormOrFloatColorBuffer =
+ fb->_HasSNormOrFloatColorBuffer ||
+ type == GL_SIGNED_NORMALIZED || type == GL_FLOAT;
+ }
+
/* Error-check width, height, format */
if (numImages == 1) {
/* save format */
@@ -1537,15 +1552,16 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
/* NumSamples == 0 indicates non-multisampling */
samples = 0;
}
-
- /* check the sample count;
- * note: driver may choose to use more samples than what's requested
- */
- sample_count_error = _mesa_check_sample_count(ctx, target,
- internalFormat, samples);
- if (sample_count_error != GL_NO_ERROR) {
- _mesa_error(ctx, sample_count_error, "%s(samples)", func);
- return;
+ else {
+ /* check the sample count;
+ * note: driver may choose to use more samples than what's requested
+ */
+ sample_count_error = _mesa_check_sample_count(ctx, target,
+ internalFormat, samples);
+ if (sample_count_error != GL_NO_ERROR) {
+ _mesa_error(ctx, sample_count_error, "%s(samples)", func);
+ return;
+ }
}
rb = ctx->CurrentRenderbuffer;
diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c
index 78c5fbe5e..e45dc8680 100644
--- a/mesalib/src/mesa/main/formatquery.c
+++ b/mesalib/src/mesa/main/formatquery.c
@@ -30,6 +30,21 @@
#include "fbobject.h"
#include "formatquery.h"
+/* default implementation of QuerySamplesForFormat driverfunc, for
+ * non-multisample-capable drivers. */
+size_t
+_mesa_query_samples_for_format(struct gl_context *ctx, GLenum target,
+ GLenum internalFormat, int samples[16])
+{
+ (void) target;
+ (void) internalFormat;
+ (void) ctx;
+
+ samples[0] = 1;
+ return 1;
+}
+
+
void GLAPIENTRY
_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
GLsizei bufSize, GLint *params)
diff --git a/mesalib/src/mesa/main/formatquery.h b/mesalib/src/mesa/main/formatquery.h
index 585c3eb64..603400059 100644
--- a/mesalib/src/mesa/main/formatquery.h
+++ b/mesalib/src/mesa/main/formatquery.h
@@ -28,6 +28,10 @@
#include "compiler.h"
#include "glheader.h"
+size_t
+_mesa_query_samples_for_format(struct gl_context *ctx, GLenum target,
+ GLenum internalFormat, int samples[16]);
+
extern void GLAPIENTRY
_mesa_GetInternalformativ(GLenum target, GLenum internalformat,
GLenum pname, GLsizei bufSize, GLint *params);
diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c
index 619aaa337..6c6977431 100644
--- a/mesalib/src/mesa/main/framebuffer.c
+++ b/mesalib/src/mesa/main/framebuffer.c
@@ -32,6 +32,7 @@
#include "glheader.h"
#include "imports.h"
+#include "blend.h"
#include "buffers.h"
#include "context.h"
#include "enums.h"
@@ -154,6 +155,8 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
fb->Delete = _mesa_destroy_framebuffer;
fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
+ fb->_AllColorBuffersFixedPoint = !visual->floatMode;
+ fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
compute_depth_max(fb);
}
@@ -740,6 +743,9 @@ _mesa_update_framebuffer(struct gl_context *ctx)
update_framebuffer(ctx, drawFb);
if (readFb != drawFb)
update_framebuffer(ctx, readFb);
+
+ _mesa_update_clamp_vertex_color(ctx);
+ _mesa_update_clamp_fragment_color(ctx);
}
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 582ef3198..2ba868c0d 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -24,6 +24,7 @@
#include "glheader.h"
#include "context.h"
+#include "blend.h"
#include "enable.h"
#include "enums.h"
#include "extensions.h"
@@ -358,6 +359,13 @@ EXTRA_EXT(ARB_texture_buffer_range);
EXTRA_EXT(ARB_texture_multisample);
static const int
+extra_ARB_color_buffer_float_or_glcore[] = {
+ EXT(ARB_color_buffer_float),
+ EXTRA_API_GL_CORE,
+ EXTRA_END
+};
+
+static const int
extra_NV_primitive_restart[] = {
EXT(NV_primitive_restart),
EXTRA_END
@@ -767,13 +775,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
break;
case GL_FOG_COLOR:
- if(ctx->Color._ClampFragmentColor)
+ if (_mesa_get_clamp_fragment_color(ctx))
COPY_4FV(v->value_float_4, ctx->Fog.Color);
else
COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
break;
case GL_COLOR_CLEAR_VALUE:
- if(ctx->Color._ClampFragmentColor) {
+ if (_mesa_get_clamp_fragment_color(ctx)) {
v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F);
v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F);
v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F);
@@ -782,13 +790,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f);
break;
case GL_BLEND_COLOR_EXT:
- if(ctx->Color._ClampFragmentColor)
+ if (_mesa_get_clamp_fragment_color(ctx))
COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
else
COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped);
break;
case GL_ALPHA_TEST_REF:
- if(ctx->Color._ClampFragmentColor)
+ if (_mesa_get_clamp_fragment_color(ctx))
v->value_float = ctx->Color.AlphaRef;
else
v->value_float = ctx->Color.AlphaRefUnclamped;
@@ -868,7 +876,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
* \param func name of calling glGet*v() function for error reporting
* \param d the struct value_desc that has the extra constraints
*
- * \return GL_FALSE if one of the constraints was not satisfied,
+ * \return GL_FALSE if all of the constraints were not satisfied,
* otherwise GL_TRUE.
*/
static GLboolean
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 7d4f7e2a4..4ef23247b 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -96,7 +96,7 @@ descriptor=[
# GL_ARB_color_buffer_float
[ "CLAMP_VERTEX_COLOR", "CONTEXT_ENUM(Light.ClampVertexColor), extra_ARB_color_buffer_float" ],
[ "CLAMP_FRAGMENT_COLOR", "CONTEXT_ENUM(Color.ClampFragmentColor), extra_ARB_color_buffer_float" ],
- [ "CLAMP_READ_COLOR", "CONTEXT_ENUM(Color.ClampReadColor), extra_ARB_color_buffer_float" ],
+ [ "CLAMP_READ_COLOR", "CONTEXT_ENUM(Color.ClampReadColor), extra_ARB_color_buffer_float_or_glcore" ],
# GL_ARB_copy_buffer
[ "COPY_READ_BUFFER", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index 4b783818b..c4110ef10 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -500,17 +500,11 @@ _mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize );
#ifndef FFS_DEFINED
#define FFS_DEFINED 1
#ifdef __GNUC__
-
-#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(ANDROID) || defined(__APPLE__)
#define ffs __builtin_ffs
#define ffsll __builtin_ffsll
-#endif
-
#else
-
extern int ffs(int i);
extern int ffsll(long long int i);
-
#endif /*__ GNUC__ */
#endif /* FFS_DEFINED */
diff --git a/mesalib/src/mesa/main/light.c b/mesalib/src/mesa/main/light.c
index 3c43ec766..c694bebe6 100644
--- a/mesalib/src/mesa/main/light.c
+++ b/mesalib/src/mesa/main/light.c
@@ -1202,7 +1202,8 @@ _mesa_init_lighting( struct gl_context *ctx )
NULL );
ctx->Light.ColorMaterialEnabled = GL_FALSE;
- ctx->Light.ClampVertexColor = GL_TRUE;
+ ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
+ ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT;
/* Miscellaneous */
ctx->Light._NeedEyeCoords = GL_FALSE;
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index a0e7e281d..008f68bda 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -146,9 +146,6 @@ typedef enum
* VERT_ATTRIB_TEX
* include the classic texture coordinate attributes.
* Is a subset of VERT_ATTRIB_FF.
- * VERT_ATTRIB_GENERIC_NV
- * include the NV shader attributes.
- * Is a subset of VERT_ATTRIB_FF.
* VERT_ATTRIB_GENERIC
* include the OpenGL 2.0+ GLSL generic shader attributes.
* These alias the generic GL_ARB_vertex_shader attributes.
@@ -159,9 +156,6 @@ typedef enum
#define VERT_ATTRIB_TEX(i) (VERT_ATTRIB_TEX0 + (i))
#define VERT_ATTRIB_TEX_MAX MAX_TEXTURE_COORD_UNITS
-#define VERT_ATTRIB_GENERIC_NV(i) (VERT_ATTRIB_POS + (i))
-#define VERT_ATTRIB_GENERIC_NV_MAX MAX_VERTEX_GENERIC_ATTRIBS
-
#define VERT_ATTRIB_GENERIC(i) (VERT_ATTRIB_GENERIC0 + (i))
#define VERT_ATTRIB_GENERIC_MAX MAX_VERTEX_GENERIC_ATTRIBS
@@ -198,10 +192,6 @@ typedef enum
#define VERT_BIT_TEX_ALL \
BITFIELD64_RANGE(VERT_ATTRIB_TEX(0), VERT_ATTRIB_TEX_MAX)
-#define VERT_BIT_GENERIC_NV(i) VERT_BIT(VERT_ATTRIB_GENERIC_NV(i))
-#define VERT_BIT_GENERIC_NV_ALL \
- BITFIELD64_RANGE(VERT_ATTRIB_GENERIC_NV(0), VERT_ATTRIB_GENERIC_NV_MAX)
-
#define VERT_BIT_GENERIC(i) VERT_BIT(VERT_ATTRIB_GENERIC(i))
#define VERT_BIT_GENERIC_ALL \
BITFIELD64_RANGE(VERT_ATTRIB_GENERIC(0), VERT_ATTRIB_GENERIC_MAX)
@@ -683,7 +673,6 @@ struct gl_colorbuffer_attrib
GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
GLboolean _ClampFragmentColor; /** < with GL_FIXED_ONLY_ARB resolved */
GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
- GLboolean _ClampReadColor; /** < with GL_FIXED_ONLY_ARB resolved */
GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */
};
@@ -1025,6 +1014,7 @@ struct gl_stencil_attrib
GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
GLboolean _Enabled; /**< Enabled and stencil buffer present */
+ GLboolean _WriteEnabled; /**< _Enabled and non-zero writemasks */
GLboolean _TestTwoSide;
GLubyte _BackFace; /**< Current back stencil state (1 or 2) */
GLenum Function[3]; /**< Stencil function */
@@ -2670,6 +2660,10 @@ struct gl_framebuffer
/** Integer color values */
GLboolean _IntegerColor;
+ /* ARB_color_buffer_float */
+ GLboolean _AllColorBuffersFixedPoint; /* no integer, no float */
+ GLboolean _HasSNormOrFloatColorBuffer;
+
/** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT];
@@ -3002,9 +2996,11 @@ struct gl_extensions
GLboolean ARB_texture_float;
GLboolean ARB_texture_multisample;
GLboolean ARB_texture_non_power_of_two;
+ GLboolean ARB_texture_query_lod;
GLboolean ARB_texture_rg;
GLboolean ARB_texture_rgb10_a2ui;
GLboolean ARB_texture_storage;
+ GLboolean ARB_texture_storage_multisample;
GLboolean ARB_timer_query;
GLboolean ARB_transform_feedback2;
GLboolean ARB_transform_feedback3;
diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c
index d3d09dea3..0dee38063 100644
--- a/mesalib/src/mesa/main/readpix.c
+++ b/mesalib/src/mesa/main/readpix.c
@@ -24,6 +24,7 @@
#include "glheader.h"
#include "imports.h"
+#include "blend.h"
#include "bufferobj.h"
#include "context.h"
#include "enums.h"
@@ -80,7 +81,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat,
if (uses_blit) {
/* For blit-based ReadPixels packing, the clamping is done automatically
* unless the type is float. */
- if (ctx->Color._ClampReadColor == GL_TRUE &&
+ if (_mesa_get_clamp_read_color(ctx) &&
(type == GL_FLOAT || type == GL_HALF_FLOAT)) {
transferOps |= IMAGE_CLAMP_BIT;
}
@@ -88,7 +89,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat,
else {
/* For CPU-based ReadPixels packing, the clamping must always be done
* for non-float types, */
- if (ctx->Color._ClampReadColor == GL_TRUE ||
+ if (_mesa_get_clamp_read_color(ctx) ||
(type != GL_FLOAT && type != GL_HALF_FLOAT)) {
transferOps |= IMAGE_CLAMP_BIT;
}
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index be6946798..2c307e79c 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -518,9 +518,11 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
GLint max_len = 0;
for (i = 0; i < shProg->NumUserUniformStorage; i++) {
- /* Add one for the terminating NUL character.
+ /* Add one for the terminating NUL character for a non-array, and
+ * 4 for the "[0]" and the NUL for an array.
*/
- const GLint len = strlen(shProg->UniformStorage[i].name) + 1;
+ const GLint len = strlen(shProg->UniformStorage[i].name) + 1 +
+ ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0);
if (len > max_len)
max_len = len;
diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c
index fb8b71cfe..251c1aea9 100644
--- a/mesalib/src/mesa/main/state.c
+++ b/mesalib/src/mesa/main/state.c
@@ -51,6 +51,7 @@
#include "texobj.h"
#include "texstate.h"
#include "varray.h"
+#include "blend.h"
static void
@@ -308,47 +309,6 @@ update_multisample(struct gl_context *ctx)
/**
- * Update the ctx->Color._ClampFragmentColor field
- */
-static void
-update_clamp_fragment_color(struct gl_context *ctx)
-{
- if (ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB)
- ctx->Color._ClampFragmentColor =
- !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
- else
- ctx->Color._ClampFragmentColor = ctx->Color.ClampFragmentColor;
-}
-
-
-/**
- * Update the ctx->Color._ClampVertexColor field
- */
-static void
-update_clamp_vertex_color(struct gl_context *ctx)
-{
- if (ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB)
- ctx->Light._ClampVertexColor =
- !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
- else
- ctx->Light._ClampVertexColor = ctx->Light.ClampVertexColor;
-}
-
-
-/**
- * Update the ctx->Color._ClampReadColor field
- */
-static void
-update_clamp_read_color(struct gl_context *ctx)
-{
- if (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB)
- ctx->Color._ClampReadColor =
- !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode;
- else
- ctx->Color._ClampReadColor = ctx->Color.ClampReadColor;
-}
-
-/**
* Update the ctx->VertexProgram._TwoSideEnabled flag.
*/
static void
@@ -507,9 +467,6 @@ _mesa_update_state_locked( struct gl_context *ctx )
if (new_state & (_NEW_LIGHT | _NEW_PROGRAM))
update_twoside( ctx );
- if (new_state & (_NEW_LIGHT | _NEW_BUFFERS))
- update_clamp_vertex_color(ctx);
-
if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
_mesa_update_stencil( ctx );
@@ -525,12 +482,6 @@ _mesa_update_state_locked( struct gl_context *ctx )
if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS))
update_multisample( ctx );
- if (new_state & (_NEW_COLOR | _NEW_BUFFERS))
- update_clamp_read_color(ctx);
-
- if(new_state & (_NEW_FRAG_CLAMP | _NEW_BUFFERS))
- update_clamp_fragment_color(ctx);
-
#if 0
if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
| _NEW_STENCIL | _MESA_NEW_SEPARATE_SPECULAR))
diff --git a/mesalib/src/mesa/main/stencil.c b/mesalib/src/mesa/main/stencil.c
index c161808e5..330841731 100644
--- a/mesalib/src/mesa/main/stencil.c
+++ b/mesalib/src/mesa/main/stencil.c
@@ -551,6 +551,11 @@ _mesa_update_stencil(struct gl_context *ctx)
ctx->Stencil.Ref[0] != ctx->Stencil.Ref[face] ||
ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[face] ||
ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[face]);
+
+ ctx->Stencil._WriteEnabled =
+ ctx->Stencil._Enabled &&
+ (ctx->Stencil.WriteMask[0] != 0 ||
+ (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[face] != 0));
}
diff --git a/mesalib/src/mesa/main/texenv.c b/mesalib/src/mesa/main/texenv.c
index 0fe5fbd7a..2979e6706 100644
--- a/mesalib/src/mesa/main/texenv.c
+++ b/mesalib/src/mesa/main/texenv.c
@@ -32,6 +32,7 @@
#include "main/glheader.h"
#include "main/context.h"
+#include "main/blend.h"
#include "main/enums.h"
#include "main/macros.h"
#include "main/mtypes.h"
@@ -680,7 +681,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
if (pname == GL_TEXTURE_ENV_COLOR) {
if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
_mesa_update_state(ctx);
- if(ctx->Color._ClampFragmentColor)
+ if (_mesa_get_clamp_fragment_color(ctx))
COPY_4FV( params, texUnit->EnvColor );
else
COPY_4FV( params, texUnit->EnvColorUnclamped );
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index bc755ae79..784b389a7 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -47,6 +47,7 @@
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
+#include "texstorage.h"
#include "mtypes.h"
#include "glformats.h"
@@ -4194,7 +4195,8 @@ check_multisample_target(GLuint dims, GLenum target)
static void
teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
GLint internalformat, GLsizei width, GLsizei height,
- GLsizei depth, GLboolean fixedsamplelocations)
+ GLsizei depth, GLboolean fixedsamplelocations,
+ GLboolean immutable, const char *func)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
@@ -4206,12 +4208,12 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
if (!(ctx->Extensions.ARB_texture_multisample
&& _mesa_is_desktop_gl(ctx))) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%uDMultisample", dims);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
return;
}
if (!check_multisample_target(dims, target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uDMultisample(target)", dims);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
return;
}
@@ -4219,26 +4221,40 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
* refer GL3.1 spec 4.4.4
*/
+ if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(internalformat=%s not legal for immutable-format)",
+ func, _mesa_lookup_enum_by_nr(internalformat));
+ return;
+ }
+
if (!is_renderable_texture_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%uDMultisample(internalformat=%s)",
- dims,
- _mesa_lookup_enum_by_nr(internalformat));
+ "%s(internalformat=%s)",
+ func, _mesa_lookup_enum_by_nr(internalformat));
return;
}
sample_count_error = _mesa_check_sample_count(ctx, target,
internalformat, samples);
if (sample_count_error != GL_NO_ERROR) {
- _mesa_error(ctx, sample_count_error, "glTexImage%uDMultisample(samples)", dims);
+ _mesa_error(ctx, sample_count_error, "%s(samples)", func);
return;
}
texObj = _mesa_get_current_tex_object(ctx, target);
+
+ if (immutable && (!texObj || (texObj->Name == 0))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(texture object 0)",
+ func);
+ return;
+ }
+
texImage = _mesa_get_tex_image(ctx, texObj, 0, 0);
if (texImage == NULL) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uDMultisample()", dims);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
return;
}
@@ -4268,13 +4284,19 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
else {
if (!dimensionsOK) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%uDMultisample(invalid width or height)", dims);
+ "%s(invalid width or height)", func);
return;
}
if (!sizeOK) {
_mesa_error(ctx, GL_OUT_OF_MEMORY,
- "glTexImage%uDMultisample(texture too large)", dims);
+ "%s(texture too large)", func);
+ return;
+ }
+
+ /* Check if texObj->Immutable is set */
+ if (texObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
return;
}
@@ -4299,6 +4321,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
}
}
+ texObj->Immutable = immutable;
_mesa_update_fbo_texture(ctx, texObj, 0, 0);
}
}
@@ -4309,7 +4332,7 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
GLsizei height, GLboolean fixedsamplelocations)
{
teximagemultisample(2, target, samples, internalformat,
- width, height, 1, fixedsamplelocations);
+ width, height, 1, fixedsamplelocations, GL_FALSE, "glTexImage2DMultisample");
}
void GLAPIENTRY
@@ -4319,5 +4342,25 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
GLboolean fixedsamplelocations)
{
teximagemultisample(3, target, samples, internalformat,
- width, height, depth, fixedsamplelocations);
+ width, height, depth, fixedsamplelocations, GL_FALSE, "glTexImage3DMultisample");
+}
+
+
+void GLAPIENTRY
+_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLboolean fixedsamplelocations)
+{
+ teximagemultisample(2, target, samples, internalformat,
+ width, height, 1, fixedsamplelocations, GL_TRUE, "glTexStorage2DMultisample");
+}
+
+void GLAPIENTRY
+_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ teximagemultisample(3, target, samples, internalformat,
+ width, height, depth, fixedsamplelocations, GL_TRUE, "glTexStorage3DMultisample");
}
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 744c47a8a..bb295c7a7 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -305,6 +305,17 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
GLsizei height, GLsizei depth,
GLboolean fixedsamplelocations);
+extern void GLAPIENTRY
+_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLboolean fixedsamplelocations);
+
+extern void GLAPIENTRY
+_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations);
+
/*@}*/
#ifdef __cplusplus
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index bd2f75170..f60eb204e 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -31,6 +31,7 @@
#include <stdbool.h>
#include "main/glheader.h"
+#include "main/blend.h"
#include "main/colormac.h"
#include "main/context.h"
#include "main/enums.h"
@@ -175,6 +176,16 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX];
}
break;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ if (ctx->Extensions.ARB_texture_storage_multisample) {
+ return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX];
+ }
+ break;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ if (ctx->Extensions.ARB_texture_storage_multisample) {
+ return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX];
+ }
+ break;
default:
;
}
@@ -250,6 +261,20 @@ incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
}
+static GLboolean
+target_allows_setting_sampler_parameters(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return GL_FALSE;
+
+ default:
+ return GL_TRUE;
+ }
+}
+
+
/**
* Set an integer-valued texture parameter
* \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
@@ -261,6 +286,9 @@ set_tex_parameteri(struct gl_context *ctx,
{
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MinFilter == params[0])
return GL_FALSE;
switch (params[0]) {
@@ -286,6 +314,9 @@ set_tex_parameteri(struct gl_context *ctx,
return GL_FALSE;
case GL_TEXTURE_MAG_FILTER:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MagFilter == params[0])
return GL_FALSE;
switch (params[0]) {
@@ -300,6 +331,9 @@ set_tex_parameteri(struct gl_context *ctx,
return GL_FALSE;
case GL_TEXTURE_WRAP_S:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.WrapS == params[0])
return GL_FALSE;
if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
@@ -310,6 +344,9 @@ set_tex_parameteri(struct gl_context *ctx,
return GL_FALSE;
case GL_TEXTURE_WRAP_T:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.WrapT == params[0])
return GL_FALSE;
if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
@@ -320,6 +357,9 @@ set_tex_parameteri(struct gl_context *ctx,
return GL_FALSE;
case GL_TEXTURE_WRAP_R:
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.WrapR == params[0])
return GL_FALSE;
if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
@@ -335,6 +375,11 @@ set_tex_parameteri(struct gl_context *ctx,
if (texObj->BaseLevel == params[0])
return GL_FALSE;
+
+ if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
+ texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0)
+ goto invalid_operation;
+
if (params[0] < 0 ||
(texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -348,6 +393,7 @@ set_tex_parameteri(struct gl_context *ctx,
case GL_TEXTURE_MAX_LEVEL:
if (texObj->MaxLevel == params[0])
return GL_FALSE;
+
if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTexParameter(param=%d)", params[0]);
@@ -373,6 +419,10 @@ set_tex_parameteri(struct gl_context *ctx,
case GL_TEXTURE_COMPARE_MODE_ARB:
if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
|| _mesa_is_gles3(ctx)) {
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.CompareMode == params[0])
return GL_FALSE;
if (params[0] == GL_NONE ||
@@ -388,6 +438,10 @@ set_tex_parameteri(struct gl_context *ctx,
case GL_TEXTURE_COMPARE_FUNC_ARB:
if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
|| _mesa_is_gles3(ctx)) {
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.CompareFunc == params[0])
return GL_FALSE;
switch (params[0]) {
@@ -489,7 +543,11 @@ set_tex_parameteri(struct gl_context *ctx,
case GL_TEXTURE_SRGB_DECODE_EXT:
if (_mesa_is_desktop_gl(ctx)
&& ctx->Extensions.EXT_texture_sRGB_decode) {
- GLenum decode = params[0];
+ GLenum decode = params[0];
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
if (texObj->Sampler.sRGBDecode != decode) {
flush(ctx);
@@ -504,6 +562,10 @@ set_tex_parameteri(struct gl_context *ctx,
if (_mesa_is_desktop_gl(ctx)
&& ctx->Extensions.AMD_seamless_cubemap_per_texture) {
GLenum param = params[0];
+
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (param != GL_TRUE && param != GL_FALSE) {
goto invalid_param;
}
@@ -528,6 +590,11 @@ invalid_param:
_mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
_mesa_lookup_enum_by_nr(params[0]));
return GL_FALSE;
+
+invalid_operation:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+ return GL_FALSE;
}
@@ -545,6 +612,9 @@ set_tex_parameterf(struct gl_context *ctx,
if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
goto invalid_pname;
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MinLod == params[0])
return GL_FALSE;
flush(ctx);
@@ -555,6 +625,9 @@ set_tex_parameterf(struct gl_context *ctx,
if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
goto invalid_pname;
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MaxLod == params[0])
return GL_FALSE;
flush(ctx);
@@ -571,6 +644,9 @@ set_tex_parameterf(struct gl_context *ctx,
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.MaxAnisotropy == params[0])
return GL_FALSE;
if (params[0] < 1.0) {
@@ -598,6 +674,9 @@ set_tex_parameterf(struct gl_context *ctx,
if (ctx->API != API_OPENGL_COMPAT)
goto invalid_pname;
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
if (texObj->Sampler.LodBias != params[0]) {
flush(ctx);
texObj->Sampler.LodBias = params[0];
@@ -609,6 +688,9 @@ set_tex_parameterf(struct gl_context *ctx,
if (!_mesa_is_desktop_gl(ctx))
goto invalid_pname;
+ if (!target_allows_setting_sampler_parameters(texObj->Target))
+ goto invalid_operation;
+
flush(ctx);
/* ARB_texture_float disables clamping */
if (ctx->Extensions.ARB_texture_float) {
@@ -633,6 +715,11 @@ invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
_mesa_lookup_enum_by_nr(pname));
return GL_FALSE;
+
+invalid_operation:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+ return GL_FALSE;
}
@@ -1329,7 +1416,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
_mesa_update_state_locked(ctx);
- if (ctx->Color._ClampFragmentColor) {
+ if (_mesa_get_clamp_fragment_color(ctx)) {
params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c
index 675fd745b..6309b5716 100644
--- a/mesalib/src/mesa/main/texstorage.c
+++ b/mesalib/src/mesa/main/texstorage.c
@@ -202,20 +202,9 @@ clear_texture_fields(struct gl_context *ctx,
}
-/**
- * Do error checking for calls to glTexStorage1/2/3D().
- * If an error is found, record it with _mesa_error(), unless the target
- * is a proxy texture.
- * \return GL_TRUE if any error, GL_FALSE otherwise.
- */
-static GLboolean
-tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,
- GLsizei levels, GLenum internalformat,
- GLsizei width, GLsizei height, GLsizei depth)
+GLboolean
+_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat)
{
- struct gl_texture_object *texObj;
- GLboolean legalFormat;
-
/* check internal format - note that only sized formats are allowed */
switch (internalformat) {
case GL_ALPHA:
@@ -250,13 +239,27 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,
case GL_LUMINANCE_INTEGER_EXT:
case GL_LUMINANCE_ALPHA_INTEGER_EXT:
/* these unsized formats are illegal */
- legalFormat = GL_FALSE;
- break;
+ return GL_FALSE;
default:
- legalFormat = _mesa_base_tex_format(ctx, internalformat) > 0;
+ return _mesa_base_tex_format(ctx, internalformat) > 0;
}
+}
+
+
+/**
+ * Do error checking for calls to glTexStorage1/2/3D().
+ * If an error is found, record it with _mesa_error(), unless the target
+ * is a proxy texture.
+ * \return GL_TRUE if any error, GL_FALSE otherwise.
+ */
+static GLboolean
+tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,
+ GLsizei levels, GLenum internalformat,
+ GLsizei width, GLsizei height, GLsizei depth)
+{
+ struct gl_texture_object *texObj;
- if (!legalFormat) {
+ if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTexStorage%uD(internalformat = %s)", dims,
_mesa_lookup_enum_by_nr(internalformat));
diff --git a/mesalib/src/mesa/main/texstorage.h b/mesalib/src/mesa/main/texstorage.h
index 99382df51..9f172e1ca 100644
--- a/mesalib/src/mesa/main/texstorage.h
+++ b/mesalib/src/mesa/main/texstorage.h
@@ -57,5 +57,8 @@ _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth);
+extern GLboolean
+_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat);
+
#endif /* TEXSTORAGE_H */
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index 3d4af5923..ecca446c1 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -233,7 +233,8 @@ compute_version(struct gl_context *ctx)
const GLboolean ver_3_0 = (ver_2_1 &&
ctx->Const.GLSLVersion >= 130 &&
ctx->Const.MaxSamples >= 4 &&
- ctx->Extensions.ARB_color_buffer_float &&
+ (ctx->API == API_OPENGL_CORE ||
+ ctx->Extensions.ARB_color_buffer_float) &&
ctx->Extensions.ARB_depth_buffer_float &&
ctx->Extensions.ARB_half_float_pixel &&
ctx->Extensions.ARB_half_float_vertex &&
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 2cb5f02f4..14cf5baa7 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -2048,6 +2048,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
case ir_txf_ms:
assert(!"Unexpected ir_txf_ms opcode");
break;
+ case ir_lod:
+ assert(!"Unexpected ir_lod opcode");
+ break;
}
const glsl_type *sampler_type = ir->sampler->type;
diff --git a/mesalib/src/mesa/program/prog_cache.c b/mesalib/src/mesa/program/prog_cache.c
index 47f926b1b..1f1c6142d 100644
--- a/mesalib/src/mesa/program/prog_cache.c
+++ b/mesalib/src/mesa/program/prog_cache.c
@@ -37,6 +37,7 @@
struct cache_item
{
GLuint hash;
+ unsigned keysize;
void *key;
struct gl_program *program;
struct cache_item *next;
@@ -174,7 +175,8 @@ struct gl_program *
_mesa_search_program_cache(struct gl_program_cache *cache,
const void *key, GLuint keysize)
{
- if (cache->last &&
+ if (cache->last &&
+ cache->last->keysize == keysize &&
memcmp(cache->last->key, key, keysize) == 0) {
return cache->last->program;
}
@@ -183,7 +185,10 @@ _mesa_search_program_cache(struct gl_program_cache *cache,
struct cache_item *c;
for (c = cache->items[hash % cache->size]; c; c = c->next) {
- if (c->hash == hash && memcmp(c->key, key, keysize) == 0) {
+ if (c->hash == hash &&
+ c->keysize == keysize &&
+ memcmp(c->key, key, keysize) == 0) {
+
cache->last = c;
return c->program;
}
@@ -207,6 +212,7 @@ _mesa_program_cache_insert(struct gl_context *ctx,
c->key = malloc(keysize);
memcpy(c->key, key, keysize);
+ c->keysize = keysize;
c->program = program; /* no refcount change */
@@ -235,6 +241,7 @@ _mesa_shader_cache_insert(struct gl_context *ctx,
c->key = malloc(keysize);
memcpy(c->key, key, keysize);
+ c->keysize = keysize;
c->program = (struct gl_program *)program; /* no refcount change */
diff --git a/mesalib/src/mesa/program/prog_statevars.c b/mesalib/src/mesa/program/prog_statevars.c
index 5a350798c..09d2a568a 100644
--- a/mesalib/src/mesa/program/prog_statevars.c
+++ b/mesalib/src/mesa/program/prog_statevars.c
@@ -31,6 +31,7 @@
#include "main/glheader.h"
#include "main/context.h"
+#include "main/blend.h"
#include "main/imports.h"
#include "main/macros.h"
#include "main/mtypes.h"
@@ -239,14 +240,14 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
{
/* state[1] is the texture unit */
const GLuint unit = (GLuint) state[1];
- if(ctx->Color._ClampFragmentColor)
+ if (_mesa_get_clamp_fragment_color(ctx))
COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
else
COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped);
}
return;
case STATE_FOG_COLOR:
- if(ctx->Color._ClampFragmentColor)
+ if (_mesa_get_clamp_fragment_color(ctx))
COPY_4V(value, ctx->Fog.Color);
else
COPY_4V(value, ctx->Fog.ColorUnclamped);
@@ -871,6 +872,9 @@ append_token(char *dst, gl_state_index k)
case STATE_CURRENT_ATTRIB:
append(dst, "current");
break;
+ case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
+ append(dst, "currentAttribMaybeVPClamped");
+ break;
case STATE_NORMAL_SCALE:
append(dst, "normalScale");
break;
diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c
index a9064c38c..2c826fc66 100644
--- a/mesalib/src/mesa/program/register_allocate.c
+++ b/mesalib/src/mesa/program/register_allocate.c
@@ -70,6 +70,7 @@
* this during ra_set_finalize().
*/
+#include <stdbool.h>
#include <ralloc.h>
#include "main/imports.h"
@@ -93,6 +94,8 @@ struct ra_regs {
struct ra_class **classes;
unsigned int class_count;
+
+ bool round_robin;
};
struct ra_class {
@@ -185,6 +188,22 @@ ra_alloc_reg_set(void *mem_ctx, unsigned int count)
return regs;
}
+/**
+ * The register allocator by default prefers to allocate low register numbers,
+ * since it was written for hardware (gen4/5 Intel) that is limited in its
+ * multithreadedness by the number of registers used in a given shader.
+ *
+ * However, for hardware without that restriction, densely packed register
+ * allocation can put serious constraints on instruction scheduling. This
+ * function tells the allocator to rotate around the registers if possible as
+ * it allocates the nodes.
+ */
+void
+ra_set_allocate_round_robin(struct ra_regs *regs)
+{
+ regs->round_robin = true;
+}
+
static void
ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2)
{
@@ -436,16 +455,19 @@ GLboolean
ra_select(struct ra_graph *g)
{
int i;
+ int start_search_reg = 0;
while (g->stack_count != 0) {
- unsigned int r;
+ unsigned int ri;
+ unsigned int r = -1;
int n = g->stack[g->stack_count - 1];
struct ra_class *c = g->regs->classes[g->nodes[n].class];
/* Find the lowest-numbered reg which is not used by a member
* of the graph adjacent to us.
*/
- for (r = 0; r < g->regs->count; r++) {
+ for (ri = 0; ri < g->regs->count; ri++) {
+ r = (start_search_reg + ri) % g->regs->count;
if (!c->regs[r])
continue;
@@ -461,12 +483,15 @@ ra_select(struct ra_graph *g)
if (i == g->nodes[n].adjacency_count)
break;
}
- if (r == g->regs->count)
+ if (ri == g->regs->count)
return GL_FALSE;
g->nodes[n].reg = r;
g->nodes[n].in_stack = GL_FALSE;
g->stack_count--;
+
+ if (g->regs->round_robin)
+ start_search_reg = r + 1;
}
return GL_TRUE;
diff --git a/mesalib/src/mesa/program/register_allocate.h b/mesalib/src/mesa/program/register_allocate.h
index 2a9d61191..fa119e320 100644
--- a/mesalib/src/mesa/program/register_allocate.h
+++ b/mesalib/src/mesa/program/register_allocate.h
@@ -37,6 +37,7 @@ struct ra_regs;
* two real registers from which they are composed.
*/
struct ra_regs *ra_alloc_reg_set(void *mem_ctx, unsigned int count);
+void ra_set_allocate_round_robin(struct ra_regs *regs);
unsigned int ra_alloc_reg_class(struct ra_regs *regs);
void ra_add_reg_conflict(struct ra_regs *regs,
unsigned int r1, unsigned int r2);
diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
index 961fb28a9..56ba96fe3 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
@@ -39,6 +39,7 @@
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_upload_mgr.h"
+#include "cso_cache/cso_context.h"
#include "st_debug.h"
#include "st_context.h"
@@ -96,16 +97,17 @@ void st_upload_constants( struct st_context *st,
_mesa_print_parameter_list(params);
}
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb);
+ cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb);
pipe_resource_reference(&cb.buffer, NULL);
st->state.constants[shader_type].ptr = params->ParameterValues;
st->state.constants[shader_type].size = paramBytes;
}
else if (st->state.constants[shader_type].ptr) {
+ /* Unbind. */
st->state.constants[shader_type].ptr = NULL;
st->state.constants[shader_type].size = 0;
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
+ cso_set_constant_buffer(st->cso_context, shader_type, 0, NULL);
}
}
@@ -196,7 +198,7 @@ static void st_bind_ubos(struct st_context *st,
cb.buffer_size = st_obj->buffer->width0 - binding->Offset;
- st->pipe->set_constant_buffer(st->pipe, shader_type, 1 + i, &cb);
+ cso_set_constant_buffer(st->cso_context, shader_type, 1 + i, &cb);
pipe_resource_reference(&cb.buffer, NULL);
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
index 866e5627d..62464b475 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -227,8 +227,7 @@ static void update_raster_state( struct st_context *st )
/* _NEW_FRAG_CLAMP */
raster->clamp_fragment_color = !st->clamp_frag_color_in_shader &&
- ctx->Color._ClampFragmentColor &&
- !ctx->DrawBuffer->_IntegerColor;
+ ctx->Color._ClampFragmentColor;
raster->gl_rasterization_rules = 1;
/* _NEW_RASTERIZER_DISCARD */
diff --git a/mesalib/src/mesa/state_tracker/st_atom_shader.c b/mesalib/src/mesa/state_tracker/st_atom_shader.c
index c1d7c80bb..c0239e929 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_shader.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_shader.c
@@ -86,8 +86,7 @@ update_fp( struct st_context *st )
/* _NEW_FRAG_CLAMP */
key.clamp_color = st->clamp_frag_color_in_shader &&
- st->ctx->Color._ClampFragmentColor &&
- !st->ctx->DrawBuffer->_IntegerColor;
+ st->ctx->Color._ClampFragmentColor;
st->fp_variant = st_get_fp_variant(st, stfp, &key);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
index bae9ff858..b3ca40501 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
@@ -417,8 +417,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
key.st = st;
key.bitmap = GL_TRUE;
key.clamp_color = st->clamp_frag_color_in_shader &&
- st->ctx->Color._ClampFragmentColor &&
- !st->ctx->DrawBuffer->_IntegerColor;
+ st->ctx->Color._ClampFragmentColor;
fpv = st_get_fp_variant(st, st->fp, &key);
@@ -766,6 +765,7 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
/* create pass-through vertex shader now */
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_COLOR,
+ st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD :
TGSI_SEMANTIC_GENERIC };
const uint semantic_indexes[] = { 0, 0, 0 };
st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
index f0baa3435..f5a1e27f7 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -294,6 +294,9 @@ static void *
make_passthrough_vertex_shader(struct st_context *st,
GLboolean passColor)
{
+ const unsigned texcoord_semantic = st->needs_texcoord_semantic ?
+ TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
+
if (!st->drawpix.vert_shaders[passColor]) {
struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
@@ -307,7 +310,7 @@ make_passthrough_vertex_shader(struct st_context *st,
/* MOV result.texcoord0, vertex.attr[1]; */
ureg_MOV(ureg,
- ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ),
+ ureg_DECL_output( ureg, texcoord_semantic, 0 ),
ureg_DECL_vs_input( ureg, 1 ));
if (passColor) {
@@ -707,8 +710,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 = !st->clamp_frag_color_in_shader &&
- ctx->Color._ClampFragmentColor &&
- !ctx->DrawBuffer->_IntegerColor;
+ ctx->Color._ClampFragmentColor;
rasterizer.gl_rasterization_rules = 1;
rasterizer.depth_clip = !ctx->Transform.DepthClamp;
rasterizer.scissor = ctx->Scissor.Enabled;
@@ -1034,8 +1036,7 @@ get_color_fp_variant(struct st_context *st)
ctx->Pixel.AlphaScale != 1.0);
key.pixelMaps = ctx->Pixel.MapColorFlag;
key.clamp_color = st->clamp_frag_color_in_shader &&
- st->ctx->Color._ClampFragmentColor &&
- !st->ctx->DrawBuffer->_IntegerColor;
+ st->ctx->Color._ClampFragmentColor;
fpv = st_get_fp_variant(st, st->fp, &key);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
index a8806c91e..c4efce02f 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
@@ -209,7 +209,9 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
SET_ATTRIB(2, attr, s1, t1, 0.0f, 1.0f); /* upper right */
SET_ATTRIB(3, attr, s0, t1, 0.0f, 1.0f); /* upper left */
- semantic_names[attr] = TGSI_SEMANTIC_GENERIC;
+ semantic_names[attr] = st->needs_texcoord_semantic ?
+ TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
+ /* XXX: should this use semantic index i instead of 0 ? */
semantic_indexes[attr] = 0;
attr++;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
index bfed98870..9fab113fa 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
@@ -133,7 +133,6 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
!screen->is_format_supported(screen, src_format, src->target,
src->nr_samples,
PIPE_BIND_SAMPLER_VIEW)) {
- printf("fallback: src format unsupported %s\n", util_format_short_name(src_format));
goto fallback;
}
@@ -147,8 +146,6 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
dst_format = st_choose_matching_format(screen, bind, format, type,
pack->SwapBytes);
if (dst_format == PIPE_FORMAT_NONE) {
- printf("fallback: no matching format for %s, %s\n",
- _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type));
goto fallback;
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index 94fbbf7be..0cd0d77af 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -868,7 +868,7 @@ st_GetTexImage(struct gl_context * ctx,
goto fallback;
}
- if (!stImage->pt) {
+ if (!stImage->pt || !src) {
goto fallback;
}
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 11db9d3f3..2d8b9efec 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -629,6 +629,7 @@ void st_init_extensions(struct st_context *st)
ctx->Const.PrimitiveRestartInSoftware = GL_TRUE;
}
+ /* ARB_color_buffer_float. */
if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) {
ctx->Extensions.ARB_color_buffer_float = GL_TRUE;
@@ -639,6 +640,16 @@ void st_init_extensions(struct st_context *st)
if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) {
st->clamp_frag_color_in_shader = TRUE;
}
+
+ /* For drivers which cannot do color clamping, it's better to just
+ * disable ARB_color_buffer_float in the core profile, because
+ * the clamping is deprecated there anyway. */
+ if (ctx->API == API_OPENGL_CORE &&
+ (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) {
+ st->clamp_vert_color_in_shader = GL_FALSE;
+ st->clamp_frag_color_in_shader = GL_FALSE;
+ ctx->Extensions.ARB_color_buffer_float = GL_FALSE;
+ }
}
if (screen->fence_finish) {
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index e3718eeda..338c652cb 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1009,7 +1009,9 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
src.reladdr = NULL;
src.negate = 0;
- if (type->is_array() || type->is_matrix()) {
+ if (!options->EmitNoIndirectTemp &&
+ (type->is_array() || type->is_matrix())) {
+
src.file = PROGRAM_ARRAY;
src.index = next_array << 16 | 0x8000;
array_sizes[next_array] = type_size(type);
@@ -2772,6 +2774,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
case ir_txf_ms:
assert(!"Unexpected ir_txf_ms opcode");
break;
+ case ir_lod:
+ assert(!"Unexpected ir_lod opcode");
+ break;
}
if (ir->projector) {
@@ -3191,7 +3196,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
prevWriteMask = tempWrites[inst->dst.index];
tempWrites[inst->dst.index] |= inst->dst.writemask;
} else
- break;
+ continue;
/* For a CMP to be considered a conditional write, the destination
* register and source register two must be the same. */
diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c
index 0b025d9d5..03e086a72 100644
--- a/mesalib/src/mesa/state_tracker/st_manager.c
+++ b/mesalib/src/mesa/state_tracker/st_manager.c
@@ -170,9 +170,8 @@ st_context_validate(struct st_context *st,
/**
* Validate a framebuffer to make sure up-to-date pipe_textures are used.
- * The context we need to pass in is s dummy context needed only to be
- * able to get a pipe context to create pipe surfaces, and to have a
- * context to call _mesa_resize_framebuffer():
+ * The context is only used for creating pipe surfaces and for calling
+ * _mesa_resize_framebuffer().
* (That should probably be rethought, since those surfaces become
* drawable state, not context state, and can be freed by another pipe
* context).
diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c
index 82fa43f1c..051354dc8 100644
--- a/mesalib/src/mesa/swrast/s_blit.c
+++ b/mesalib/src/mesa/swrast/s_blit.c
@@ -110,8 +110,8 @@ blit_nearest(struct gl_context *ctx,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield buffer)
{
- struct gl_renderbuffer *readRb, *drawRb;
- struct gl_renderbuffer_attachment *readAtt, *drawAtt;
+ struct gl_renderbuffer *readRb, *drawRb = NULL;
+ struct gl_renderbuffer_attachment *readAtt = NULL, *drawAtt = NULL;
struct gl_framebuffer *readFb = ctx->ReadBuffer;
struct gl_framebuffer *drawFb = ctx->DrawBuffer;
GLuint numDrawBuffers = 0;
@@ -135,12 +135,12 @@ blit_nearest(struct gl_context *ctx,
UNPACK_Z_FLOAT,
UNPACK_Z_INT,
UNPACK_S,
- } mode;
+ } mode = DIRECT;
GLubyte *srcMap, *dstMap;
GLint srcRowStride, dstRowStride;
GLint dstRow;
- GLint pixelSize;
+ GLint pixelSize = 0;
GLvoid *srcBuffer, *dstBuffer;
GLint prevY = -1;